/orgs/:id/webhooks family — see Tier 3 orgs docs when shipped.
Endpoint family
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/me/webhooks | List your subscriptions |
POST | /api/v1/me/webhooks | Create a subscription |
PUT | /api/v1/me/webhooks/:id | Update URL / event_types / status |
DELETE | /api/v1/me/webhooks/:id | Remove a subscription |
GET | /api/v1/me/webhooks/:id/deliveries?page=&page_size= | Inspect delivery attempts |
Authorization: Bearer … or x-api-key). All non-mutating endpoints are free; create/update/delete are free too — webhooks don’t burn credits.
Create
Body
| Field | Type | Required | Notes |
|---|---|---|---|
url | string | yes | Must be HTTPS in production. We POST JSON here on each event. |
event_types | string[] | yes | At least one event from the event catalog. |
secret | string | no | Provide your own HMAC secret. Omit to have the gateway generate a 32-hex value (recommended). |
Response — create
The only response that includes the rawsecret. Save it now — every subsequent list/update response omits it.
List
{ items: [...], total }. secret is omitted on every row.
Update
| Field | Type | Notes |
|---|---|---|
url | string | Updates the destination. We keep the secret. |
event_types | string[] | Replaces the full subscription set. |
status | string | active / disabled. Disabled rows don’t dispatch but are kept for delivery-history. |
Delete
204 No Content. Delivery history for this webhook is kept for 30 days post-delete, then purged.
Deliveries
attempt: 2 / 3 under the same event_type. response_status: 0 means a network/timeout failure (no HTTP response received).
Event catalog
Pass any subset onevent_types. Grouped by source:
user.* — your account self-config writes
user.webhook.create/user.webhook.update/user.webhook.delete
system.* — gateway side
system.balance.notify.dispatched— fired when the low-balance cron pages yousystem.payment.received— fired when a top-up posts
org.* — only if your account is an org owner/admin
org.settings.updateorg.member.concurrencyorg.member.allowed_models/org.member.allowed_models.bulkorg.api_key.create/org.api_key.revokeorg.webhook.create/org.webhook.update/org.webhook.delete
admin.* — only if your account has platform-admin role
admin.org.create/admin.org.update/admin.org.deleteadmin.org.member.add/admin.org.member.role/admin.org.member.removeadmin.org.member.allowed_models/admin.org.member.allotmentadmin.org.allowed_modelsadmin.user.create/admin.user.update/admin.user.deleteadmin.group.create/admin.group.update/admin.group.deleteadmin.balance.adjust
Payload signing
Outgoing POST bodies are signed by the gateway. Verify before trusting:X-ByteSpike-Signature header. Reject any payload whose signature doesn’t verify — we treat that as the contract.
Retry & failure model
- Retry: up to 3 attempts on 5xx / network failures. Backoff: 30s, then 5min.
- fail_count: cumulative since last successful delivery. Reset on the next 2xx.
- Auto-disable: when
fail_countreaches50, the gateway flipsstatustodisabledand stops dispatching. The webhook row is preserved so you can inspect deliveries and re-enable via PUT. - No bypass: 4xx responses count as a delivery (your endpoint rejected the payload); retries don’t fire on 4xx.
Errors
| Status | error.type | Trigger |
|---|---|---|
| 400 | invalid_request_error | URL not HTTPS, event_types empty / unknown event, body malformed. |
| 401 | authentication_error | Missing / revoked key. |
| 403 | permission_error | Subscribed to admin.* / org.* events without the required role. |
| 404 | not_found_error | Webhook :id doesn’t belong to this caller. |
| 409 | conflict_error | Same URL already subscribed (one URL per user, change events on the existing row instead). |