Text messages

Text messages

A plain text message is the simplest thing you can send on WhatsApp: one message string through POST /send. It's also the message type most constrained by the 24-hour customer service window, so it's the best place to learn that rule.


Send a text message

Post to /api/app-whatsapp/send with a channelId, the recipient's E.164 number in to, and your text in the message field. That's the entire body — no other content field.

curl -X POST https://api.telenow.ai/api/app-whatsapp/send \
  -H "Authorization: Bearer vai_app_…" \
  -H "Content-Type: application/json" \
  -d '{
    "channelId": "b1e2c3d4-…",
    "to": "+919876543210",
    "message": "Hi Asha! Your order #1234 has shipped and will arrive Thursday."
  }'
await fetch('https://api.telenow.ai/api/app-whatsapp/send', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer vai_app_…',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    channelId: 'b1e2c3d4-…',
    to: '+919876543210',
    message: 'Hi Asha! Your order #1234 has shipped.',
  }),
})
import requests

requests.post(
    'https://api.telenow.ai/api/app-whatsapp/send',
    headers={'Authorization': 'Bearer vai_app_…'},
    json={
        'channelId': 'b1e2c3d4-…',
        'to': '+919876543210',
        'message': 'Hi Asha! Your order #1234 has shipped.',
    },
)
{ "success": true, "data": { "wamid": "wamid.HBgLMTQxNTU1MDEwMBUCABIYFj…" } }

message carries plain text. WhatsApp renders its own light formatting (*bold*, _italic_, ~strike~, ```mono```) and auto-links bare URLs. Keep it under 4096 characters — longer bodies are rejected.

Get your channelId from GET /api/app-whatsapp/channels — it's the id of the WhatsApp number you connected. See WhatsApp overview.

The returned wamid

Every successful send returns a wamid (WhatsApp message ID). It is the one durable handle on the message, and it's what ties the send to its delivery lifecycle: each whatsapp.message.status webhook you receive carries the same wamid, letting you correlate sent → delivered → read (or failed) back to this exact message.

{
  "event": "whatsapp.message.status",
  "channelId": "b1e2c3d4-…",
  "wamid": "wamid.HBgLMTQxNTU1MDEwMBUCABIYFj…",
  "status": "delivered",
  "recipient": "+919876543210",
  "timestamp": "2026-07-18T09:31:04Z"
}

There is no idempotency key on /senddedupe on the returned wamid. See Webhooks & events for the full status payload and signature verification.

Reply to a specific message

To quote a particular message — so it shows as a threaded reply under the message you're answering, just like tapping Reply in the WhatsApp app — add reply_to set to that message's wamid. You get the wamid from the whatsapp.message.received webhook (its wamid field) or from the message history (each message's wamid).

curl -X POST https://api.telenow.ai/api/app-whatsapp/send \
  -H "Authorization: Bearer vai_app_…" \
  -H "Content-Type: application/json" \
  -d '{
    "channelId": "b1e2c3d4-…",
    "to": "+919876543210",
    "message": "Yes — it shipped this morning and arrives tomorrow.",
    "reply_to": "wamid.HBgLMTQx…"
  }'
{ "success": true, "data": { "wamid": "wamid.HBgLMjE2…" } }
  • reply_to (camelCase replyTo also works) is the wamid of the message you're replying to. It's optional — omit it for a normal, unquoted message.
  • It works with any content type, not just text — add reply_to alongside a mediaId, location, interactive, etc. on /send, and on the dashboard POST …/threads/{id}/send and …/channels/{id}/send routes.
  • Quoting is native-channel only. If the wamid isn't a real message in that conversation, WhatsApp ignores the quote and still delivers the message.

The 24-hour window

You can only send free-form text — this endpoint's message field — inside the 24-hour customer service window: the 24 hours that follow the customer's most recent inbound message. Every inbound message from that customer resets the clock.

Outside the window there is no open conversation to reply into, so free-form text is blocked and you must re-open the thread with an approved template message. Attempting a text send outside the window fails:

{ "success": false, "error": "24-hour window closed — send a template (131047)" }

The 131047 is Meta's error code for a closed window. Handle it by falling back to send-template; once the customer replies to the template, the window re-opens and free-form text works again.

SituationWhat you can send
Within 24h of the customer's last inbound messageFree-form message text (this page), media, interactive, etc.
Outside the 24h windowAn approved template only — free-form gets 400 131047

Dashboard equivalent

The programmatic route above is the primary surface. The dashboard sends the same text through a per-channel route on the org base — POST /api/orgs/{orgId}/whatsapp-hub/channels/{id}/send with a user JWT and the X-Org-Id header. Same 24-hour rule, same wamid back.

curl -X POST https://api.telenow.ai/api/orgs/{orgId}/whatsapp-hub/channels/{id}/send \
  -H "Authorization: Bearer <jwt>" \
  -H "X-Org-Id: {orgId}" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+919876543210", "message": "Hi Asha! Your order #1234 has shipped." }'