Developer documentation

Build focused WhatsApp workflows with Whatsly

Pair a business number, create scoped API credentials, send supported messages and receive signed events without giving an integration unrestricted workspace access.

Implementation reference

  • Device-scoped credentials
  • Signed webhook events
  • Idempotent message requests
  • Workspace-controlled access
01

Quickstart

Whatsly uses workspace-controlled devices and scoped API keys. A connected WhatsApp number must be available before an external system can send a message.

  1. 1

    Connect a number

    Pair the company WhatsApp number from the Whatsly workspace and confirm that its connection status is healthy.

  2. 2

    Create a dedicated API key

    Create credentials for the specific device and workflow. Copy the secret when it is shown and store it in a secret manager.

  3. 3

    Copy the API base URL

    Use the API base URL displayed in your Whatsly workspace or integration settings. Do not assume that an example or old hostname is valid for your account.

  4. 4

    Send a test message

    Use an opted-in test recipient, a supported message type and a unique idempotency key.

  5. 5

    Add a webhook

    Subscribe to the message and device events your system needs, then verify every signature before processing the payload.

Use test contacts that you are authorized to message. API access does not remove your responsibility for consent, opt-outs or WhatsApp policy compliance.

02

Authentication and scopes

Public API requests use a key identifier and a secret. Credentials should belong to one approved integration and include only the permissions that workflow needs.

X-Api-Key-ID
The public identifier for the device-scoped credential.
X-Api-Key-Secret
The secret copied when the credential is created. Keep it outside source control and browser code.
messages:send
Allows the integration to send supported outbound messages through the selected device.
messages:read
Allows supported conversation or message reads where enabled for the plan and credential.
device:status
Allows the integration to inspect the selected device connection state.

Rotate a credential if it may have been exposed. Revoke credentials when the integration is removed or no longer needs access.

03

Send a message

Use the message endpoint for supported outbound types. Whatsly checks device ownership, subscription access, quotas, rate limits and abuse controls before accepting the send.

  • text — a plain text body.
  • media — a supported file delivered from an accessible HTTPS URL, with an optional caption.
  • template — a saved Whatsly template populated with approved variables.
  • location — latitude, longitude and an optional place name.
Example text request
curl -X POST "$WHATSLY_API_BASE_URL/api/v1/messages/send" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key-ID: <your-api-key-id>" \
  -H "X-Api-Key-Secret: <your-api-key-secret>" \
  -d '{
    "device_id": 1,
    "to": "+966500000000",
    "message_type": "text",
    "text": {
      "body": "Hello from Whatsly"
    },
    "idempotency_key": "order-1001"
  }'

Set WHATSLY_API_BASE_URL to the value shown in your workspace. Phone numbers should use the international format expected by your configured workflow.

04

Templates and variables

Templates are created inside the Whatsly workspace and can be used for repeated operational messages. Variables personalize the message without rebuilding the body for every request.

  • Named variables include {name}, {phone_number}, {my_name}, {my_email} and {my_contact_number}.
  • Numbered API variables can use practical placeholders from {1} through {20}.
  • The integration remains responsible for supplying accurate values and reviewing the final message workflow.
Example template payload
{
  "device_id": 1,
  "to": "+966500000000",
  "message_type": "template",
  "template_id": 12,
  "variables": {
    "name": "Ahmed",
    "1": "Order #1001",
    "2": "SAR 250"
  },
  "idempotency_key": "order-1001"
}
05

Receive signed webhook events

Webhooks can notify an approved system about inbound messages, outbound outcomes and device state. Configure only the event types the receiving system needs.

message.received
A supported inbound message was received by the connected number.
message.sent
An outbound message reached the corresponding sent state.
message.failed
An outbound attempt failed and should be reviewed.
device.connected
The selected WhatsApp device is connected.
device.disconnected
The device connection is no longer available.
device.connection.failed / device.revoked
The connection failed or access was revoked and may require operator action.
Example event envelope
{
  "event_id": "evt_01H...",
  "event_type": "message.received",
  "occurred_at": "2026-06-03T10:00:00Z",
  "tenant_id": 1,
  "device_id": 1,
  "data": {
    "message": {
      "id": 101,
      "direction": "inbound",
      "from_phone": "+966500000000",
      "message_type": "text",
      "body": "Hi, is my order ready?"
    }
  }
}

Verify X-Whatsly-Signature with HMAC SHA-256 over the documented timestamp and raw request body. Reject invalid signatures before reading or storing event data.

06

Commerce integrations

Shopify and WooCommerce integrations turn selected store events into operational WhatsApp messages while leaving the commerce platform as the system of record.

WooCommerce
The available plugin supports selected order, payment, status, COD, cancellation and refund workflows.
Shopify
The hosted Shopify connector is in Early Access and supports selected order, payment, fulfillment and checkout workflows.

Use the dedicated integration guides for setup requirements, supported workflows and security guidance.

07

Handle errors predictably

Store the returned message identifier, keep idempotency keys stable for retries and treat rate or quota responses as a signal to slow down or review the integration.

401 / 403
Check the key identifier, secret, scopes, device ownership, plan access and workspace permissions.
422
Check the recipient number, required fields, body length, media URL, template variables and current device state.
429
Slow the request rate and review device or workspace usage controls before retrying.

Do not retry every failure indefinitely. Use bounded retries, retain enough context for diagnosis and alert an operator when the connected number needs attention.