Skip to content
Documentation

Create or update a contact by external id

PUT
/v1/public-api/contacts/by-external-id

Scope: contacts:write. external_id is required and is your own user id (the user_id of the widget identify call). If a contact with that id exists it is updated (200), otherwise created (201); no matching by email or phone. An id that belongs to another contact returns 409 EXTERNAL_ID_EXISTS. Idempotency-Key is required.

Authorization

integrationKey
headerAuthorizationBearer <cf_sk_…>

Organization API key (cf_sk_…), created under Organization → API and automations → API keys and sent as Authorization: Bearer cf_sk_….

Header Parameters

Idempotency-Key*string
Lengthlength <= 200

Request Body

application/json
  1. body
name?string
Lengthlength <= 255
email?string
phone?string
job_title?string
Lengthlength <= 120
company?|
Formatuuid
locale?string
timezone?string
notes?string
custom_fields?
blocked?boolean
external_id*string

The customer's own user id; empty clears it. 409 EXTERNAL_ID_EXISTS when another contact has it.

Lengthlength <= 200

Response Body

Updated

application/json
  1. response
success*true
Value intrue
data*
meta*
Example Request
curl -X PUT 'https://api.getclickfix.com/v1/public-api/contacts/by-external-id' \  -H 'Idempotency-Key: string' \  -H 'Content-Type: application/json' \  -d '{  "external_id": "1001",  "name": "Ayşe Yılmaz",  "email": "ayse@example.com",  "custom_fields": {    "plan": "pro",    "seats": 12  }}'
Example Response
{  "success": true,  "data": {    "uuid": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",    "name": "Ayşe Yılmaz",    "email": "ayse@example.com",    "phone": "+905551112233",    "external_id": "1001",    "identity_state": "verified",    "verified_at": "2026-11-10T18:42:11Z",    "job_title": "Operations manager",    "company": {      "uuid": "0f9e8d7c-6b5a-4493-8271-605f4e3d2c1b",      "name": "Acme Ltd.",      "external_id": "F-77"    },    "locale": "tr",    "timezone": "Europe/Istanbul",    "notes": "",    "custom_fields": {      "plan": "pro",      "seats": 12    },    "blocked": false,    "channel_types": [      "widget",      "email"    ],    "conversation_count": 3,    "last_seen_at": "2026-11-11T09:14:50Z",    "created_at": "2026-10-01T07:00:00Z",    "updated_at": "2026-11-11T09:14:50Z"  },  "meta": {    "request_id": "01JCK9ZQ3M8R2W7X5E4T1N0PAB"  }}