Skip to main content
Version: Latest

Sending Sandbox Messages

To use a WhatsApp, Instagram, or Messenger sandbox, first create an account, verify the email, create an Application, and generate its API key as described in Authentication.

WhatsApp, Instagram, and Messenger sandboxes use their provider's regular send endpoint; no separate sandbox-message endpoint is required. Set from to the sandbox keyword or its Application Channel ID. Sandbox accepts only the content types listed below, not every live-channel content object.

Before sending, reach the test-message step in Hub and connect at least one 24-hour session by sending the displayed keyword to the shared sandbox account. Completing setup makes the Sandbox channel available in the application, but is not required for tests on step 3. The API key must belong to the application that owns the sandbox.

{
"from": "SANDBOX_KEYWORD_OR_APPLICATION_CHANNEL_ID",
"to": "SESSION_EXTERNAL_IDENTIFIER",
"content": {
"text": "Hello from the sandbox!"
}
}

Use the endpoint for the configured provider:

ProviderEndpoint
WhatsAppPOST /v1/communication/whatsapp/message
InstagramPOST /v1/communication/instagram/message
MessengerPOST /v1/communication/messenger/message

from accepts only the sandbox keyword shown in Hub or that sandbox's Application Channel ID. It does not accept the shared WhatsApp number, Instagram username, or Messenger page name. to is the external identifier returned for a connected sandbox session.

Supported Sandbox content​

Choose one primary content type per request. For media, companions text, mimeType, filename, and voice are permitted; text is a caption, not a second primary type. Use filename (camelCase fileName is not a public field). Caption/voice presentation follows the selected provider: Instagram/Messenger media discards caption text, and WhatsApp supports voice notes.

ProviderSupported content keys
WhatsApptext, fake Sandbox template, imageUrl, videoUrl, audioUrl, documentUrl
Instagramtext, imageUrl, videoUrl, audioUrl
Messengertext, imageUrl, videoUrl, audioUrl

Sandbox does not support live-channel-only features such as typing, reactions, interactive messages, or Messenger templates. Unsupported content returns UNSUPPORTED_MESSAGE_TYPE.

For example, send audio through the WhatsApp sandbox endpoint:

{
"from": "SANDBOX_KEYWORD_OR_APPLICATION_CHANNEL_ID",
"to": "SESSION_EXTERNAL_IDENTIFIER",
"content": {
"audioUrl": "https://example.com/voice.ogg",
"mimeType": "audio/ogg",
"filename": "voice.ogg",
"voice": true
}
}

All successful sandbox sends return status: "enqueued" and the persisted Hub messageId; that status is not a delivery receipt. A failed submission can return a non-2xx HTTP sandbox error instead.

Authentication and webhook configuration​

The Hub screen sends with the signed-in organization; the public API uses the owning application's x-api-key. In both cases the sandbox session must be connected and unexpired. An API key cannot send through a sandbox from another application.

Configure and read subscriptions from the moment a Sandbox is created, including while it is pending, with the standard channel endpoints:

POST /v1/communication/channel/{applicationChannelId}/webhook/{webhookId}/configure
GET /v1/communication/channel/{applicationChannelId}/webhook/{webhookId}/config

Use the Sandbox Application Channel ID as {applicationChannelId}. Send {"events": []} to unsubscribe. The response identifies the target as applicationChannelId.

API key examples​

curl -X POST https://app.chatt2.me/v1/communication/messenger/message \
-H 'x-api-key: YOUR_APPLICATION_API_KEY' \
-H 'content-type: application/json' \
--data '{"from":"YOUR_SANDBOX_KEYWORD","to":"SESSION_EXTERNAL_IDENTIFIER","content":{"text":"Hello from the sandbox!"}}'
curl -X POST 'https://app.chatt2.me/v1/communication/channel/YOUR_SANDBOX_APPLICATION_CHANNEL_ID/webhook/YOUR_WEBHOOK_ID/configure' \
-H 'x-api-key: YOUR_APPLICATION_API_KEY' \
-H 'content-type: application/json' \
--data '{"events":["messages"],"enabled":true}'

WhatsApp template example​

List the Sandbox catalog with GET /v1/communication/channel/whatsapp/templates/{applicationChannelId}. It is localized and read-only, returns phoneNumber: null, and marks examples with sandboxFamily. Templates use the regular WhatsApp template body. The following image template supplies both the body variable and image URL:

{
"from": "SANDBOX_KEYWORD_OR_APPLICATION_CHANNEL_ID",
"to": "SESSION_EXTERNAL_IDENTIFIER",
"content": {
"template": {
"id": "10000000-0000-4000-8000-000000000003",
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"image": { "link": "https://example.com/image.jpg" }
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"variable": "1",
"text": "Dani"
}
]
}
]
}
}
}

Incoming webhook identity​

Sandbox message events include message.is_sandbox: true. The recipient uses the owning keyword as recipient.id and includes the sandbox Application Channel ID:

{
"eventType": "message",
"payload": {
"provider": "whatsapp",
"direction": "IN",
"message": {
"id": "a16c0971-1887-4612-a0b2-d9489d6ca04f",
"type": "Text",
"content": { "text": "Hello" },
"is_sandbox": true
},
"sender": {
"id": "5511993986082",
"username": "5511993986082"
},
"recipient": {
"id": "YOUR_SANDBOX_KEYWORD",
"applicationChannelId": "e690cc45-4abe-4f83-8373-01e7026797ad"
}
}
}

Quota and session recovery​

The message quota is shared by organization and provider, across that provider's sandbox ownership in the organization. Each provider starts with a default allowance of 100 messages; the configured allowance shown in Hub can differ. Check the Sandbox screen for used and remaining messages. Both accepted inbound and outbound messages count. Connecting with the keyword is consumed as a connection action and does not become a normal message webhook.

When exhausted, inbound messages are not persisted or forwarded to your webhook. Outbound sends fail with SANDBOX_MESSAGE_LIMIT_REACHED. If outbound provider submission fails after reserving a quota slot, the reservation is released. Reconnecting does not replenish the allowance. Disconnecting or deleting the owning application clears sessions, webhook configuration, and the keyword, but does not reset usage.

A connected sandbox session lasts 24 hours from keyword connection. Send the displayed keyword again to renew/reconnect an expired session. Each external sender has only one active association per provider: connecting that sender to another sandbox of the same provider expires the previous association. Use the current keyword in the desired Sandbox screen and then its returned external identifier for to.

For SANDBOX_SESSION_NOT_FOUND, SANDBOX_SESSION_NOT_CONNECTED, or SANDBOX_SESSION_EXPIRED, reconnect the sender before retrying. Recheck from, the owning application's API key, the selected provider, and remaining quota if the send still fails. Sandbox testing does not bypass a provider rejection or promise live-channel policy eligibility.