SmarticBot/Developers
Developer reference · v1

Build with the SmarticBot API

Send messages from a QR-connected WhatsApp phone, schedule campaigns, verify one-time codes, and talk to an assistant.

QR-connected phones · Public API v1

Quickstart

  1. Connect a phone by QR code in Channels and activate a plan.
  2. In Developer access, create a public phone API key. Copy it once and store it securely. Creating another key revokes the previous one; the provider connection is unaffected.
  3. Send a request with x-api-key. Use an assistant key only for /chat.
curl -X POST https://smarticbot.com/api/v1/send-message \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -H 'Idempotency-Key: order-2026-001' \
  -H 'Content-Type: application/json' \
  -d '{"number":"967771234567","message":"Hello from SmarticBot"}'

The example numbers are illustrative: Yemen uses +967 and Saudi Arabia uses +966. Replace them with your intended recipients before sending.

Accepted sends return HTTP 202 and an ID you can query at GET /messages/{id}. Acceptance does not guarantee delivery.

Before you integrate

QR WhatsApp setup guide · Official WhatsApp Business setup guide

Numbers use international digits (8–15 digits), optionally with a leading +. JSON endpoints require Content-Type: application/json; media uses multipart/form-data and accepts JPEG, PNG, WebP or MP4 up to 10 MiB.

Rate limits: 60 v1 requests per minute per API key (or IP without a key). OTP issue is additionally limited to five requests per number per 10 minutes and 30 per device per hour. Campaign messages consume quota when each recipient is sent.

Message states are pending, accepted, sent, delivered, read, failed or unknown. Providers may skip intermediate states; status never moves backward. An unknown outcome may still be delivered.

Supply Idempotency-Key on sends, OTP issue, campaigns, and chat. Repeating the same payload returns the original result for 24 hours. A changed payload or pending request returns 409. A timeout can mean the provider accepted the send: do not automatically retry with a new key.

OTP is a device-and-number-bound, single-use code valid for five minutes with at most five verification attempts. It does not log users into SmarticBot.

Customer webhooks

Available for paid phone plans. Enable a webhook URL in phone settings, then create a signing secret in Developer access. Each delivery includes X-Webhook-ID, X-Webhook-Timestamp, X-Webhook-Key-Version and X-Webhook-Signature. Verify the hex HMAC-SHA256 signature over timestamp + "." + the exact raw JSON body. Deduplicate by event ID. Retries preserve the body and signing version.

expected = 'sha256=' + HMAC_SHA256(secret, timestamp + '.' + raw_body)

Events include device_status_updated and message_status_updated. Provider callbacks are private; there is no public status-update endpoint.

Responses, limits & migration

Success has success=true and a data object. Errors have success=false with code, message, and details. Validation uses 422; bad keys 401; exhausted assistant credits 402; inactive plans 403; disconnected devices or idempotency conflicts 409; rate or quota limits 429; provider rejection 502; uncertain outcomes 503.

Legacy keys tied to provider identities are accepted for no more than 30 days after migration and can be revoked sooner. Create separate public keys now. The old public device/message status-update endpoints are removed. Campaign recipients are now a JSON array and scheduled_at must include a timezone offset. request_id is not used.

Operational health is available separately at /api/health; it is not a customer-authenticated v1 endpoint.

Messages

Send text

POST/api/v1/send-message

Request fields

FieldTypeRequired
numberstringYes
messagestring · max 4096Yes

Possible HTTP statuses

202401409422429502503

Response data fields

FieldTypeRequired
idstringYes
statusstringYes
provider_message_idstring | nullYes

Request

curl -X POST https://smarticbot.com/api/v1/send-message \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "number": "967771234567",
    "message": "Hello from SmarticBot"
}'

Success response

{
    "success": true,
    "data": {
        "id": "01J...",
        "status": "accepted",
        "provider_message_id": "ABCD"
    }
}

Send image or video

POST/api/v1/send-media

Request fields

FieldTypeRequired
numberstringYes
mediastringYes
captionstring · max 3500No

Possible HTTP statuses

202401409422429502503

Response data fields

FieldTypeRequired
idstringYes
statusstringYes
provider_message_idstring | nullYes

Request

curl -X POST https://smarticbot.com/api/v1/send-media \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -F 'number=967771234567' \
  -F '[email protected]'

Success response

{
    "success": true,
    "data": {
        "id": "01J...",
        "status": "accepted",
        "provider_message_id": "ABCD"
    }
}

Send poll

POST/api/v1/send-poll-message

Request fields

FieldTypeRequired
numberstringYes
poll_questionstring · max 255Yes
poll_optionsarrayYes
allow_multiple_answersbooleanNo

Possible HTTP statuses

202401409422429502503

Response data fields

FieldTypeRequired
idstringYes
statusstringYes
provider_message_idstring | nullYes

Request

curl -X POST https://smarticbot.com/api/v1/send-poll-message \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "number": "967771234567",
    "poll_question": "Which day?",
    "poll_options": [
        "Monday",
        "Tuesday"
    ],
    "allow_multiple_answers": false
}'

Success response

