Webhooks Reference
Endpoints for managing webhook endpoints and the Event Webhook settings. For the guide, see Webhooks.
Base paths:
/v3/user/webhooks— endpoint CRUD (multiple URLs, per-URL event set)/v3/user/webhooks/event/settings— single-URL model with per-type booleans
Required permission: webhooks.read for reads, webhooks.write for writes.
GET /v3/user/webhooks#
List webhook endpoints.
Query parameters:
| Parameter | Notes |
|---|---|
page |
1-indexed (default 1) |
page_size |
1–100 (default 20) |
is_active |
Filter by enabled state |
Response (200):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
POST /v3/user/webhooks#
Create a webhook endpoint.
Request body:
| Field | Type | Required | Notes |
|---|---|---|---|
url |
string | Yes | HTTPS URL; HTTP is accepted for local development but refused in production |
enabled_events |
array | Yes | Event types to subscribe to, or ["*"] for all |
oauth_client_id |
string | No | If set, ScaiSend does OAuth2 before delivering |
oauth_client_secret |
string | No | Paired with oauth_client_id |
Response (201):
1 2 3 4 5 6 7 8 | |
The signing_secret is returned exactly once. Save it.
GET /v3/user/webhooks/{webhook_id}#
Get a single endpoint.
Response (200): endpoint object (without signing_secret).
PATCH /v3/user/webhooks/{webhook_id}#
Update an endpoint.
Request body: any subset of:
| Field | Notes |
|---|---|
url |
New URL |
enabled_events |
New event set |
enabled |
Pause/resume delivery |
Response (200): updated endpoint.
DELETE /v3/user/webhooks/{webhook_id}#
Delete an endpoint. Past delivery records are also removed.
Response (204): no body.
POST /v3/user/webhooks/{webhook_id}/signing_secret#
Rotate the signing secret.
Response (200):
1 | |
The old secret stops validating immediately. Update your verifier before rotating, or accept both briefly during rollout.
GET /v3/user/webhooks/event/settings#
Get the Event Webhook settings (single-URL model).
Response (200):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
PATCH /v3/user/webhooks/event/settings#
Update Event Webhook settings. Partial update — unspecified fields retain their value.
Request body: any subset of the response fields above.
Response (200): updated settings.
Webhook request format#
Every outbound request from ScaiSend carries:
| Header | Value |
|---|---|
Content-Type |
application/json |
User-Agent |
ScaiSend-Webhook/1.0 |
X-ScaiSend-Event |
Event type |
X-ScaiSend-Timestamp |
Unix timestamp |
X-ScaiSend-Signature |
HMAC-SHA256 of {timestamp}.{body} |
Payload:
1 2 3 4 5 6 7 8 9 10 11 | |
See Events and Webhooks for the per-event metadata fields.
Signature verification#
1 2 3 4 5 6 7 8 9 | |
Reject requests with a timestamp more than 5 minutes off from wall-clock. That prevents replay attacks.
Retry policy#
ScaiSend retries failed deliveries (any non-2xx response or timeout > 30 seconds) with exponential backoff:
| Attempt | Delay after previous failure |
|---|---|
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 15 minutes |
| 5 | 1 hour |
| 6 | 2 hours |
After 6 failed attempts, the delivery is marked failed and not retried. After 10 consecutive failures across deliveries, the endpoint is auto-disabled (disabled_at set). Re-enable with PATCH {"enabled": true}.
See Webhooks Deep Dive for the details.
Event types#
Full list of X-ScaiSend-Event values (and the event_type field):
processeddeferreddeliveredbounceblockeddroppedopenclickspam_reportunsubscribegroup_unsubscribegroup_resubscribe