Helixcer API
Messaging APIv1

Helixcer Developer API

Connect your apps to the Helixcer inbox.

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.

Base URLapi.chat.helixcer.com
AuthenticationBearer hxc_live_…
Formatapplication/json
Available channelWhatsApp

Available 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

Send a template from your server

Choose a saved WhatsApp channel, provide the recipient and approved Meta template, then retain the returned Helixcer message ID.

POSThttps://api.chat.helixcer.com/api/v1/whatsapp/template-messages
cURL · simple template
curl --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" }
    }
  }'
1

Select the channel

Use a Helixcer channelId. Credentials stay encrypted on the connection.

2

Send Meta-native data

Name, locale, components, parameter types, and indexes must match the approved template.

3

Track the message

Save messageId. Poll its status or use the inbox and status webhooks.

Authentication

Your key stays on your server

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.

A Helixcer key is not a Meta token. External applications never receive the Meta token, WABA ID, or phone-number ID saved on the channel.
Required headers
Authorization: Bearer hxc_live_REPLACE_WITH_YOUR_KEY
X-Workspace-Id: b0963871-a454-4fb8-94eb-80464e2358b0
Content-Type: application/json

An 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

Send a template message

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.

POSThttps://api.chat.helixcer.com/api/v1/whatsapp/template-messages
JSON request body
{
  "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" }
        ]
      }
    ]
  }
}
FieldRequiredDescription
channelIdYesHelixcer ID of the saved WhatsApp channel that sends the message.
toYesRecipient's WhatsApp number in international digits-only format, for example 919999999999.
contactNoOptional 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.nameNoContact display name. Alias: displayName. When both are sent they must match.
contact.companyNoCompany or organization stored on the contact.
contact.tagsNoArray of tag strings. When provided, replaces the contact's current tags.
clientReferenceNoYour order, ticket, campaign, or transaction ID. It is stored with and returned on the message.
previewTextNoOptional inbox-text override. When omitted, Helixcer renders the approved Meta template with the supplied variables, media, footer, and action labels.
templateYesMeta-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.

WhatsApp

List all templates

Return the message templates stored on the selected WhatsApp Business Account, including name, language, status, category, components, and variables.

GEThttps://api.chat.helixcer.com/api/v1/whatsapp/templates?channelId=66d66f0c-0ca2-4c79-96b9-d182d5a481b4
FieldRequiredDescription
channelIdYesHelixcer ID of the WhatsApp channel whose WABA templates should be listed. Query parameter.
refreshNoSet to 1 to bypass Helixcer's short template cache and reload from Meta.
cURL · list templates
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'
200 · template list
{
  "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"
}

WhatsApp

Fetch template

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.

