Skip to main content

Customers

List Customers​

Retrieve a paginated list of customers. Supports filtering by search query, tags, and blacklist status.

GET /api/v1/public/customers

Query Parameters​

ParameterTypeRequiredDescription
limitnumbernoNumber of customers to return (1-200, default 50)
cursorstringnoCustomer ID for pagination (from next_cursor in previous response)
searchstringnoSearch by phone number, name, or email
tagsstringnoComma-separated list of tags to filter by
blacklistedstringnoFilter by blacklist status: "true" or "false"

Example Request​

curl -X GET "https://chat.api.co.id/api/v1/public/customers?limit=50&search=john&tags=vip,loyal" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

{
"success": true,
"data": [
{
"id": "clxxx1234567890",
"phone_number": "628123456789",
"name": "John Doe",
"email": "[email protected]",
"tags": ["vip", "loyal"],
"is_window_active": true,
"unread_count": 3,
"created_at": "2026-01-01T00:00:00.000Z"
},
{
"id": "clxxx0987654321",
"phone_number": "628987654321",
"name": "Jane Smith",
"email": "[email protected]",
"tags": ["new"],
"is_window_active": false,
"unread_count": 0,
"created_at": "2026-02-15T08:30:00.000Z"
}
],
"pagination": {
"has_more": true,
"next_cursor": "clxxx0987654321",
"limit": 50
}
}
info

Use next_cursor from the pagination object as the cursor query parameter to fetch the next page.

Get Customer​

Retrieve full details for a single customer, including custom fields, consent logs, and notes.

GET /api/v1/public/customers/:id

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID), phone number, or Instagram username

Example Request​

curl -X GET "https://chat.api.co.id/api/v1/public/customers/628123456789" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

{
"success": true,
"data": {
"id": "clxxx1234567890",
"phone_number": "628123456789",
"name": "John Doe",
"email": "[email protected]",
"instagram_username": null,
"tags": ["vip", "loyal"],
"is_window_active": true,
"unread_count": 3,
"custom_fields": {
"company": "Acme Inc",
"plan": "enterprise"
},
"consent_logs": [
{
"source": "website_form",
"purpose": "marketing",
"consent_status": true,
"logged_at": "2026-01-01T00:00:00.000Z"
}
],
"notes": [
{
"id": "note_abc123",
"content": "VIP customer, handle with care",
"created_at": "2026-01-05T14:00:00.000Z"
}
],
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-07T10:30:00.000Z"
}
}

Create Customer​

Create a new customer record with phone number, profile information, tags, and consent status.

POST /api/v1/public/customers

Parameters​

ParameterTypeRequiredDescription
phone_numberstringyesCustomer phone number in E.164 format (e.g., 628123456789)
whatsapp_phone_number_idstringyesWhich of your WhatsApp numbers to associate this customer with. Use the id from GET /phone-numbers.
namestringnoCustomer display name
emailstringnoCustomer email address
tagsstring[]noArray of tags for categorization (e.g., ["vip", "loyal"])
consent_statusbooleannoWhether the customer has given messaging consent
consent_sourcestringnoSource of consent (e.g., "api", "website_form", "manual")

Example Request​

curl -X POST "https://chat.api.co.id/api/v1/public/customers" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "628123456789",
"whatsapp_phone_number_id": "clyyy9876543210",
"name": "John Doe",
"email": "[email protected]",
"tags": ["vip"],
"consent_status": true,
"consent_source": "api"
}'

Response​

{
"success": true,
"data": {
"id": "clxxx1234567890",
"phone_number": "628123456789",
"name": "John Doe",
"email": "[email protected]",
"tags": ["vip"],
"consent_status": true,
"consent_source": "api",
"blacklisted": false,
"created_at": "2026-04-03T10:00:00.000Z",
"updated_at": "2026-04-03T10:00:00.000Z"
}
}

Update Customer​

Update an existing customer's profile. Only provided fields are modified (partial update).

