Sign in

Developers

QNNECT Public API: send WhatsApp messages and templates, read the channel's template catalog, receive webhooks. Tokens and channel identifiers live in the cabinet, under “Integrations → API”.

OpenAPI 3.1 (YAML) Full docs as one .md llms.txt

MCP

Endpoint: https://qnnect.kz/mcp · Streamable HTTP
claude mcp add --transport http qnnect https://qnnect.kz/mcp

Without a token the MCP server serves the API documentation. With a read-only token from the cabinet (“API integrations & MCP” → “MCP”) it also exposes your company data — channels and templates: connect using https://qnnect.kz/mcp?token=<MCP_READ_TOKEN>. One-click install buttons for Cursor and VS Code live in the cabinet as well.

HTTP API for sending WhatsApp messages and templates through your QNNECT channel, and for reading the channel's template catalog.

Authentication

Every request is authenticated with two values you can copy from the QNNECT cabinet (Integrations → API):

  • channel_uuid — the channel identifier, part of the URL path;
  • api_token — the channel's secret token, passed as the token query parameter.

Both values are per-channel. Keep the token secret: anyone who has it can send messages at your expense. The token can be regenerated in the cabinet at any time (the old one stops working immediately).

Delivery model

Sending endpoints are asynchronous: a successful call returns 202 with a message_uuid — the message is queued and delivered in the background. Delivery progress is reported through webhook integrations (see Webhooks).

Errors

Errors are JSON objects {"error": "<code>"} with an optional human-readable message. HTTP status codes: 400 invalid input, 401 missing or invalid token, 403 sending suspended (company blocked or out of funds), 404 unknown channel or template.

Endpoints

POST /api/v1/{channel_uuid}/message/Send a text or media message

Sends a free-form message to a WhatsApp user. Free-form messages are deliverable only inside the 24-hour customer-service window opened by the user's last inbound message; outside the window use a template.

type selects the payload kind. For text the text field is required. For media types (image, video, audio, document, sticker) the media.url field is required; text becomes the caption where WhatsApp supports it (image, video, document).

Supported media formats and size limits:

typeMIMEmax size
imageimage/jpeg, image/png5 MB
videovideo/mp4, video/3gpp16 MB
audioaudio/aac, audio/mp4, audio/mpeg, audio/amr, audio/ogg16 MB
documentpdf, doc(x), xls(x), ppt(x), txt100 MB
stickerimage/webp500 KB

The media.url must be a public HTTPS URL.

Request body

FieldTypeRequiredDescription
typestring (text, image, video, audio, document, sticker)yesMessage kind. text requires text; media kinds require media.url.
phonestringyesRecipient phone in international format, digits only (e.g. 77778866697).
textstringnoMessage text for type=text; caption for image/video/document.
mediaobjectnoMedia descriptor; required for media types.

Example request

curl -X POST 'https://qnnect.kz/api/v1/{channel_uuid}/message/?token=YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "text",
  "phone": "77778866697",
  "text": "Hello! Your order is ready."
}'

Responses

  • 202 — Message accepted and queued for delivery.
  • 400 — Invalid input. error holds a machine-readable code.
  • 401 — Token is missing (missing_token) or wrong (invalid_token).
  • 403 — Sending is suspended — the company is blocked or out of funds (company_inactive).
  • 404 — No channel with this channel_uuid (channel_not_found).
POST /api/v1/{channel_uuid}/template/Send a template message

Sends an approved WhatsApp template. Templates work outside the 24-hour window and are the way to start a conversation.

values fills the numbered body placeholders {{1}}, {{2}}, … in order; the count must match the template exactly (see GET /api/v1/{channel_uuid}/templates/variables.body). header_values and button_values fill header/button placeholders when the template has them.

Media templates (IMAGE/VIDEO/DOCUMENT header): pass a public media_url (with optional media_mime_type) or a pre-registered media_id. Carousel templates: cards replaces card images by index; null keeps the sample image from the template.

Request body

