Select the channel
Use a Helixcer channelId. Credentials stay encrypted on the connection.
Helixcer Developer API
The Helixcer Messaging API gives external systems one secure path into the shared inbox. Available now: send approved WhatsApp templates from an ERP, CRM, store, or custom app and track Meta delivery on the same conversation.
api.chat.helixcer.comBearer hxc_live_…application/jsonWhatsAppAvailable now: WhatsApp template messages. Telegram and Instagram external-send endpoints are not enabled yet. Live WhatsApp delivery requires a valid Meta access token and an approved template whose name, language, components, and parameters match the request.
Quickstart
Choose a saved WhatsApp channel, provide the recipient and approved Meta template, then retain the returned Helixcer message ID.
https://api.chat.helixcer.com/api/v1/whatsapp/template-messagescurl --request POST \
--url https://api.chat.helixcer.com/api/v1/whatsapp/template-messages \
--header 'Authorization: Bearer hxc_live_REPLACE_WITH_YOUR_KEY' \
--header 'X-Workspace-Id: b0963871-a454-4fb8-94eb-80464e2358b0' \
--header 'Content-Type: application/json' \
--data '{
"channelId": "66d66f0c-0ca2-4c79-96b9-d182d5a481b4",
"to": "919999999999",
"contact": { "name": "Asha", "company": "Acme Retail", "tags": ["VIP"] },
"clientReference": "customer-4082",
"template": {
"name": "hello_world",
"language": { "code": "en_US" }
}
}'
Use a Helixcer channelId. Credentials stay encrypted on the connection.
Name, locale, components, parameter types, and indexes must match the approved template.
Save messageId. Poll its status or use the inbox and status webhooks.
Authentication
Create a workspace key in Helixcer and include it as a Bearer token. Every request must also include the workspace ID shown under Workspace in X-Workspace-Id. Helixcer verifies that it matches the API key; the header cannot grant access to another workspace. Sending requires whatsapp:template:send; reading status requires messages:read. Each send selects one of that workspace's connections with channelId.
Authorization: Bearer hxc_live_REPLACE_WITH_YOUR_KEY
X-Workspace-Id: b0963871-a454-4fb8-94eb-80464e2358b0
Content-Type: application/jsonAn API key is shown once. Store it in a server-side secret manager or environment variable. Never place it in browser JavaScript, a mobile app, logs, screenshots, support messages, or a source repository. Revoke and replace it immediately if it may have leaked.
Request contract
Helixcer validates the outer envelope, finds the channel's encrypted credentials, renders the approved template for the inbox, records its text and media, and submits a Meta-compatible template payload.
https://api.chat.helixcer.com/api/v1/whatsapp/template-messages{
"channelId": "66d66f0c-0ca2-4c79-96b9-d182d5a481b4",
"to": "919999999999",
"contact": {
"name": "Asha",
"company": "Acme Retail",
"tags": ["VIP", "Orders"]
},
"clientReference": "order-1001",
"previewText": "Order ORD-1001 confirmed",
"template": {
"name": "order_confirmation",
"language": { "code": "en_US" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Asha" },
{ "type": "text", "text": "ORD-1001" }
]
}
]
}
}| Field | Required | Description |
|---|---|---|
channelId | Yes | Helixcer ID of the saved WhatsApp channel that sends the message. |
to | Yes | Recipient's WhatsApp number in international digits-only format, for example 919999999999. |
contact | No | Optional contact fields to save or update on the recipient. Include only the fields you want to change. Omitted fields keep their existing values and are never cleared to null. |
contact.name | No | Contact display name. Alias: displayName. When both are sent they must match. |
contact.company | No | Company or organization stored on the contact. |
contact.tags | No | Array of tag strings. When provided, replaces the contact's current tags. |
clientReference | No | Your order, ticket, campaign, or transaction ID. It is stored with and returned on the message. |
previewText | No | Optional inbox-text override. When omitted, Helixcer renders the approved Meta template with the supplied variables, media, footer, and action labels. |
template | Yes | Meta-native template object. name and language.code are required; add components when expected. |
Do not send connection credentials. Meta access token, WABA ID, phone-number ID, Graph version, messaging_product, and recipient_type belong to the selected Helixcer channel.
Return the message templates stored on the selected WhatsApp Business Account, including name, language, status, category, components, and variables.
https://api.chat.helixcer.com/api/v1/whatsapp/templates?channelId=66d66f0c-0ca2-4c79-96b9-d182d5a481b4| Field | Required | Description |
|---|---|---|
channelId | Yes | Helixcer ID of the WhatsApp channel whose WABA templates should be listed. Query parameter. |
refresh | No | Set to 1 to bypass Helixcer's short template cache and reload from Meta. |
curl --request GET \
--url 'https://api.chat.helixcer.com/api/v1/whatsapp/templates?channelId=66d66f0c-0ca2-4c79-96b9-d182d5a481b4' \
--header 'Authorization: Bearer hxc_live_REPLACE_WITH_YOUR_KEY' \
--header 'X-Workspace-Id: b0963871-a454-4fb8-94eb-80464e2358b0'{
"status": true,
"channelId": "66d66f0c-0ca2-4c79-96b9-d182d5a481b4",
"items": [
{
"templateId": "123456789012345",
"name": "order_confirmation",
"language": { "code": "en_US" },
"status": "APPROVED",
"category": "UTILITY",
"components": [
{ "type": "body", "text": "Hello {{1}}, order {{2}} is confirmed." }
],
"variables": [
{ "component": "body", "componentIndex": 0, "parameterIndex": 0, "key": "1", "kind": "text", "example": "" },
{ "component": "body", "componentIndex": 0, "parameterIndex": 1, "key": "2", "kind": "text", "example": "" }
]
}
],
"truncated": false,
"requestId": "96fe6806-a769-451e-918a-034b33d06dc1"
}Fetch one template by Meta template name for a WhatsApp channel. When the template exists in multiple languages, every matching variant is returned unless you filter with language.
https://api.chat.helixcer.com/api/v1/whatsapp/templates/order_confirmation?channelId=66d66f0c-0ca2-4c79-96b9-d182d5a481b4| Field | Required | Description |
|---|---|---|
template name | Yes | Path segment. Meta template name using lowercase letters, numbers, and underscores only. |
channelId | Yes | Helixcer ID of the WhatsApp channel. Query parameter. |
language | No | Optional language filter such as en_US. When omitted, all language variants for the name are returned. |
curl --request GET \
--url 'https://api.chat.helixcer.com/api/v1/whatsapp/templates/order_confirmation?channelId=66d66f0c-0ca2-4c79-96b9-d182d5a481b4&language=en_US' \
--header 'Authorization: Bearer hxc_live_REPLACE_WITH_YOUR_KEY' \
--header 'X-Workspace-Id: b0963871-a454-4fb8-94eb-80464e2358b0'{
"status": true,
"channelId": "66d66f0c-0ca2-4c79-96b9-d182d5a481b4",
"name": "order_confirmation",
"language": "en_US",
"items": [
{
"templateId": "123456789012345",
"name": "order_confirmation",
"language": { "code": "en_US" },
"status": "APPROVED",
"category": "UTILITY",
"components": [
{ "type": "body", "text": "Hello {{1}}, order {{2}} is confirmed." }
],
"variables": [
{ "component": "body", "componentIndex": 0, "parameterIndex": 0, "key": "1", "kind": "text", "example": "" },
{ "component": "body", "componentIndex": 0, "parameterIndex": 1, "key": "2", "kind": "text", "example": "" }
]
}
],
"requestId": "f2baa47a-97e6-47c8-a200-7a235cad5d92"
}Template patterns
Each panel shows the template portion of a request. Add the same top-level channelId, to, contact/reference fields, and required headers shown above.
Omit components when the approved template contains no runtime values.
"template": {
"name": "hello_world",
"language": { "code": "en_US" }
}Positional values map to {{1}}, {{2}}, and so on by array order.
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "ORD-1001" },
{ "type": "text", "text": "28 October" }
]
}
]For named variables, include each approved parameter_name. Do not mix named and positional values in one component.
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"parameter_name": "customer_name",
"text": "Asha"
},
{
"type": "text",
"parameter_name": "order_number",
"text": "ORD-1001"
}
]
}
]Use a header component only when the approved header contains a runtime text variable.
"components": [
{
"type": "header",
"parameters": [
{ "type": "text", "text": "ORD-1001" }
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Asha" }
]
}
]The media type must match the approved header. Supply exactly one source: a public HTTPS link or uploaded Meta media id.
"components": [{
"type": "header",
"parameters": [{
"type": "image",
"image": {
"link": "https://cdn.example.com/products/item-1001.jpg"
}
}]
}]"components": [{
"type": "header",
"parameters": [{
"type": "video",
"video": { "id": "META_MEDIA_ID" }
}]
}]"components": [{
"type": "header",
"parameters": [{
"type": "document",
"document": {
"link": "https://cdn.example.com/invoices/INV-1001.pdf",
"filename": "INV-1001.pdf"
}
}]
}]Use Meta's native typed parameters. amount_1000 is the amount multiplied by 1,000. Always provide a readable fallback.
"components": [{
"type": "body",
"parameters": [
{
"type": "currency",
"currency": {
"fallback_value": "INR 1,499.00",
"code": "INR",
"amount_1000": 1499000
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "31 October 2026"
}
}
]
}]Static CTA: When a phone number or URL is fully static in the approved template, omit its button component at send time. Meta renders it automatically.
Dynamic URL: Send only the approved variable value. The index is a zero-based string.
"components": [{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [
{ "type": "text", "text": "ORD-1001" }
]
}]For an approved URL ending /orders/{{1}}, this supplies only ORD-1001.
The payload returns with the customer's response and can drive your automation.
"components": [{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [{
"type": "payload",
"payload": "CONFIRM_ORDER_1001"
}]
}]A copy-code button commonly uses a coupon code parameter.
"components": [{
"type": "button",
"sub_type": "copy_code",
"index": "0",
"parameters": [{
"type": "coupon_code",
"coupon_code": "SAVE20"
}]
}]Authentication templates can include an OTP, copy-code button, and/or autofill or zero-tap URL. Pass exactly what Meta approved. Never place an OTP in a client reference or log.
Future-compatible
Helixcer keeps template.components Meta-native. Supported catalog/product, Flow, carousel/card, limited-time offer, and authentication components pass through without a second Helixcer-specific schema.
Helixcer validates the outer envelope and security boundary. Meta remains the authority on whether a component matches an approved template and whether the selected account can use it.
"template": {
"name": "recommended_products",
"language": { "code": "en_US" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Asha" }
]
},
{
"type": "button",
"sub_type": "catalog",
"index": "0",
"parameters": []
}
]
}This is illustrative, not a universal schema. Copy the exact structure, types, indexes, and values required by your approved template and the current Meta Cloud API.
Accepted response
Helixcer first records the message and queues provider delivery. Accepted sends therefore return 202 Accepted. The first messageStatus value is normally pending; Meta submission happens just after the response.
status reports whether the API request succeeded. messageStatus reports the message's delivery state.
The message exists in the inbox and provider delivery is running asynchronously.
The status route returns the latest stored result using the same flat shape.
Read the stable error code and decide whether the request is safe to retry.
{
"status": true,
"messageId": "594798db-1c00-481f-adab-137d1c80b2d8",
"conversationId": "9e9411e9-c1a7-4a66-a46f-e6e31d9577da",
"contactId": "af4d6756-e658-4b5f-8593-f1daef0998b7",
"channelId": "66d66f0c-0ca2-4c79-96b9-d182d5a481b4",
"messageStatus": "pending",
"channelMessageId": "",
"error": "",
"clientReference": "order-1001",
"createdAt": "2026-10-25T10:30:12.442Z",
"statusUrl": "https://api.chat.helixcer.com/api/v1/messages/594798db-1c00-481f-adab-137d1c80b2d8",
"requestId": "96fe6806-a769-451e-918a-034b33d06dc1"
}Status API
https://api.chat.helixcer.com/api/v1/messages/{messageId}Use the same Bearer key and X-Workspace-Id header. The key requires the message-read scope and can read only messages it created.
A message can move to failed. Status updates are asynchronous, and some recipients or devices may not produce every intermediate event.
{
"status": true,
"messageId": "594798db-1c00-481f-adab-137d1c80b2d8",
"conversationId": "9e9411e9-c1a7-4a66-a46f-e6e31d9577da",
"contactId": "af4d6756-e658-4b5f-8593-f1daef0998b7",
"channelId": "66d66f0c-0ca2-4c79-96b9-d182d5a481b4",
"messageStatus": "delivered",
"channelMessageId": "wamid.HBgMOTE5OTk5OTk5OTk5FQIAERgS...",
"error": "",
"clientReference": "order-1001",
"createdAt": "2026-10-25T10:30:12.442Z",
"statusUrl": "https://api.chat.helixcer.com/api/v1/messages/594798db-1c00-481f-adab-137d1c80b2d8",
"requestId": "f2baa47a-97e6-47c8-a200-7a235cad5d92"
}Unified inbox
Helixcer resolves the WhatsApp identity, creates a contact and open conversation when needed, and records the outbound template before provider delivery runs.
Meta sends asynchronous status webhooks to the connected channel. Helixcer applies sent, delivered, read, or failed to the same item. Replies join the same contact and conversation, so agents see the complete thread.
Error handling
Use error.code, not the human-readable message. Include requestId or the matching X-Request-Id response header when contacting support.
{
"status": false,
"error": {
"code": "channel_not_ready",
"message": "The WhatsApp channel is missing its access token.",
"requestId": "96fe6806-a769-451e-918a-034b33d06dc1"
}
}| Status | Meaning | Action |
|---|---|---|
400 | Malformed JSON, missing workspace header, missing or unknown field, or invalid parameter. | Correct the request; do not retry unchanged. |
401 | Missing, invalid, expired, or revoked API key. | Replace the key and ensure it is not logged. |
403 | Browser-origin request, workspace mismatch, or key lacks the required scope. | Send server-to-server; check the workspace ID and key permissions. |
404 | Channel, message, or API route was not found for this key. | Check the ID and confirm the channel belongs to the key's workspace. |
409 | The selected channel is not ready to send. | Read error.code and fix the channel setup. |
429 | Rate limit exceeded. | Wait for Retry-After before trying again. |
5xx | Temporary Helixcer, rate-limiter, or upstream failure. | Wait, then retry with exponential backoff. |
Before production
202 as recorded and queued, not delivered.Source of truth
Meta controls template approval, names, locales, component schemas, parameter types, limits, and feature availability by account and region. Use the current official payload for advanced components.