PATCH /api/v1/public/customers/:id

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID)

Body Parameters​

ParameterTypeRequiredDescription
namestringnoUpdated customer name
emailstringnoUpdated email address
tagsstring[]noReplaces all existing tags with this array

Example Request​

curl -X PATCH "https://chat.api.co.id/api/v1/public/customers/clxxx1234567890" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Name",
"tags": ["vip", "loyal"]
}'

Response​

{
"success": true,
"data": {
"id": "clxxx1234567890",
"phone_number": "628123456789",
"name": "Updated Name",
"email": "[email protected]",
"tags": ["vip", "loyal"],
"consent_status": true,
"blacklisted": false,
"updated_at": "2026-04-03T11:00:00.000Z"
}
}

Delete Customer​

Permanently delete a customer record. This action cannot be undone.

DELETE /api/v1/public/customers/:id

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID) to delete
warning

Warning: Deleting a customer is permanent and will also remove all associated conversation history, notes, and consent records.

Example Request​

curl -X DELETE "https://chat.api.co.id/api/v1/public/customers/clxxx1234567890" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

{
"success": true,
"data": {
"id": "clxxx1234567890",
"deleted": true
}
}

Log consent actions for a customer. Useful for GDPR/compliance tracking and managing messaging permissions.

POST /api/v1/public/customers/:id/consent

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID)

Body Parameters​

ParameterTypeRequiredDescription
actionstringyesConsent action: "OPT_IN", "OPT_OUT", or "UPDATE"
sourcestringyesWhere consent was collected (e.g., "website_form", "api", "phone_call")
purposestringnoPurpose of consent (e.g., "marketing", "transactional", "support")

Example Request​

curl -X POST "https://chat.api.co.id/api/v1/public/customers/clxxx1234567890/consent" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "OPT_IN",
"source": "website_form",
"purpose": "marketing"
}'

Response​

{
"success": true,
"data": {
"customer_id": "clxxx1234567890",
"action": "OPT_IN",
"source": "website_form",
"purpose": "marketing",
"consent_status": true,
"logged_at": "2026-04-03T10:00:00.000Z"
}
}

Check Messaging Window​

Check if the 24-hour messaging window is active for a customer. Non-template messages can only be sent within this window.

GET /api/v1/public/customers/:id/window-status

warning

24-Hour Window Rule: WhatsApp only allows free-form messages (text, media, interactive) within 24 hours of the customer's last inbound message. After the window closes, you can only send pre-approved template messages. Always check the window status before sending non-template messages.

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID), phone number, or Instagram username

Example Request​

curl -X GET "https://chat.api.co.id/api/v1/public/customers/628123456789/window-status" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

{
"success": true,
"data": {
"customer_id": "clxxx1234567890",
"whatsapp": {
"is_window_active": true,
"window_expires_at": "2026-01-08T10:30:00.000Z",
"last_inbound_message_at": "2026-01-07T10:30:00.000Z",
"can_send_freeform": true,
"can_send_template": true,
"free_entry_point": {
"is_active": true,
"expires_at": "2026-01-14T10:30:00.000Z"
},
"is_free": true,
"free_reason": "ctwa",
"free_service_messages": {
"limit": 1000,
"used": 312,
"remaining": 688
}
},
"instagram": {
"is_window_active": false,
"window_expires_at": null
}
}
}

Click-to-WhatsApp Free Window​

whatsapp.free_entry_point tells you whether the customer is inside a free entry point window from a Click-to-WhatsApp ad. Since October 2026 this window lasts up to 7 days, and every message sent to the customer inside it is free, including templates. It opens when the customer messages you from an ad. Messages sent inside this window do not count toward the 1,000 free service messages. expires_at is null if the customer never came from an ad.

info

This is an estimate: we start the window at the ad message, while Meta starts it at your first reply (within 24 hours). Your Meta invoice is the final number.

Is the Next Message Free?​

