REST API Reference.

From contact management to message sending, from tickets to live chat: every endpoint and sample body for connecting Cxperium to your own systems.

Authentication

All requests go to https://api.cxperium.com under the /api/… path over HTTPS. Add the apikey header carrying your API key to every request.

sample-request.sh
curl https://api.cxperium.com/api/contacts?page=1&limit=10 \
  -H "apikey: $CX_API_KEY"
  • Creating a key — in the dashboard go to Settings → API Integration and click Generate; available on Premium and Enterprise plans. Step by step: API Creation and Connection Operations.
  • Postman collection — the View Collection button on the same screen gives you a collection with every endpoint on this page and sample bodies.
  • One key per account — generating a new key immediately invalidates the previous one. Sub-users can also generate a key from the API Integration screen; doing so renews the account's shared key.
  • Keep the key secret — it grants access to your whole account. Do not embed it in browser code or a mobile app; call from your server. If you think it has leaked, regenerate it in the dashboard; the old key becomes invalid.

An invalid, missing or plan-ineligible key returns 401:

401.json
{ "error": "Invalid API key!" }

Conventions

Request and response formats are the same across all endpoints. Bodies are JSON (Content-Type: application/json); the one exception is ticket creation with attachments (multipart/form-data).

Response envelope

response.json
# Successful request (200 / 201)
{ "status": 201, "success": true, "message": "OK", "data": { … } }

# Validation error (400) — which field was rejected and why is in error/message
{ "status": 400, "success": false, "error": "MEDIA_NOT_SUPPORTED_ON_CHANNEL", "message": "…" }

# Rate limit (429)
{ "error": "Too many requests, please slow down." }
TopicRule
PaginationList endpoints take the page (starting at 1) and limit query parameters. Default order is createdAt descending; you can pass JSON to sort: sort={"createdAt":-1}.
FilteringThe filter parameter is URL-encoded JSON: filter={"phone":"9055"}. Text fields match case-insensitively as "contains"; the tags field can be given as an array.
IdentifiersAll _id values are 24-character hexadecimal strings.
Phone numbersWith country code, without plus sign or spaces: 905551112233.
DatesISO 8601, UTC. Export endpoints take date_type (TODAY, THIS_WEEK, THIS_MONTH, THIS_YEAR) or start / end (YYYY-MM-DD).
Rate limit100 requests per minute per IP. Beyond it 429; the remaining quota can be read from the RateLimit response headers.
Body sizeUp to 10 MB on endpoints that carry media.
LanguageThe optional language header (TR, EN …) sets the language of response messages.

Contacts

A contact is unique: the phone number is the identity. A second create request with the same number does not open a new record; it updates the existing one.

EndpointDescription
GET/api/contactsPaginated, filtered list, e.g. filter={"userProfileName":"Jane"}.
GET/api/contacts/phone/:phoneOne contact by phone.
GET/api/contacts/:idOne contact by id.
POST/api/contactsCreate a contact (update if it exists). Body below.
POST/api/contacts/bulkBulk create: { "data": [ {…}, {…} ], "uniqueData": "phone" }. With uniqueData, existing records with the same value are not recreated.
PUT/api/contacts/:idUpdate; send only the changed fields (phone, userProfileName, email, language, tags, custom).
PUT/api/contactsBulk tag assignment: { "contact_ids": ["…"], "tags": ["…"] }.
PUT/api/contacts/delete/:idDelete a contact.
PUT/api/contacts/delete-manyBulk delete by condition: { "condition": [ { "column": "phone", "operation": "EQUAL", "value": "9055…" } ] }. operation: EQUAL, NOT_EQUAL, CONTAINS.
PATCH/api/contacts/anonymize/:phoneAnonymise a contact (for "right to be forgotten" requests).
POST /api/contacts
{
  "phone": "905551112233",          // required
  "userProfileName": "Jane Doe",    // required — the name shown in the dashboard
  "email": "jane@example.com",
  "language": "EN",
  "tags": ["66201122334455667788990a"],
  "custom": { "customerNo": "C-4821", "segment": "vip" }  // free custom fields; new keys become columns in the dashboard
}

Tags

Contact tags and ticket tags are separate lists.

EndpointDescription
GET/api/tagsPaginated list of contact tags.
POST/api/tagsCreate a contact tag: { "name": "VIP", "color": "#ff0f30" }.
GET/api/ticket/tagsList ticket tags.
POST/api/ticket/tagCreate a ticket tag.

Sending Messages

The WhatsApp rule: if the customer wrote to you within the last 24 hours you can send free-form messages; otherwise you can only reach them with a Meta-approved template. The endpoints are split along these two cases.

