Switchbord’s API is a JSON-over-HTTP surface that you deploy alongside your own infrastructure. The base URL is the domain where you run the API service — for example, https://api.your-switchbord.example.com. There is no central Switchbord-hosted API; you own and operate the endpoint. All requests and responses use Content-Type: application/json unless otherwise noted.
Authentication model
Switchbord uses different authentication mechanisms depending on the endpoint family:
- Webhook ingress — Meta sends an
X-Hub-Signature-256 header containing an HMAC-SHA256 signature of the raw request body, signed with your WEBHOOK_SIGNING_SECRET. Switchbord validates this signature before accepting any delivery. See Webhooks for the full signature model.
- Compatibility endpoints — These public-facing endpoints accept unauthenticated requests but are rate-limited to 100 requests per minute per IP address. The Emarsys endpoint additionally validates a shared secret passed as a query parameter.
- Internal operator endpoints — The
/internal/* routes are designed for the operator application and should be placed behind your authentication layer (Supabase session enforcement or a signed bearer token). In the current release, workspace scoping is enforced at the database layer.
The /internal/* endpoints are not yet treated as a stable external contract. Their shape may change between releases. Use them for operator tooling and debugging, not for production integrations.
Endpoint groups
Health and readiness
Two lightweight probes let your infrastructure verify that Switchbord’s API process is up and configured correctly.
| Method | Path | Description |
|---|
GET | /health | Returns build version, environment, and service identity. Use this for load balancer health checks. |
GET | /ready | Returns the full runtime status payload including provider configuration. Use this during deployment to confirm readiness. |
See Health and readiness for response shapes and examples.
Webhook ingress
These endpoints receive events from Meta’s WhatsApp Business Platform and normalize them for processing.
| Method | Path | Description |
|---|
GET | /webhooks/whatsapp | Meta webhook verification challenge. Register this URL in the Meta App Dashboard. |
POST | /webhooks/whatsapp | Receive inbound WhatsApp events. Validates X-Hub-Signature-256. |
GET | /webhooks/meta | Alias for the verification challenge (same behavior). |
POST | /webhooks/meta | Alternative ingress path (same behavior as /webhooks/whatsapp). |
See Webhooks for the full signature verification flow, event normalization, and testing examples.
Compatibility endpoints
These endpoints let existing Charles-era automations and partner systems send data to Switchbord without requiring upstream rewrites.
| Method | Path | Description |
|---|
POST | /compat/contact | Upsert a contact using the Charles-compatible contract. |
PUT | /api/v1beta/contact/ | Legacy path for contact mutation (same behavior, legacy response shape). |
POST | /compat/journey-trigger/{legacyPath} | Trigger a journey by legacy path identifier. |
POST | /webhooks/v0/rest-trigger/organization/{organizationId}/flow/{flowId}/trigger/ | Versioned legacy journey trigger. |
POST | /webhooks/v0/rest-trigger/organization/{organizationId}/flow/{flowId}/trigger/{triggerId}/ | Versioned legacy journey trigger with explicit trigger ID. |
POST | /api/v0/webhooks/incoming/emarsys/custom_external_event | Emarsys custom event ingress. Validates a shared secret query parameter when EMARSYS_WEBHOOK_SECRET is set. |
See Compatibility for request schemas and response shapes.
Operator reads
These /internal/* endpoints power the operator application. They require an authenticated session in production.
| Method | Path | Description |
|---|
GET | /internal/conversations | List conversations with inbox summary. Supports limit and offset. |
GET | /internal/conversations/{conversationId} | Get a single conversation with message history. |
GET | /internal/inbox/summary | Inbox summary counts only. |
GET | /internal/contacts | List contacts. Supports limit and offset. |
GET | /internal/templates | List synced WhatsApp message templates. |
GET | /internal/campaigns | List campaigns. |
GET | /internal/journeys | List journey definitions. |
GET | /internal/webhooks | List webhook deliveries with metadata. |
GET | /internal/webhooks/{webhookId} | Inspect a single webhook delivery: headers, body hash, normalization status. |
GET | /internal/webhook-events | List normalized webhook events. Supports limit. |
GET | /internal/webhook-rejections | List rejected or failed webhook deliveries for forensics. |
GET | /internal/audit-logs | List operator audit log entries. Supports limit. |
GET | /internal/runtime | Full runtime snapshot: queue depths, worker status, provider constraints, recent outbox jobs. |
Operator mutations
| Method | Path | Description |
|---|
POST | /internal/conversations/{conversationId}/messages | Send a message in a conversation. |
POST | /internal/webhooks/{webhookId}/replay | Replay a webhook delivery, creating a new processing attempt. |
POST | /internal/webhook-events/{webhookEventId}/replay | Replay a specific normalized webhook event. |
See Conversations, Contacts, and Webhook events for detailed documentation on each group.
Response conventions
All successful responses return JSON with a predictable top-level key matching the resource (conversations, contacts, webhooks, etc.). Mutation endpoints include a stable identifier for audit and retry tracing.
Validation failures return structured error objects:
{
"accepted": false,
"reason": "invalid_contact_update",
"issues": {
"fieldErrors": { "phone_number": ["Required"] },
"formErrors": []
}
}
Replay and operator mutation endpoints include identifiers that appear in audit logs so you can trace every action.
Current posture
The API surface is under active development. All endpoints described here follow stable route contracts, though response shapes for some internal endpoints may expand in future releases as data persistence is completed across all surfaces.