wexora.Back
WEXORA / DEVELOPER DOCS

Connect with Wexora

Connect your store and tools to WhatsApp through Wexora.

Quick start

Create an API key and save it; it is shown only once. Send it in the Authorization header from your server only.

Authorization: Bearer YOUR_WEXORA_KEY
Content-Type: application/json

Rate limits: 60 requests per minute per key, and 180 per account.

Create a key in the dashboard after the website content review. New keys include all available public integration permissions. The key name is taken from the reviewed website; no manual name or permission selection is needed. Existing keys retain their original permissions. Sent messages and OTP codes use the authenticated key name as their source label; source headers are not required. Pausing a key blocks new requests until it is resumed. Deleting a key is permanent.

Send a message

Link your WhatsApp number in the Wexora dashboard and copy its Session ID.

POST /api/v1/messages

Use a connected device, the messages.send permission and an available message balance. Reuse the same Idempotency-Key when retrying to prevent duplicates; changing the payload with the same key returns 409.

curl -X POST 'https://wexora.pro/api/v1/messages' \
  -H 'Authorization: Bearer YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-123-confirmation' \
  -d '{"session_id":"SESSION_ID","to":"+201000000000","type":"text","body":"Hello {{name}}","variables":{"name":"Alex"}}'
HTTP 202
{"id":"MESSAGE_ID","status":"queued"}

For media, set type to image, video or document. Provide a public HTTPS link in url and an optional caption.

Send a message with buttons

Use POST /api/v1/messages with messages.send. Add 1–3 reply buttons, each with a unique id and a title of up to 20 characters. The message body supports up to 1,024 characters.

{
  "session_id": "SESSION_ID",
  "to": "+201000000000",
  "type": "interactive",
  "body": "Would you like to confirm your order?",
  "buttons": [
    {"id": "confirm_order_123", "title": "Confirm order"},
    {"id": "cancel_order_123", "title": "Cancel order"}
  ]
}

Use the same Authorization and Idempotency-Key headers as a text message. Subscribe to message.received in Webhooks; the selected button id arrives in data.body, with the customer number in data.sender. Your integration decides what happens next. IDs starting with wxb_, wxr_ or wxorder_ are reserved for Wexora.

OTP verification

Send a six-digit WhatsApp code with a Copy code button, then verify it from your server. Use a key with otp.send and otp.verify; existing keys do not gain these permissions automatically. OTP uses your connected Wexora device and message balance.

POST /api/v1/otp
Authorization: Bearer YOUR_KEY
Idempotency-Key: otp-order-123-attempt-1
Content-Type: application/json

{
  "session_id": "SESSION_ID",
  "to": "+201000000000",
  "purpose": "confirm_order",
  "reference": "order-123:customer-456",
  "language": "en"
}
HTTP 202
{"id":"OTP_ID","status":"pending","delivery_status":"queued","expires_at":"2026-10-17 12:05:00"}

English is the default language. Change "language": "en" to "language": "ar" for Arabic, including the copy button. Wexora generates the code and never returns it through the API. Default expiry: 5 minutes; optional expires_in: 60–600 seconds. Reuse the same Idempotency-Key for retries. To request a new code, wait 60 seconds and use a new key; it replaces the pending code for the same purpose and reference. Limit: 3 sends per recipient per 15 minutes.

POST /api/v1/otp/{id}/verify
Authorization: Bearer YOUR_KEY
Content-Type: application/json

{"code":"123456"}
HTTP 200
{"id":"OTP_ID","verified":true,"status":"verified","attempts_remaining":4}

Allow the operation only after this verification returns verified: true. Bind OTP_ID to your authenticated customer and intended operation on your server. Each code can be verified once, with up to 5 attempts. Copying a code does not verify it.

GET /api/v1/otp/{id}

Use otp.send to check delivery and expiry. Queued or sent does not mean delivered. This release supports Wexora linked devices; Meta Cloud API authentication templates require separate setup. Keep API keys on your server.

Endpoints & permissions

EndpointPermission
GET /api/v1/messagesmessages.read
POST /api/v1/messagesmessages.send
GET /api/v1/sessionssessions.read
POST /api/v1/otpotp.send
GET /api/v1/otp/{id}otp.send
POST /api/v1/otp/{id}/verifyotp.verify

Receive WhatsApp events

Add a Webhook destination to receive JSON events. Verify the signature using its secret, reject timestamps older than 5 minutes, and use event.id to prevent duplicate processing.

X-Wexora-Timestamp: UNIX_SECONDS
X-Wexora-Signature: sha256=HEX_HMAC

signature = HMAC_SHA256(timestamp + "." + raw_body, webhook_secret)

Events: message.sent, message.delivered, message.failed, message.received, session.connected, session.disconnected and campaign.completed. Delivery is retried up to 5 times. Use a public HTTPS URL without redirects.

Errors

Check Subscription & billing for your balance and plan limits. Use these response codes to troubleshoot requests.

401Invalid API key or authentication required
402Subscription expired or plan limit reached
403Insufficient permissions
404Resource not found or unavailable to your account
409State or idempotency key conflict
422Invalid request data
429Rate limit exceeded; check Retry-After
503Service temporarily unavailable

Use the Wexora agent in n8n

Use a Wexora API key with ai.invoke. Enable the agent and external automation for your session. Replies use your plan balance; no separate AI provider key is needed.

Add your Production URL in Webhooks and select message.received. Verify the event, then call:

POST /api/v1/ai/responses
Authorization: Bearer YOUR_WEXORA_KEY
Idempotency-Key: agent-EVENT_ID
Content-Type: application/json

{"session_id":"SESSION_ID","to":"+201000000000","message":"Customer question"}

Use session_id, data.sender and data.body from the event. For responded, send reply through POST /api/v1/messages with the same session and number and the key reply-EVENT_ID. For handoff, transfer to an employee; for failed, do not send. After a 202 response, check GET /api/v1/ai/responses/{id}.

Reuse the same Idempotency-Key when retrying to avoid duplicate usage.