GEThttps://api.chat.helixcer.com/api/v1/whatsapp/templates/order_confirmation?channelId=66d66f0c-0ca2-4c79-96b9-d182d5a481b4
FieldRequiredDescription
template nameYesPath segment. Meta template name using lowercase letters, numbers, and underscores only.
channelIdYesHelixcer ID of the WhatsApp channel. Query parameter.
languageNoOptional language filter such as en_US. When omitted, all language variants for the name are returned.
cURL · fetch template
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'
200 · template
{
  "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

Use the components Meta approved

Each panel shows the template portion of a request. Add the same top-level channelId, to, contact/reference fields, and required headers shown above.

Simple template with no variables No components

Omit components when the approved template contains no runtime values.

template
"template": {
  "name": "hello_world",
  "language": { "code": "en_US" }
}
Positional and named body variables Body

Positional values map to {{1}}, {{2}}, and so on by array order.

Positional parameters
"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.

Named parameters
"components": [
  {
    "type": "body",
    "parameters": [
      {
        "type": "text",
        "parameter_name": "customer_name",
        "text": "Asha"
      },
      {
        "type": "text",
        "parameter_name": "order_number",
        "text": "ORD-1001"
      }
    ]
  }
]
Text header variable Header

Use a header component only when the approved header contains a runtime text variable.

Text header
"components": [
  {
    "type": "header",
    "parameters": [
      { "type": "text", "text": "ORD-1001" }
    ]
  },
  {
    "type": "body",
    "parameters": [
      { "type": "text", "text": "Asha" }
    ]
  }
]
Image, video, and document headers Media

The media type must match the approved header. Supply exactly one source: a public HTTPS link or uploaded Meta media id.

Image · URL
"components": [{
  "type": "header",
  "parameters": [{
    "type": "image",
    "image": {
      "link": "https://cdn.example.com/products/item-1001.jpg"
    }
  }]
}]
Video · media ID
"components": [{
  "type": "header",
  "parameters": [{
    "type": "video",
    "video": { "id": "META_MEDIA_ID" }
  }]
}]
Document · URL
"components": [{
  "type": "header",
  "parameters": [{
    "type": "document",
    "document": {
      "link": "https://cdn.example.com/invoices/INV-1001.pdf",
      "filename": "INV-1001.pdf"
    }
  }]
}]
Currency and date/time parameters Typed values

Use Meta's native typed parameters. amount_1000 is the amount multiplied by 1,000. Always provide a readable fallback.

Currency + date/time
"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 and dynamic call-to-action buttons CTA

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.

Dynamic URL suffix
"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.

Quick-reply button Interactive

The payload returns with the customer's response and can drive your automation.

Quick reply
"components": [{
  "type": "button",
  "sub_type": "quick_reply",
  "index": "0",
  "parameters": [{
    "type": "payload",
    "payload": "CONFIRM_ORDER_1001"
  }]
}]
Copy-code and authentication templates Code / OTP

A copy-code button commonly uses a coupon code parameter.

Copy code
"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

Advanced components pass through

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.

Illustrative catalog button
"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

Every valid send is asynchronous

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.

202 Accepted

Stored and queued

The message exists in the inbox and provider delivery is running asynchronously.

GET 200

Current state

The status route returns the latest stored result using the same flat shape.

4xx / 5xx

Request rejected

Read the stable error code and decide whether the request is safe to retry.

202 · accepted for async delivery
{
  "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

Read the current message state

GEThttps://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.

pending→retrying→submitted→sent→delivered→read

A message can move to failed. Status updates are asynchronous, and some recipients or devices may not produce every intermediate event.

200 · current status
{
  "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

External sends stay in the conversation

Helixcer resolves the WhatsApp identity, creates a contact and open conversation when needed, and records the outbound template before provider delivery runs.

Your apptemplate request
→
Helixcerrecord in chatbox
→
MetaWhatsApp delivery
→
Customermessage & reply

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.

Machine-to-machine status: poll the GET endpoint or use the chatbox today. When Helixcer outbound status webhooks are enabled, consumers should verify signatures, acknowledge quickly, deduplicate event IDs, expect retries and out-of-order events, and reconcile through GET.

Error handling

Stable codes for application logic

Use error.code, not the human-readable message. Include requestId or the matching X-Request-Id response header when contacting support.

Standard error
{
  "status": false,
  "error": {
    "code": "channel_not_ready",
    "message": "The WhatsApp channel is missing its access token.",
    "requestId": "96fe6806-a769-451e-918a-034b33d06dc1"
  }
}
StatusMeaningAction
400Malformed JSON, missing workspace header, missing or unknown field, or invalid parameter.Correct the request; do not retry unchanged.
401Missing, invalid, expired, or revoked API key.Replace the key and ensure it is not logged.
403Browser-origin request, workspace mismatch, or key lacks the required scope.Send server-to-server; check the workspace ID and key permissions.
404Channel, message, or API route was not found for this key.Check the ID and confirm the channel belongs to the key's workspace.
409The selected channel is not ready to send.Read error.code and fix the channel setup.
429Rate limit exceeded.Wait for Retry-After before trying again.
5xxTemporary Helixcer, rate-limiter, or upstream failure.Wait, then retry with exponential backoff.

Before production

Security and reliability checklist

  • The WhatsApp channel is enabled and has a valid Meta access token and Phone Number ID.
  • The template name, locale, components, indexes, and parameters exactly match Meta's approved template.
  • Recipient numbers use international digits-only format.
  • The API key is stored only on your server and rotated periodically.
  • Your application treats 202 as recorded and queued, not delivered.
  • Retries use exponential backoff.
  • Logs exclude keys, OTPs, sensitive message content, and unnecessary personal data.
  • Status processing safely handles duplicate provider events and can reconcile through the GET endpoint.

Source of truth

Official Meta references

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.