API v1

Twasel API

A RESTful API for programmatically sending and receiving WhatsApp messages. All requests and responses use JSON over HTTPS.

Base URL

https://twasel.io/api/v1/

Protocol

HTTPS only, UTF-8

Auth Method

API Key + Secret in Headers

Daily Limit

1,000 requests/day (adjustable)

Authentication

Include the following headers with every request. Generate your key and secret from Admin Panel → API tab.

HeaderDescription
X-API-KeyPublic key, generated from the API tab in admin panel
X-API-SecretSecret key, displayed only once upon creation
Content-Typeapplication/json for POST requests

Rate Limits

Each API key has a default daily limit of 1,000 requests. Exceeding it returns 429 Too Many Requests. Contact support to raise the limit.

POST /api/v1/send/text

Send a free text message to a WhatsApp number. Only works within the free reply window (24 hours from the customer's last message).

Parameters

FieldTypeDescription
tostringRequiredRecipient number in international format without + (e.g. 966501234567)
bodystringRequiredMessage text, max 4,096 characters
account_idintegerOptionalAccount ID, required only if the key is linked to multiple accounts

Example

curl -X POST https://twasel.io/api/v1/send/text \
  -H "X-API-Key: wk_abc123..." \
  -H "X-API-Secret: ws_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "966501234567",
    "body": "مرحباً! رسالة تجريبية من تواصل."
  }'
import requests

resp = requests.post(
    "https://twasel.io/api/v1/send/text",
    headers={
        "X-API-Key": "wk_abc123...",
        "X-API-Secret": "ws_xyz789...",
    },
    json={"to": "966501234567", "body": "مرحباً من تواصل!"}
)
print(resp.json())
const resp = await fetch("https://twasel.io/api/v1/send/text", {
  method: "POST",
  headers: {
    "X-API-Key": "wk_abc123...",
    "X-API-Secret": "ws_xyz789...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ to: "966501234567", body: "مرحباً من تواصل!" }),
});
console.log(await resp.json());

Response

{
  "ok": true,
  "wa_message_id": "wamid.HBgLOTY2NTAxMjM0..."
}
{
  "ok": false,
  "error": "to_and_body_required"
}
⚡ Try It

POST /api/v1/send/template

Send a Meta approved message template. Templates work even outside the free reply window. Each delivered template is billed by Meta directly.

Parameters

FieldTypeDescription
tostringRequiredRecipient number in international format without +
template_namestringRequiredTemplate name exactly as registered with Meta (e.g. order_confirmation)
languagestringOptionalLanguage code (default: ar)
componentsarrayOptionalTemplate variables in Meta components format
account_idintegerOptionalAccount ID, required only if the key is linked to multiple accounts

Example

curl -X POST https://twasel.io/api/v1/send/template \
  -H "X-API-Key: wk_abc123..." \
  -H "X-API-Secret: ws_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "966501234567",
    "template_name": "order_confirmation",
    "language": "ar",
    "components": [{
      "type": "body",
      "parameters": [
        { "type": "text", "text": "أحمد" },
        { "type": "text", "text": "ORD-1234" }
      ]
    }]
  }'

Response

{
  "ok": true,
  "wa_message_id": "wamid.HBgLOTY2NTAxMjM0..."
}
{
  "ok": false,
  "error": "to_and_template_name_required"
}
⚡ Try It

POST /api/v1/send/media

Send a media file (image, video, document, audio) via a direct public HTTPS URL

Parameters

FieldTypeDescription
tostringRequiredRecipient number in international format without +
typestringRequiredimage | video | document | audio
urlstringRequiredDirect public HTTPS URL to the file
captionstringOptionalAttached caption, max 1,024 characters
account_idintegerOptionalAccount ID, required only if the key is linked to multiple accounts

Example

