Authentication
Send Authorization: Bearer <key>. Organization keys are tenant-scoped; application keys are accepted only by provisioning operations.
Customer API · v1
Send messages, manage templates and media, receive signed events, and build customer workflows on one tenant-isolated API.
https://castapi.dev/api/v101
Use an organization key from the portal. Keep it on your server and never place it in browser code or logs.
POST /api/v1/messagesexport CASTAPI_BASE_URL="https://castapi.dev"
curl --request POST \
--url "$CASTAPI_BASE_URL/api/v1/messages" \
--header "Authorization: Bearer $CASTAPI_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: order-842-reminder-1" \
--data '{
"from": "default",
"to": "+972501234567",
"type": "template",
"template": {
"name": "appointment_reminder",
"language": "he"
},
"metadata": { "order_id": "842" }
}'The API stores the message before queueing delivery. Track final delivery through signed webhooks or GET /api/v1/messages/{id}.
02
These rules apply across the customer API.
Send Authorization: Bearer <key>. Organization keys are tenant-scoped; application keys are accepted only by provisioning operations.
Message, campaign, conversation-reply, and top-up writes require an Idempotency-Key of at most 255 characters. Replays return the original result.
Cursor endpoints return data and next_cursor. Pass that opaque value as cursor; do not parse or construct it.
Limits apply per credential. A 429 response includes Retry-After; wait that many seconds before retrying with backoff.
All expected API failures use the same shape. Validation errors may add a safe details field.
{
"error": {
"code": "validation_error",
"message": "Invalid request",
"details": [
{ "path": "to", "message": "E.164 number required" }
]
}
}03
The send endpoint supports text, templates, images, documents, audio, video, interactive content, reactions, and locations.
Recipient numbers must use E.164 with a leading +. Set from to default when the organization has one active sender, or pass its Meta phone-number id.
Upload a file or import an HTTPS URL with POST /api/v1/media, then reference the returned UUID as media_id. Downloads redirect to short-lived signed URLs.
List, create, inspect, and delete WhatsApp templates through the gateway. Meta remains the authority for approval status and template validation.
04
Subscribe to message, template, and billing events. The endpoint secret is shown once when the endpoint is created or rotated.
Each delivery includes X-CastAPI-Signature, X-CastAPI-Timestamp, X-CastAPI-Event-Id, and X-CastAPI-Event-Type.
Do not parse JSON first.
Reject stale requests.
Compare in constant time.
Store before processing.
HMAC-SHA256signed_payload = X-CastAPI-Timestamp + "." + raw_request_body
expected = hex(hmac_sha256(webhook_secret, signed_payload))
received = X-CastAPI-Signature.remove_prefix("v1=")
constant_time_compare(expected, received)A 2xx response confirms receipt. Other responses and network errors are retried with exponential backoff, up to eight attempts over roughly four hours.
Use X-CastAPI-Event-Id as a unique key. Duplicate delivery is normal, so acknowledge events you have already processed.
message.received, message.status, template.status, and billing.low_balance.
05
All 75 customer operations are listed below. Request and response schemas are available in the machine-readable OpenAPI contract.
/keys and /api-keys/api/v1/keys is the canonical paginated list and revoke surface. Create keys with POST /api/v1/api-keys. The older list and revoke operations under /api-keys remain available for compatibility and are marked deprecated in OpenAPI; no existing client is being broken.
GET /api/v1/billing/balance returns checkout_enabled. When it is false, top-ups, payment-customer creation, and enabling automatic top-up return 503 billing_checkout_unavailable; messaging and billing reads remain available.
/api/v1/messagesQueue a message/api/v1/messagesList messages/api/v1/messages/{id}Get a message/api/v1/events/{id}/redeliverRedeliver a stored event/api/v1/mediaUpload or import media/api/v1/mediaList media/api/v1/media/{id}Download media/api/v1/templatesList message templates/api/v1/templatesCreate a message template/api/v1/templates/{name}Get a message template/api/v1/templates/{name}Delete a message template/api/v1/webhooksCreate a webhook endpoint/api/v1/webhooksList webhook endpoints/api/v1/webhooks/{id}Get a webhook endpoint/api/v1/webhooks/{id}Update a webhook endpoint/api/v1/webhooks/{id}Delete a webhook endpoint/api/v1/webhooks/{id}/testSend a test event/api/v1/webhooks/{id}/deliveriesList endpoint deliveries/api/v1/webhooks/{id}/statsGet endpoint delivery statistics/api/v1/channelsList WhatsApp channels/api/v1/channels/{waba_id}/phonesList channel phone numbers/api/v1/channels/{waba_id}/syncSync a channel from Meta/api/v1/embedded-signup/configGet Embedded Signup public configuration/api/v1/embedded-signup/exchangeComplete Embedded Signup for the current organization/api/v1/contactsList contacts/api/v1/contactsCreate a contact/api/v1/contacts/{id}Get a contact/api/v1/contacts/{id}Update a contact/api/v1/contacts/{id}Delete a contact/api/v1/contacts/importImport contacts from CSV or XLSX/api/v1/suppressionList suppressed recipients/api/v1/suppressionSuppress a recipient/api/v1/suppression/{id}Remove a suppression/api/v1/audiencesList audiences/api/v1/audiencesCreate an audience/api/v1/audiences/{id}Get an audience/api/v1/audiences/{id}Delete an audience/api/v1/campaignsList campaigns/api/v1/campaignsCreate a campaign draft/api/v1/campaigns/{id}Get a campaign/api/v1/campaigns/{id}/scheduleSchedule a campaign/api/v1/campaigns/{id}/cancelCancel a campaign/api/v1/campaigns/{id}/exportExport campaign recipients/api/v1/conversationsList conversations/api/v1/conversations/{id}Get a conversation and its messages/api/v1/conversations/{id}/messagesReply in a conversation/api/v1/overviewGet the workspace overview/api/v1/analyticsGet messaging analytics/api/v1/billing/balanceGet the prepaid balance/api/v1/billing/usageList usage ledger entries/api/v1/billing/profileGet the billing profile/api/v1/billing/profileReplace the billing profile/api/v1/billing/auto-topupConfigure automatic top-ups/api/v1/billing/payment-methodStart payment-method configuration/api/v1/billing/topupsCreate a balance top-up/api/v1/billing/topups/{id}Get a top-up/api/v1/billing/documentsList billing documents/api/v1/billing/documents/{id}/pdfDownload a billing document PDF/api/v1/membersList organization members/api/v1/membersInvite an organization member/api/v1/members/{id}Update a member/api/v1/members/{id}Remove a member/api/v1/invitationsList pending invitations/api/v1/invitationsCreate an invitation/api/v1/invitations/{id}Revoke an invitation/api/v1/api-keysList API keys (compatibility shape)compatibility/api/v1/api-keysCreate an organization API key/api/v1/api-keys/{id}Revoke an API key (compatibility shape)compatibility/api/v1/keysList organization API keys/api/v1/keys/{id}Revoke an organization API key/api/v1/orgsCreate an organization/api/v1/orgs/{id}/keysCreate a key for an organization/api/v1/orgs/{id}/webhooksList an organization’s webhooks/api/v1/orgs/{id}/webhooksCreate an organization webhook/api/v1/orgs/{id}/embedded-signup/exchangeComplete Embedded Signup for an organization06
Partner applications can create isolated customer organizations, mint their first organization key, register webhooks, and complete Embedded Signup.
Application-scoped credentials work only on /api/v1/orgs provisioning routes. They do not grant access to an organization’s messages or contacts.
Send the short-lived code, WABA id, and phone-number id to the exchange operation. Never expose Meta access tokens to customer browsers.
The full key is returned once. Store it in a server-side secret manager and use it for the tenant’s normal messaging operations.