FieldTypeRequiredDescription
phonestringyesRecipient phone in international format, digits only.
template_namestringyesTemplate name exactly as in the catalog (listTemplates).
valuesarraynoBody placeholder values {{1}}, {{2}}, … in order; count must match variables.body.
header_valuesarraynoHeader placeholder values, when the template header has variables.
button_valuesarraynoButton placeholder values (dynamic URL suffixes etc.).
media_urlstringnoPublic media URL for templates with a media header.
media_idstringnoPre-registered media id — alternative to media_url.
media_mime_typestringnoMIME type of media_url (e.g. image/jpeg).
cardsarraynoCarousel only — per-card image overrides; null keeps the sample image.

Example request

curl -X POST 'https://qnnect.kz/api/v1/{channel_uuid}/template/?token=YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "phone": "77778866697",
  "template_name": "order_confirm",
  "values": [
    "Ivan",
    "12345"
  ]
}'

Responses

  • 202 — Template accepted and queued for delivery.
  • 400 — Invalid input. error holds a machine-readable code.
  • 401 — Token is missing (missing_token) or wrong (invalid_token).
  • 403 — Sending is suspended — the company is blocked or out of funds (company_inactive).
  • 404 — Channel or template not found.
GET /api/v1/{channel_uuid}/templates/List channel templates

Returns the channel's template catalog with statuses and variable counts. Use it to discover what can be sent and how many values each template expects before calling the send endpoint.

All statuses are returned by default, including PENDING and REJECTED — only APPROVED templates can actually be sent.

Query parameters

  • status — Filter by exact status (e.g. APPROVED, PENDING, REJECTED).
  • category — Filter by category.
  • type — Filter by template type (TEXT, IMAGE, VIDEO, DOCUMENT, CAROUSEL, …).

Example request

curl 'https://qnnect.kz/api/v1/{channel_uuid}/templates/?token=YOUR_API_TOKEN'

Responses

  • 200 — Template catalog of the channel.
  • 401 — Token is missing (missing_token) or wrong (invalid_token).
  • 404 — No channel with this channel_uuid (channel_not_found).

Webhooks

HOOK incoming_messageIncoming message from a WhatsApp user

Sent to your configured webhook URL when a WhatsApp user writes to the channel. Webhook URLs are configured in the cabinet (Integrations → Webhooks) and can be enabled per event type.

Delivery: POST with JSON body, Content-Type: application/json; charset=utf-8. Respond with any 2xx within 12 seconds; failed deliveries are retried in the background.

Payload

FieldTypeDescription
eventstring (incoming_message, outgoing_message, message_status_update)Event type; matches the webhook name.
phonestringWhatsApp user's phone number.
channel_idstringChannel identifier (Gupshup app id) the event belongs to.
textstringMessage text (empty for non-text content).
message_uuidstringMessage identifier; matches QueuedResponse.message_uuid for API sends.
statusstringCurrent message status (queued, sent, delivered, read, failed, …).
senderstring (CLIENT, COMPANY, AI)Who authored the message.
timestampstringEvent time (ISO 8601).
HOOK outgoing_messageOutgoing message sent from the channel

Sent when a message leaves the channel — from the QNNECT UI, the API or an integration. Same delivery contract as incoming_message.

Payload

FieldTypeDescription
eventstring (incoming_message, outgoing_message, message_status_update)Event type; matches the webhook name.
phonestringWhatsApp user's phone number.
channel_idstringChannel identifier (Gupshup app id) the event belongs to.
textstringMessage text (empty for non-text content).
message_uuidstringMessage identifier; matches QueuedResponse.message_uuid for API sends.
statusstringCurrent message status (queued, sent, delivered, read, failed, …).
senderstring (CLIENT, COMPANY, AI)Who authored the message.
timestampstringEvent time (ISO 8601).
HOOK message_status_updateDelivery status of an earlier message changed

Sent when WhatsApp reports a status change for a previously sent message (sentdeliveredread, or failed). Correlate by message_uuid. Same delivery contract as incoming_message.

Payload

FieldTypeDescription
eventstring (incoming_message, outgoing_message, message_status_update)Event type; matches the webhook name.
phonestringWhatsApp user's phone number.
channel_idstringChannel identifier (Gupshup app id) the event belongs to.
textstringMessage text (empty for non-text content).
message_uuidstringMessage identifier; matches QueuedResponse.message_uuid for API sends.
statusstringCurrent message status (queued, sent, delivered, read, failed, …).
senderstring (CLIENT, COMPANY, AI)Who authored the message.
timestampstringEvent time (ISO 8601).