EndpointDescription
POST/api/send-messageFree-form message to a contact with an open session. type: TEXT, IMAGE, DOCUMENT, VIDEO. Give media as link (URL) or media (Base64) + file_name.
POST/api/notification/send-singleNotification with an approved template to one contact (no session window needed). Body in Notifications.
POST/api/message/one-personSurvey invitation to one contact: { "name": "…", "survey_id": "…", "phone": "9055…", "tags": [] }.
POST/api/message/bulkCreates a sending group from contacts matching a condition (does not send yet): { "name", "survey_id", "condition": [ { "column", "operation", "value" } ] }.
POST/api/message/send/:idSends the created group. Empty body.
POST/api/message/directInstant survey invitation to one contact with custom template parameters (customNotification).
POST/api/message/basic-directSame as direct; template fields (template_name, template_lang, bodyPayload) at the root of the body.
GET/api/messageList sending tasks.
GET/api/message/task/:taskIdStatus of one sending task.
POST /api/send-message
# Text
{ "type": "TEXT", "phone": "905551112233", "text": "Hi! Your order has been shipped." }

# Image by URL
{ "type": "IMAGE", "phone": "905551112233", "link": "https://example.com/campaign.jpg", "text": "September campaign" }

# Document as Base64
{ "type": "DOCUMENT", "phone": "905551112233", "media": "JVBERi0xLjcK…", "file_name": "invoice.pdf" }

The response is 201 and echoes the body you sent in data. If the channel does not support media you get 400 with MEDIA_NOT_SUPPORTED_ON_CHANNEL.

Surveys

Surveys are designed in the dashboard; through the API you list them, read results and generate personalised pre-filled links.

EndpointDescription
GET/api/survey/formPaginated list of surveys.
GET/api/survey/pure-surveyPlain list (id and name), unpaginated.
GET/api/survey/form/:idThe survey form: questions, options, flow.
GET/api/statistic/:survey_idSurvey results (sessions and answers), paginated.
GET/api/survey/pre-start/:surveyForm_idLists the pre-filled links generated for this survey.
POST/api/survey/pre-start/:surveyForm_idGenerates a pre-filled short link. The body is free JSON ({ "orderNo": "12345", "segment": "vip" }); the fields are available in the survey flow and arrive in webhooks as preData. data in the response carries the short link: https://cxpe.net/pXXXXXXXX.

Notifications (Template Messages)

A notification schema is Cxperium's counterpart of the WhatsApp template submitted to Meta for approval. Creating, listing and deleting schemas is open on Professional and higher plans.

EndpointDescription
POST/api/notification/schemaCreates a template and submits it to Meta. Required: name, category (UTILITY, MARKETING, AUTHENTICATION), lang. Optional: headerOptions, bodyOptions, footerText, buttonOptions, carouselOptions.
GET/api/notification/schemaLists templates and their approval status.
GET/api/notification/schema/:idOne template.
DELETE/api/notification/schema/:templateNameDeletes the template.
POST/api/notification/send-singleSends a template notification to one contact. Body below.
GET/api/notification/formLists notification sending tasks.
GET/api/notification/form/:taskIdDetails of one task.
GET/api/notification/exportExports notification records as Excel (date_type or start/end).
GET/api/notification/notification-message-status/:idDelivery status of one notification (sent, delivered, read, failed).
POST /api/notification/send-single
{
  "contact": { "phone": "905551112233" },
  "notification": {
    "template_name": "order_shipped",       // Meta-approved template name
    "name": "Shipping notification",        // task name (shown in the dashboard)
    "data": {
      "template_lang": "en",
      "bodyPayload": ["Jane", "TR-48291"],  // {{1}}, {{2}} … in order
      "headerPayload": { "format": "IMAGE", "link": "https://example.com/shipping.jpg" },  // if the template has a media header
      "buttonPayload": [ { "type": "QUICK_REPLY", "payload": "track_shipping" } ]          // if the template has buttons
    }
  }
}

Fill the body according to your template's structure: an empty bodyPayload array for a template without variables, no headerPayload for a template without a header. When a bulk send finishes, the NOTIFICATION_SENDING_COMPLETED webhook event arrives.

Tickets

Ticket statuses are NEW, OPEN, PENDING, CLOSED. Ticket creation accepts multipart/form-data so that files can be attached.

EndpointDescription
GET/api/ticketPaginated, filtered, sorted list: filter={"status":"NEW"}&sort={"createdAt":-1}.
GET/api/ticket/:_idOne ticket with its comments.
GET/api/ticket/task/:taskIdBy the ticket number shown in the dashboard.
GET/api/ticket/contact/:contactNumberA contact's tickets by phone.
GET/api/ticket/contact-by-id/:_idTickets by contact id.
GET/api/ticket/assignee-countOpen ticket counts per agent.
GET/api/last-answer/:idThe ticket's last answer.
POST/api/ticketCreate a ticket (multipart). Fields: subject, contactId, message (required); tags (JSON array), media (one or more files).
POST/api/ticket/send-comment/user/:_idComment on a ticket on behalf of a dashboard user: { "message": "…" }.
POST/api/ticket/send-comment/phone/:_id/:phoneA message/comment on the ticket delivered to the contact over WhatsApp: { "message": "…" }.
POST/api/ticket/:_id/wa/:phone/commentsAdds a comment the contact sent over WhatsApp to the ticket (for bot integrations).
PATCH/api/assignee-change/:_id/:type/:assigneeIdAssigns the ticket to a user.
create-ticket.sh
curl -X POST https://api.cxperium.com/api/ticket \
  -H "apikey: $CX_API_KEY" \
  -F "subject=Delivery delay" \
  -F "contactId=6612cc33dd44ee55ff667788" \
  -F "message=My order has not arrived for 5 days." \
  -F 'tags=["66201122334455667788990a"]' \
  -F "media=@invoice.pdf"

