Lynkist Developers

Messages

Send pre-approved WhatsApp template messages through the tenant's active WABA.

The Messages API sends WhatsApp messages. Only pre-approved template messages are sendable via the Public API — free-form session messaging is dashboard-only because it requires careful policy enforcement (24-hour reply window, opt-out tracking) Lynkist does not yet expose to API integrators.

ScopeEndpoint
messages:sendPOST /messages/template

Base path: /api/v1/public/messages

Prerequisites

  1. The tenant must have an active, connected WABA (WhatsApp Business Account). If not, the endpoint returns 404 No active WABA account for this tenant.
  2. The template_name must exist and be in approved status under that WABA. See Templates for the approval flow.
  3. The recipient phone number must be in E.164 format (e.g. +919999999999).

POST /messages/template — Send a template message

curl -X POST https://api.lynkist.io/api/v1/public/messages/template \
  -H "Authorization: Bearer $LYNKIST_API_KEY" \
  -H "Idempotency-Key: 7c4d2e1a-…" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+919999999999",
    "template_name": "order_confirmation",
    "language": "en_US",
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Anurag" },
          { "type": "text", "text": "ORD-1042" }
        ]
      }
    ]
  }'

Request body

FieldTypeRequiredNotes
tostringYesRecipient phone in E.164 (+<country><number>).
template_namestringYesApproved template name.
languagestringNo (default en)Template locale, e.g. en_US, hi. Must match an approved variant.
componentsobject[]NoVariable substitutions. Required only if the template has variables.

components shape

The array follows Meta's Cloud API conventions. Each entry targets one component on the approved template (header, body, or button) and supplies parameters that fill its {{n}} placeholders in order.

[
  {
    "type": "header",
    "parameters": [
      { "type": "image", "image": { "link": "https://example.com/banner.jpg" } }
    ]
  },
  {
    "type": "body",
    "parameters": [
      { "type": "text", "text": "Anurag" },
      { "type": "text", "text": "ORD-1042" },
      { "type": "text", "text": "https://example.com/track/ORD-1042" }
    ]
  },
  {
    "type": "button",
    "sub_type": "url",
    "index": "0",
    "parameters": [
      { "type": "text", "text": "ORD-1042" }
    ]
  }
]

Parameter type values: text, currency, date_time, image, document, video, payload. See Meta's parameter reference for the full grammar.

Response

200 OK

{
  "message_id": "wamid.HBgM…",
  "status": "accepted",
  "to": "+919999999999"
}

status is always "accepted" on success — it means the WhatsApp upstream accepted the message for delivery. It does not mean delivered. To track real delivery, subscribe to the message.* webhook events:

EventMeans
message.sentLynkist handed the message to Meta.
message.deliveredMeta delivered to the recipient device.
message.readRecipient opened the message (if read receipts on).
message.failedMeta reported a permanent failure (carries error code).

message_id is Meta's wamid — quote it when correlating with webhook events or Meta support.

Idempotency

Send Idempotency-Key: <uuid-v4> on every request. Retries with the same key replay the cached response instead of sending a duplicate message — the entry lives 24 hours. See API Reference → Idempotency.

Errors

StatusWhen
400Body missing required fields, malformed JSON, or non-E.164 phone
401Missing / invalid API key
403Key lacks messages:send
404No active WABA account for this tenant — connect a WABA via the dashboard first
422Validation error (Pydantic) — bad components shape
429Rate limit hit
502 / 504Meta upstream error or timeout — safe to retry

A message.failed webhook may still arrive even on a 200 OK — that means Meta accepted but then could not deliver (unreachable number, opted out, template paused, etc.). The webhook payload includes Meta's numeric error code.

Common pitfalls

  • Language mismatch. language must match the language of an approved variant. A template approved in en_US will not send under en — list GET /templates to see exact values.
  • Variable count mismatch. Sending fewer parameters than the template has {{n}} placeholders rejects with 422.
  • Sending to opted-out numbers. The send returns 200 OK, then arrives as message.failed via webhook. Track opt-outs in your contact custom fields.
  • Marketing rate limits. Meta enforces per-WABA marketing tiers separately from Lynkist's rate limits. A message.failed with code 131056 means you hit Meta's marketing cap.
Messages — Lynkist Developers | Lynkist