whatsapp.is_free tells you whether the next message to this customer is free. free_reason says why:

  • "ctwa": the customer is inside a Click-to-WhatsApp free window. Every message is free, templates included.
  • "free_tier": the 24-hour window is open and the customer's phone number still has free service messages left this month. Free-form messages are free. Templates are still charged.
  • null: the next message is charged, or the window is closed and you can only send a template.

free_service_messages shows the 1,000 free service messages used and left this UTC month on the phone number linked to the customer. It is null if the customer has no linked number. These numbers are estimates as well.

Toggle Blacklist​

Add or remove a customer from the blacklist. Blacklisted customers will not receive any messages.

PATCH /api/v1/public/customers/:id/blacklist

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID), phone number, or Instagram username

Body Parameters​

ParameterTypeRequiredDescription
blacklistedbooleanyesSet to true to blacklist, false to remove from blacklist

Example Request​

curl -X PATCH "https://chat.api.co.id/api/v1/public/customers/628123456789/blacklist" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"blacklisted": true}'

Response​

{
"success": true,
"data": {
"id": "clxxx1234567890",
"phone_number": "628123456789",
"name": "John Doe",
"blacklisted": true,
"updated_at": "2026-04-03T10:00:00.000Z"
}
}

Customer Notes​

Manage internal notes attached to a customer. Notes are visible only to your team.

GET /api/v1/public/customers/:id/notes

POST /api/v1/public/customers/:id/notes

DELETE /api/v1/public/customers/:id/notes/:noteId

URL Parameters​

ParameterTypeRequiredDescription
idstringyesCustomer ID (CUID), phone number, or Instagram username
noteIdstringyesNote ID (required for DELETE only)

Body Parameters (POST)​

ParameterTypeRequiredDescription
contentstringyesThe note content text

List Notes​

curl -X GET "https://chat.api.co.id/api/v1/public/customers/628123456789/notes" \
-H "Authorization: Bearer YOUR_API_KEY"

List Notes Response​

{
"success": true,
"data": [
{
"id": "note_abc123",
"content": "VIP customer, handle with care",
"created_by": "[email protected]",
"created_at": "2026-01-05T14:00:00.000Z"
},
{
"id": "note_def456",
"content": "Prefers communication in English",
"created_by": "[email protected]",
"created_at": "2026-02-10T09:15:00.000Z"
}
]
}

Add Note​

curl -X POST "https://chat.api.co.id/api/v1/public/customers/628123456789/notes" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Follow up on order #1234"}'

Add Note Response​

{
"success": true,
"data": {
"id": "note_ghi789",
"content": "Follow up on order #1234",
"created_by": "[email protected]",
"created_at": "2026-04-03T10:00:00.000Z"
}
}

Delete Note​

curl -X DELETE "https://chat.api.co.id/api/v1/public/customers/628123456789/notes/note_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"

Delete Note Response​

{
"success": true,
"message": "Note deleted successfully"
}

Try it out​

tip

Press Try it and paste your API key (kc_live_...) into the API key (Bearer) field. Get the key from API Keys. Requests run against your live account, so endpoints that send, create, or delete act on real data.

  • GET/api/v1/public/customersList Customers
  • POST/api/v1/public/customersCreate Customer
  • GET/api/v1/public/customers/{id}Get Customer
  • PATCH/api/v1/public/customers/{id}Update Customer
  • DELETE/api/v1/public/customers/{id}Delete Customer
  • POST/api/v1/public/customers/{id}/consentCustomer Consent
  • GET/api/v1/public/customers/{id}/window-statusCheck Messaging Window
  • PATCH/api/v1/public/customers/{id}/blacklistToggle Blacklist
  • GET/api/v1/public/customers/{id}/notesList Notes
  • POST/api/v1/public/customers/{id}/notesAdd Note
  • DELETE/api/v1/public/customers/{id}/notes/{noteId}Delete Note
Was this page helpful?