curl -X POST https://twasel.io/api/v1/send/media \
  -H "X-API-Key: wk_abc123..." \
  -H "X-API-Secret: ws_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "966501234567",
    "type": "image",
    "url": "https://example.com/product.jpg",
    "caption": "منتج جديد متوفر الآن!"
  }'

Supported Formats & Limits

TypeFormatsMax Size
imageJPEG, PNG5 MB
videoMP4, 3GPP16 MB
documentPDF, DOC, DOCX, XLS, XLSX, PPT, PPTX100 MB
audioAAC, MP3, MP4, AMR, OGG16 MB

Response

{
  "ok": true,
  "wa_message_id": "wamid.HBgLOTY2NTAxMjM0..."
}
{
  "ok": false,
  "error": "url_must_be_https"
}

POST /api/v1/trigger/flow

Starts a Flow Builder flow for a specific number when an event occurs in your system. The event must match the trigger configured in the flow.

Parameters

FieldTypeDescription
eventstringRequiredEvent name as configured in the flow trigger
tostringRequiredRecipient number in international format without +
varsobjectOptionalExtra variables passed to the flow
account_idintegerOptionalAccount ID, required only if the key is linked to multiple accounts

Example

curl -X POST https://twasel.io/api/v1/trigger/flow \
  -H "X-API-Key: wk_abc123..." \
  -H "X-API-Secret: ws_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{
    "event": "order.created",
    "to": "966501234567",
    "vars": { "order_id": "ORD-1234" }
  }'

Response

{
  "ok": true,
  "status": "flow_started"
}
{
  "ok": false,
  "status": "no_matching_flow"
}

GET /api/v1/templates

Query approved (APPROVED) templates available for your account or a specific account

Query Parameters

FieldTypeDescription
account_idintegerOptionalFilter by a specific account

Response

{
  "ok": true,
  "templates": [
    {
      "id": 1,
      "name": "order_confirmation",
      "category": "UTILITY",
      "language": "ar",
      "status": "APPROVED"
    },
    {
      "id": 2,
      "name": "welcome_message",
      "category": "MARKETING",
      "language": "ar",
      "status": "APPROVED"
    }
  ]
}

GET /api/v1/accounts

Query active WhatsApp accounts available to your key

Response

{
  "ok": true,
  "accounts": [
    {
      "id": 1,
      "display_name": "الرقم الرئيسي",
      "phone_number": "+966501234567",
      "is_active": true
    }
  ]
}

Error Reference

On error, the response includes "ok": false with an error field describing the cause

Authentication Errors

HTTPerrorReason
401missing_credentialsAuthentication headers not included in request
401invalid_keyKey not found or disabled
401key_expiredKey has expired
401invalid_secretSecret does not match

Usage Errors

HTTPerrorReason
429rate_limit_exceededDaily request limit exceeded
400to_and_body_requiredBoth to and body fields are required
400to_and_template_name_requiredBoth to and template_name fields are required
400to_type_url_requiredFields to, type, and url are required, or type is unsupported
400account_id_requiredKey is linked to multiple accounts, specify account_id
400url_must_be_httpsMedia URL must use HTTPS
422outside_customer_windowFree reply window expired, only templates can be sent
403permission_deniedKey does not have permission for this action
403invalid_accountAccount does not belong to your project
404unknown_endpointAPI endpoint not found
404account_not_foundAccount not found or disabled
405method_not_allowedHTTP method not allowed (e.g. sent GET instead of POST)
502(Meta)Error from Meta servers during message delivery

General Notes

TopicDetails
Free Reply Windowsend/text only works within 24 hours of the customer's last inbound message. After that, use send/template. Meta bills per delivered template message.
Phone FormatFull international number without + or spaces, e.g. 966501234567
EncodingUTF-8. Arabic is fully supported in messages and templates
HTTPS RequiredUnencrypted HTTP requests are rejected
PermissionsEach key has permissions defined by the admin. A missing permission returns 403
Twasel · API Reference, Version 1