{
    "success": true,
    "data": {
        "id": "01J...",
        "status": "accepted",
        "provider_message_id": "ABCD"
    }
}

Get message delivery status

GET/api/v1/messages/{id}

Possible HTTP statuses

200401404

Response data fields

FieldTypeRequired
idstringYes
typestringYes
statusstringYes
provider_message_idstring | nullYes
sent_atstring | nullYes
delivered_atstring | nullYes
read_atstring | nullYes

Request

curl -X GET https://smarticbot.com/api/v1/messages/{id} \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY'

Success response

{
    "success": true,
    "data": {
        "id": "01J...",
        "type": "text",
        "status": "delivered",
        "provider_message_id": "ABCD",
        "sent_at": "2026-10-14T10:00:00Z",
        "delivered_at": "2026-10-14T10:00:03Z",
        "read_at": null
    }
}

Verification codes

Issue a six-digit verification code

POST/api/v1/send-otp

Possible HTTP statuses

202401409422429502503

Response data fields

FieldTypeRequired
expires_in_secondsintegerYes

Request

curl -X POST https://smarticbot.com/api/v1/send-otp \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "number": "967771234567"
}'

Success response

{
    "success": true,
    "data": {
        "expires_in_seconds": 300
    }
}

Verify and consume a code

POST/api/v1/verify-otp

Request fields

FieldTypeRequired
numberstringYes
codestringYes

Possible HTTP statuses

200401422

Response data fields

FieldTypeRequired
verifiedbooleanYes

Request

curl -X POST https://smarticbot.com/api/v1/verify-otp \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "number": "967771234567",
    "code": "123456"
}'

Success response

{
    "success": true,
    "data": {
        "verified": true
    }
}

Campaigns

Schedule a campaign

POST/api/v1/create-campaign
The example scheduled_at is generated seven days from page load. Replace it with your desired future time and timezone offset.

Request fields

FieldTypeRequired
campaign_namestring · max 255Yes
campaign_descstring · max 255No
messagestring · max 4096Yes
recipientsarrayYes
scheduled_atstringYes

Possible HTTP statuses

201401409422429

Response data fields

FieldTypeRequired
idintegerYes
statusstringYes
scheduled_atstringYes
recipient_countintegerYes

Request

curl -X POST https://smarticbot.com/api/v1/create-campaign \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "campaign_name": "Scheduled update",
    "message": "Hello!",
    "recipients": [
        "967771234567",
        "966501234567"
    ],
    "scheduled_at": "2026-10-26T05:39:33+00:00"
}'

Success response

{
    "success": true,
    "data": {
        "id": 123,
        "status": "scheduled",
        "scheduled_at": "2026-10-26T05:39:33+00:00",
        "recipient_count": 2
    }
}

Get campaign progress

GET/api/v1/campaigns/{id}

Possible HTTP statuses

200401404

Response data fields

FieldTypeRequired
idintegerYes
statusstringYes
scheduled_atstring | nullYes
sent_countintegerYes
failed_countintegerYes
delivered_countintegerYes
read_countintegerYes

Request

curl -X GET https://smarticbot.com/api/v1/campaigns/{id} \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY'

Success response

{
    "success": true,
    "data": {
        "id": 123,
        "status": "running",
        "sent_count": 20,
        "failed_count": 0,
        "delivered_count": 17,
        "read_count": 9
    }
}

Devices

Get QR-connected device information

GET/api/v1/device/info

Possible HTTP statuses

200401

Response data fields

FieldTypeRequired
idintegerYes
namestringYes
phone_numberstringYes
statusstringYes
is_activebooleanYes
last_seen_atstring | nullYes

Request

curl -X GET https://smarticbot.com/api/v1/device/info \
  -H 'x-api-key: YOUR_PUBLIC_PHONE_KEY'

Success response

{
    "success": true,
    "data": {
        "id": 1,
        "name": "Sales",
        "phone_number": "967771234567",
        "status": "connected",
        "is_active": true,
        "last_seen_at": "2026-10-14T10:00:00Z"
    }
}

Assistant

Send a turn to an assistant using an assistant key

POST/api/v1/chat
Each assistant has its own API key. The key in x-api-key selects that assistant. Reuse session_id for follow-up turns: the last 10 successful turns from this assistant and session in the previous 30 days are sent as context. Use a new value for a new conversation; send turns for one session sequentially. Prior context consumes input tokens and may increase credits used. A phone key cannot call this endpoint.

Request fields

FieldTypeRequired
session_idstring · max 128Yes
messagestring · max 4096Yes

Possible HTTP statuses

200401402403409422503

Response data fields

FieldTypeRequired
replystringYes
tokensintegerYes
credits_usedintegerYes

Request

curl -X POST https://smarticbot.com/api/v1/chat \
  -H 'x-api-key: YOUR_PUBLIC_ASSISTANT_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "session_id": "customer-42",
    "message": "What are your opening hours?"
}'

Success response

{
    "success": true,
    "data": {
        "reply": "We are open 9–5.",
        "tokens": 120,
        "credits_used": 2
    }
}