Skip to content

REST API v1 · Resource

Sending

Send texts, templates, media and interactive messages, and upload files to send by media id.

API reference · Sending

Endpoints

Paths are relative to https://fliok.com/api/v1. Each endpoint names the scope and the lowest key role it needs; a key without them gets 403 (see Authentication).

Sending

2
  • POST/sendSend a text, template, media or interactive messageScope messages:send · agent role or higher
  • POST/mediaUpload a document/image (up to 16 MB) to Meta and get a reusable media idScope messages:send · agent role or higher

Request bodies

What these endpoints take, field by field. A body that doesn’t match answers 400 naming the field.

POST /send

JSON body. Send an `Idempotency-Key` header (1–255 characters, remembered for 24 hours) and a retry of the same request returns the first answer instead of sending twice; the same key with a different body is refused (422 idempotency_key_reused).

FieldTypeWhat it is
torequiredstringThe customer’s number in E.164, with or without “+”. A number without a country code takes your sending number’s. For a customer WhatsApp shares no number for, pass the phone we report for them ("wa:<user id>") as it is — or leave `to` out and use `recipient`.
recipientstringInstead of `to`: the customer’s WhatsApp user id (the `userId` on webhooks and contacts, like "IN.21483648909127364650"), for a customer WhatsApp shares no phone number for. `to` wins when both are sent.
typerequiredstringtext, template, image, video, audio, document, interactive, reaction, location, sticker or contacts.
textstringThe message, for type "text" (required then, never empty). Needs an open 24-hour window.
payloadobjectFor every other type: Meta’s message object, { "type": "<type>", "<type>": { … } } — e.g. { "type": "document", "document": { "id": "<media id>", "filename": "invoice.pdf" } }.
payload.template.variablesarrayTemplate shortcut: the body’s {{1}}, {{2}}… in order. Fliok builds Meta’s components from the approved template, so you can leave components out.
payload.template.headerMediaobjectTemplate shortcut: { "id": "<media id>" } or { "link": "https://…" } (plus "filename" for a document) for an image, video or document header.
payload.template.headerText · couponCode · offerExpiresAtvariousTemplate shortcut: a text header’s variables, a coupon-code button’s code, a limited-time offer’s end (ISO time).
phoneNumberIduuidWhich of your numbers sends (GET /phone-numbers). Default: your first active number.
replyTostringA wamid to reply to: the message shows as a reply to it.

Returns 200 { "ok": true, "messageId": "<uuid>" } — queued, not yet delivered. Refusals: 422 outside_24h_window, 422 needs_phone_number (a verification-code template to a customer with no phone number — WhatsApp only delivers those to a number), 409 contact_opted_out, 402 plan_limit_reached (a new number past your contact limit) or quota_exceeded, 400 invalid_template_parameters / template_header_media_required. A refused send writes nothing: no contact, no conversation, no contact.created webhook.

POST /media

JSON body, up to 16 MB of file. Upload once, send the id as many times as you like for about 30 days. A workspace can have 4 uploads running at once, 2 of them over 10 MB (429 uploads_in_progress beyond, with Retry-After).

FieldTypeWhat it is
fileBase64requiredstringThe file’s bytes, base64-encoded, without a "data:" prefix.
mimeTypestringFor example application/pdf, image/jpeg, video/mp4. Default application/pdf.
filenamestringUp to 200 characters. Default document.pdf.
phoneNumberIduuidThe number that will send it. Default: your first active number.

Returns 200 { "id": "<Meta media id>" }

Examples

cURL
# Send a text message (needs an open 24h window). The Idempotency-Key makes a retry
# safe: the same key within 24 hours answers with the first result instead of sending twice.
curl -X POST https://fliok.com/api/v1/send \
  -H "Authorization: Bearer wa_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-12345-shipped" \
  -d '{
    "to": "+919876543210",
    "type": "text",
    "text": "Hello! Your order #12345 has been shipped."
  }'

# Send a template (the only way to open a NEW conversation)
curl -X POST https://fliok.com/api/v1/send \
  -H "Authorization: Bearer wa_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+919876543210",
    "type": "template",
    "payload": {
      "type": "template",
      "template": {
        "name": "order_confirmation",
        "language": { "code": "en" },
        "components": [
          {
            "type": "body",
            "parameters": [
              { "type": "text", "text": "Rahul" },
              { "type": "text", "text": "ORD-12345" }
            ]
          }
        ]
      }
    }
  }'

# The same template, letting Fliok build the components from the approved
# template: variables in order, and the header's media when it has one
curl -X POST https://fliok.com/api/v1/send \
  -H "Authorization: Bearer wa_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+919876543210",
    "type": "template",
    "payload": {
      "type": "template",
      "template": {
        "name": "order_confirmation",
        "language": { "code": "en" },
        "variables": ["Rahul", "ORD-12345"]
      }
    }
  }'

# Upload a document, then send it by media id
curl -X POST https://fliok.com/api/v1/media \
  -H "Authorization: Bearer wa_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fileBase64": "JVBERi0xLjQK...",
    "mimeType": "application/pdf",
    "filename": "invoice.pdf"
  }'
# -> { "id": "1234567890" }   (reusable for ~30 days)
# Successful response from POST /send (200 OK)
{
  "ok": true,
  "messageId": "4f6c1e2a-91d3-4a77-b0c2-5f1e8d9a3b44"
}

// The send is queued, not yet delivered. Poll GET /messages/{id}
// or subscribe to the message.status webhook for the outcome.

Message types and templates

Session Messages (Free-form)

24h window

When a customer messages you first, a 24-hour window opens. During this window you can send:

  • Text (type: "text")
  • Images, video, audio, documents, stickers — upload via /media
  • Interactive buttons and lists (type: "interactive")
  • Location, contacts and reactions

No template approval needed. Outside the window, /send returns 422 outside_24h_window.

Template Messages (Pre-approved)

Any time

To message a customer outside the 24h window (notifications, broadcasts, alerts), you must use Meta-approved templates:

  • Create it in the dashboard, or POST /templates
  • Submitted straight to Meta on the Cloud API — no reseller in between
  • Once approved, send it with /send using type: "template"
  • Poll GET /templates for the live approval status

3 categories: Marketing, Utility, Authentication. Meta prices and reviews each differently, and may recategorise on submission.

Marketing templates must include opt-out text (e.g., "Reply STOP to unsubscribe"). Templates with spammy language, excessive caps, or URLs in body text will be rejected by Meta.

Rate limits

The buckets these endpoints use. Burst is how many requests you can make back-to-back from a full bucket; sustained is how fast it refills.

BucketEndpointsBurstSustained
Send/send20050 / sec
Media upload/media20050 / sec

Every limit, the RateLimit-* headers and what to do on a 429: Rate limits.