smartchat

Create a contact and add a tag

You need a key with the level Draft or higher (permission contacts:write). Nothing in this guide sends a message.

The three steps tell one story: Mia is created, gets the tag vip, and is read back with that tag. The answers on this page belong together.

#1. Create the contact

curl -X POST "https://api.smartchat.marketing/v1/contacts" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Mia Muster",
  "phone": "+4915112345678",
  "email": "mia@example.com"
}'
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/contacts",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Mia Muster",
        "phone": "+4915112345678",
        "email": "mia@example.com",
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/contacts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "Mia Muster",
    "phone": "+4915112345678",
    "email": "mia@example.com"
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (201):

{
  "object": "contact",
  "id": "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
  "name": "Mia Muster",
  "phone": "+4915112345678",
  "email": "mia@example.com",
  "language": "en",
  "status": "unconfirmed",
  "optin_whatsapp": "none",
  "optin_whatsapp_at": null,
  "purpose": "marketing",
  "source": "api",
  "tags": [],
  "tag_details": [],
  "created_at": "2026-10-25T09:41:07Z"
}

Calls that create things need an Idempotency-Key (why). The new contact has optin_whatsapp set to none until the contact confirms. The API never sets a contact to confirmed.

If a contact with the same phone number or email exists, the answer is contact_already_exists with the ID of the existing contact in existing_id. Change that contact with update_contact instead.

#2. Add a tag

Tags are added to one or more contacts at once. The tag is created if it does not exist yet.

curl -X POST "https://api.smartchat.marketing/v1/contacts/tags" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "contact_ids": [
    "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234"
  ],
  "add_tags": [
    "vip"
  ]
}'
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/contacts/tags",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "contact_ids": [
            "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
        ],
        "add_tags": [
            "vip",
        ],
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/contacts/tags", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "contact_ids": [
      "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234"
    ],
    "add_tags": [
      "vip"
    ]
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (200):

{
  "object": "contact_tags_update",
  "updated": 1,
  "unchanged": 0,
  "not_found": 0,
  "failed": 0,
  "results": [
    {
      "contact_id": "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
      "status": "updated",
      "tags": [
        "vip"
      ],
      "error_code": null
    }
  ]
}

#3. Read the contact back

curl "https://api.smartchat.marketing/v1/contacts/con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY"
import os
import requests

response = requests.get(
    "https://api.smartchat.marketing/v1/contacts/con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
    headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/contacts/con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
  },
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (200):

{
  "object": "contact",
  "id": "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
  "name": "Mia Muster",
  "phone": "+4915112345678",
  "email": "mia@example.com",
  "language": "en",
  "status": "unconfirmed",
  "optin_whatsapp": "none",
  "optin_whatsapp_at": null,
  "purpose": "marketing",
  "source": "api",
  "tags": [
    "vip"
  ],
  "tag_details": [
    {
      "name": "vip",
      "origin": "manual",
      "added_at": "2026-10-25T09:42:30Z"
    }
  ],
  "created_at": "2026-10-25T09:41:07Z"
}

The contact now has the tag vip.

#Next