Skip to main content
Switchbord records every webhook delivery it receives, regardless of signature validity or parsing outcome. The webhook events API gives the operator application full visibility into that history: you can filter deliveries by type or status, inspect raw headers and body hashes, replay failed or rejected deliveries, and review the operator audit trail. These are internal endpoints intended for operator tooling and incident response.
All /internal/* endpoints are intended for the operator application and should be placed behind an authenticated session in production. Workspace scoping is enforced at the data layer.

GET /internal/webhooks

List webhook delivery records. Each record captures the raw envelope: headers, body hash, delivery ID, signature validity, and normalization status.
curl "https://api.your-switchbord.example.com/internal/webhooks"
Response:
webhooks
array
Array of webhook delivery records.
{
  "webhooks": [
    {
      "id": "evt_01hx...",
      "source": "whatsapp",
      "topic": "messages",
      "deliveryId": "wamid.ABC123",
      "signatureValid": true,
      "bodyHash": "a3f9b2c1...",
      "receivedAt": "2025-01-15T10:28:00.000Z"
    }
  ]
}
StatusCondition
200Webhook deliveries listed

GET /internal/webhooks/

Inspect a single webhook delivery in full detail: request headers, body hash, normalization status, and replay metadata.
curl https://api.your-switchbord.example.com/internal/webhooks/evt_01hx...
webhookId
string
required
The webhook delivery identifier from the list endpoint.
Response:
webhook
object
The full webhook delivery record.
StatusCondition
200Webhook found
404{"error": "webhook_not_found"}

POST /internal/webhooks//replay

Replay a webhook delivery. Switchbord creates a new processing attempt from the original raw body without mutating the original record. The replay is workspace-scoped and logged to the audit trail.
# Replay a failed webhook delivery
curl -X POST https://api.your-switchbord.example.com/internal/webhooks/evt_01hx.../replay \
  -H "Content-Type: application/json"
webhookId
string
required
The webhook delivery identifier to replay.
Response:
accepted
boolean
true when the replay job was successfully created.
replayedFromId
string
The ID of the original webhook delivery that was replayed.
webhookEvent
object
The new webhook event record created for this replay attempt.
outboxJob
object
The outbox job queued for processing the replayed delivery.
{
  "accepted": true,
  "replayedFromId": "evt_01hx...",
  "webhookEvent": {
    "id": "evt_01hy...",
    "source": "whatsapp",
    "topic": "messages",
    "receivedAt": "2025-01-15T10:35:00.000Z"
  },
  "outboxJob": {
    "id": "job_01hy...",
    "jobType": "process_webhook_event",
    "status": "pending"
  }
}
StatusCondition
200Replay accepted
404{"error": "webhook_not_found"}
Replay creates a new attempt record rather than mutating the original delivery. Deduplication keys are explicit, so replaying a delivery that was previously processed successfully will create a new outbox job with a distinct key.

GET /internal/webhook-events

List normalized webhook event records. These are the processed events derived from raw webhook deliveries — filtered and paginated for inspection.
curl "https://api.your-switchbord.example.com/internal/webhook-events?limit=25"
limit
integer
Maximum number of events to return. Defaults to 25, minimum 1, capped at 100.
Response:
webhookDeliveries
array
Array of normalized webhook delivery records.
{
  "webhookDeliveries": [
    {
      "id": "del_01hx...",
      "webhookEventId": "evt_01hx...",
      "topic": "messages",
      "status": "processed",
      "processedAt": "2025-01-15T10:28:05.000Z"
    }
  ]
}
StatusCondition
200Events listed

POST /internal/webhook-events//replay

Replay a specific normalized webhook event. Similar to the webhook replay endpoint but operates on the normalized event record rather than the raw delivery.
curl -X POST https://api.your-switchbord.example.com/internal/webhook-events/del_01hx.../replay \
  -H "Content-Type: application/json"
webhookEventId
string
required
The webhook event identifier to replay.
Response:
accepted
boolean
true when the replay was accepted.
delivery
object
The new delivery record created for the replay attempt.
job
object
The outbox job queued for processing.
{
  "accepted": true,
  "delivery": {
    "id": "del_01hy...",
    "status": "pending"
  },
  "job": {
    "id": "job_01hy...",
    "status": "pending"
  }
}
StatusCondition
202Replay accepted
404{"error": "webhook_delivery_not_found"}

GET /internal/webhook-rejections

List rejected or failed webhook deliveries. Use this endpoint for forensics when you need to understand why a delivery was not processed — for example, invalid signatures, parse failures, or payloads that did not match the expected envelope shape.
curl https://api.your-switchbord.example.com/internal/webhook-rejections
Response:
webhookRejections
array
Array of rejection records, each with the reason and original delivery details.
{
  "webhookRejections": [
    {
      "id": "rej_01hx...",
      "source": "whatsapp",
      "topic": "invalid_signature",
      "signatureValid": false,
      "receivedAt": "2025-01-15T09:00:00.000Z"
    }
  ]
}
StatusCondition
200Rejections listed

GET /internal/audit-logs

List operator audit log entries. Audit logs record actions taken through the operator application — including replays, message sends, and configuration changes.
curl "https://api.your-switchbord.example.com/internal/audit-logs?limit=25"
limit
integer
Maximum number of entries to return. Defaults to 25, minimum 1, capped at 100.
Response:
auditLogEntries
array
Array of audit log entries, most recent first.
{
  "auditLogEntries": [
    {
      "id": "aud_01hx...",
      "action": "webhook.replay",
      "targetId": "evt_01hx...",
      "actorId": "operator_session_xyz",
      "createdAt": "2025-01-15T10:35:00.000Z"
    }
  ]
}
StatusCondition
200Audit log entries listed

GET /internal/runtime

Returns a full runtime snapshot: queue depths, recent outbox jobs, active campaigns, journey definitions, recent webhook events, and provider constraints. Use this for dashboards and incident triage.
curl https://api.your-switchbord.example.com/internal/runtime
Response:
runtime
object
Runtime status from the backing store, including build version, environment, and queue state.
campaigns
array
All campaign records.
journeys
array
All journey definition records.
webhooks
array
The 10 most recent webhook delivery records.
outboxJobs
array
The 10 most recent outbox job records.
providerConstraints
object
Static WhatsApp Business Platform constraints applied by Switchbord.
{
  "runtime": {
    "buildVersion": "0.0.1",
    "environment": "production",
    "queueDepth": 3
  },
  "campaigns": [...],
  "journeys": [...],
  "webhooks": [...],
  "outboxJobs": [...],
  "providerConstraints": {
    "apiVersion": "v23.0",
    "serviceWindowHours": 24,
    "pairRateLimitSeconds": 6,
    "defaultThroughputMessagesPerSecond": 80,
    "eligibleUpgradeThroughputMessagesPerSecond": 1000
  }
}
StatusCondition
200Runtime snapshot returned