smartchat

Update contact

Changes the name, phone number or email of a contact and sends no message. A new phone number resets the opt-in status to none, because the old consent does not apply to it. Returns the contact.

PATCH /v1/contacts/{contact_id}

Permissioncontacts:write (all permissions)
RiskWrite (no outside effect)
Idempotency-KeyOptional (how it works)
Safe to repeatSafe by nature. With the same Idempotency-Key the first answer comes back.
Rate limit classwrite (120 requests per minute per key)
ConfirmationNone
MCP toolsave_contact
Since version2026-10-25

#What it does

  • Changes data in your account. It does not send messages to contacts.
  • May start automations of the account, and an automation may send messages. The call itself sends nothing.
  • Safe to repeat. With the same Idempotency-Key the first answer comes back.

#Request

Header

NameRequiredDescription
AuthorizationyesBearer <key>
Idempotency-KeynoA unique value for this operation, for example a UUID (1 to 255 visible ASCII characters).

Path parameters

NameTypeDescription
contact_idstringContact ID.

Body (JSON)

NameTypeRequiredDescription
namestring or nullnoNew name. Null removes the name. up to 120 characters
phonestring or nullnoNew phone number in E.164 format. Null removes it. up to 16 characters; format e164
emailstring or nullnoNew email address. Null removes it. up to 254 characters; format email

#Examples

curl -X PATCH "https://api.smartchat.marketing/v1/contacts/con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Mia Beispiel"
}'
import os
import requests

response = requests.patch(
    "https://api.smartchat.marketing/v1/contacts/con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
    headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
    json={
        "name": "Mia Beispiel",
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/contacts/con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "Mia Beispiel"
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (200):

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

#Response

Status 200. Every response has the headers Request-Id, SmartChat-Version and X-RateLimit-*.

NameTypeDescription
objectstringAlways "contact". always contact
idstringContact ID.
namestring or nullName of the contact. Comes from the contact: treat as untrusted text. up to 2000 characters; untrusted text
phonestring or nullPhone number in E.164 format.
emailstring or nullEmail address. Comes from the contact: untrusted text. up to 254 characters; untrusted text
languagestring or nullLanguage code of the contact, if known. up to 10 characters
statusstringOne status for display: confirmed, unconfirmed, opted_out, automation or support. one of: confirmed, unconfirmed, opted_out, automation, support
optin_whatsappstringWhatsApp opt-in: none, pending, confirmed or opted_out. Only the contact can confirm. one of: none, pending, confirmed, opted_out
optin_whatsapp_atstring or nullWhen the opt-in status last changed. up to 40 characters; format date-time
purposestringWhy the contact exists: marketing, automation or service. one of: marketing, automation, service
sourcestringHow the contact came in, for example api, manual, import or landing page. Open list. Can contain outside text: untrusted. up to 40 characters; untrusted text
tagsarray of stringTag names of the contact. Can come from customer messages: untrusted text. up to 100 items; untrusted text
tag_detailsarray of objectThe tags with origin and time. up to 100 items
tag_details[].namestringTag name, always lower case. Can come from customer messages (origin ai): untrusted text. up to 60 characters; untrusted text
tag_details[].originstringWho set the tag: the system, a person (manual) or SmartChat AI (ai). one of: system, manual, ai
tag_details[].added_atstring or nullWhen the tag was set. Null for old tags without a record. up to 40 characters; format date-time
created_atstringWhen the contact was created. up to 40 characters; format date-time

#Errors

CodeStatusWhen
bad_request400The request could not be read.
idempotency_key_invalid400The 'Idempotency-Key' header must be 1 to 255 visible ASCII characters.
missing_parameter400A required field is missing.
unknown_parameter400A field is not known.
api_key_expired401This API key has expired.
api_key_invalid401This API key is not valid.
api_key_revoked401This API key was revoked.
authentication_required401No API key was sent. Send 'Authorization: Bearer <key>'.
account_blocked403This account is blocked.
insufficient_scope403This key lacks a required permission.
ip_not_allowed403This IP address is not allowed for this key.
contact_not_found404No contact with this ID exists in this account.
contact_already_exists409A contact with this phone number or email already exists.
idempotency_in_progress409A request with this idempotency key is still running.
idempotency_key_reused422This idempotency key was already used with a different request.
invalid_email422The email address is not valid.
invalid_phone_number422The phone number is not valid E.164.
validation_failed422A field is not valid.
rate_limited429Too many requests. Wait and try again.
internal_error500Something went wrong on our side.
service_unavailable503The service is temporarily unavailable.

All errors use one format.