There are webhook events for creation, status and assignee changes and comments: Ticket events.

Live Chat

Live support chats are the records agents see in the dashboard. Through the API you can open chats, send messages and change the team or status.

EndpointDescription
POST/api/chatCreate a chat: { "contactId": "…", "message": "…", "teamId": "…" } (only contactId is required). If the contact has an open chat, that one is returned.
GET/api/chatList chats. Unassigned new chats: filter={"status":"NEW","assignee":{"exists":false}}.
GET/api/chat/active/:idWhether the contact has an open chat.
POST/api/chat/send-messageSends a message to a contact, opening a chat if needed: { "message": "…", "contactId": "…" }.
POST/api/chat/send-message/:_idMessage to an existing chat (message and/or media).
POST/api/chat/send-message/phone/:_idMessage by phone: { "phone": "9055…", "message": { "text": "…" } }.
PATCH/api/chat/team-change/:_id/:teamIdMoves the chat to another team.
PATCH/api/chat/status-change/:_id/:statusChanges the status (NEW, OPEN, PENDING, CLOSED).
PUT/api/chat/:_id/tagsAssigns tags to the chat: { "tags": ["…"] }.
GET/api/chat/exportExports chat records (date_type or start/end).
PUT/api/chat/settings/timeoutUpdates the session timeout setting.
GET/api/business-hoursBusiness hours; /api/business-hours/:phone for a specific number.
GET/api/teamsLists teams.
GET/api/subuserLists sub-users (agents); /api/subuser/:id one record, updated with PUT (e.g. chatAssignmentThreshold).

For chat creation, message, status and assignee events see Chat events.

Webhook Management

Webhook definitions can be managed from the dashboard or the API; both see the same record. Delivery is exclusive to the Enterprise plan.

EndpointDescription
POST/api/webhookCreate or update (updates when the address matches): webhook_adress, webhook_time (event codes), access_survey (survey ids or ["*"]), webhook_active.
GET/api/webhookLists the defined webhooks.
DELETE/api/webhookDeletes by address: { "webhook_adress": "https://…" }.

Event codes and the fields sent: Webhook Reference.

Assistant, Catalog, Pipeline and Other

Assistant endpoints used by chatbot integrations, WhatsApp catalog/product messages, and Pipeline management.

AI assistant

EndpointDescription
GET/api/assistant/configurationAssistant configuration.
GET/api/assistant/intentIntent list.
GET/api/assistant/localizationLocalization texts; /:languageId for one language.
POST/api/assistant/localizationBulk add texts: { "data": [ { "languageId", "key", "value" } ] }.
POST/api/assistant/sessionCreate/update a contact session: { "phone", "language", "data": [ { "message", "isLast" } ], "isActive" }.
GET/api/assistant/sessionSessions; /:phone by number, /api/assistant/session-id/:id by id.
POST/api/assistant/reportAssistant report record: { "phone", "intentName", "message", "nlp" }; /api/assistant/bulk-report in bulk.
GET/api/assistant/reportReports (start, end); /export Excel; /session-without-ticket numbers that wrote in the range without a ticket.
POST/api/assistant/shopping-cartsCart record: { "cartKey", "customerId", "productCode", "quantity", "unitPrice" }; PUT updates, GET /:cartKey reads.
PATCH/api/assistant/stage/:idUpdate a knowledge base (stage); /file/:fileId/status updates a file's processing status.
GET/api/wabaThe account's WhatsApp number details.

Catalog and product messages Meta Cloud API only

EndpointDescription
GET/api/catalog/catalogsLists catalogs; POST creates a new catalog.
GET/api/catalog/productsLists products; POST adds, DELETE /:productId removes.
GET/api/catalog/commerce-settingsCart and catalog visibility; updated with POST.
POST/api/catalog/send/single-productSingle product message; /multi-product multiple products, /catalog catalog message.

Pipeline

EndpointDescription
GET/api/funnel/stagesLists stages; POST creates, PATCH /:id updates, DELETE /:id deletes, POST /:id/move-stage reorders.
GET/api/funnel/cardsLists lead cards; POST creates, PATCH /:id updates, DELETE /:id deletes, POST /:id/move-card changes the stage.
POST/api/funnel/cards/search-by-custom-fieldSearches cards by a custom field.
POST/api/funnel/cards/:id/add-activityAdds an activity (todo, call, mail, meeting, document); PATCH …/update-activity/:activityId, DELETE …/remove-activity.
POST/api/funnel/cards/:id/add-logAdds a note/log; DELETE …/remove-log. Likewise add-follower/remove-follower and add-attachment/remove-attachment.

For using Pipeline in the dashboard see CRM Features → Pipeline.

Couldn't find what you're looking for?

Let our technical team guide you through your integration — send us your question and we'll get back to you the same day.

Dedicated technical support · Free integration consulting