Webhooks
Receive real-time HTTP notifications when events occur in your VoxBurst account.
Base URL
https://api.voxburst.io/v1/webhooksEvents
| Event | Description |
|---|---|
post.scheduled | Post has been scheduled for future publishing |
post.published | Post finished publishing — check data.status to distinguish PUBLISHED (all platforms succeeded) from PARTIAL (some platforms failed) |
post.failed | Post failed to publish on all platforms |
post.draft.approved | Post draft was approved at the final approval workflow step and is now queued for publishing |
account.connected | A new social account was connected |
account.disconnected | A social account was disconnected |
account.error | A connected account has an error (e.g. token expired or revoked) |
media.uploaded | A media file has been uploaded and passed validation |
There is no separate post.partial webhook event. When publishing results in a partial failure, VoxBurst fires post.published with status: "PARTIAL" in the payload. Always check data.status in your post.published handler to detect partial failures and trigger remediation.
Webhook Payload
All webhook events share this envelope format:
{
"id": "evt_abc123",
"type": "post.published",
"createdAt": "2026-02-20T14:00:00Z",
"data": {
"postId": "post_xyz789",
"status": "PARTIAL",
"publishedAt": "2026-02-20T14:00:00Z",
"platforms": [
{
"postPlatformId": "pp_111",
"platform": "twitter",
"accountId": "acc_123",
"status": "published",
"platformPostUrl": "https://x.com/user/status/123456",
"publishedAt": "2026-02-20T14:00:01Z",
"error": null
},
{
"postPlatformId": "pp_222",
"platform": "instagram",
"accountId": "acc_456",
"status": "failed",
"platformPostUrl": null,
"publishedAt": null,
"error": "Media format not supported: image must be JPEG or PNG"
}
]
}
}Use data.status to branch your handler logic: PUBLISHED means all platforms succeeded; PARTIAL means at least one platform failed and the post needs remediation via POST /v1/posts/:id/retry or POST /v1/posts/:id/platforms/:platformId/fix.
Signature Verification
All webhook requests include a signature header for verification:
X-VoxBurst-Signature: t=1707753600,v1=xxxxxxxxxxxxxxxxVerify signatures to ensure requests come from VoxBurst:
import { createHmac } from 'crypto'
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const [tPart, v1Part] = signature.split(',')
const timestamp = tPart.split('=')[1]
const signatureValue = v1Part.split('=')[1]
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex')
return signatureValue === expected
}
// In your webhook handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-voxburst-signature']
const isValid = verifyWebhookSignature(
req.rawBody,
signature,
process.env.WEBHOOK_SECRET
)
if (!isValid) return res.status(401).send('Invalid signature')
const event = req.body
console.log(`Received event: ${event.type}`)
res.status(200).send('OK')
})Always verify webhook signatures in production to prevent spoofed requests.
Retry and Backoff
VoxBurst automatically retries failed webhook deliveries to ensure reliability.
Retry Behavior
| Property | Value | Source |
|---|---|---|
| Max Attempts | 3 | SQS DLQ maxReceiveCount |
| Retry Strategy | Automatic via SQS | src/functions/webhook-worker/handler.ts |
| Timeout | 20 seconds | DELIVERY_TIMEOUT_MS constant |
| Response Body Limit | 10 KB | MAX_RESPONSE_BODY_LENGTH constant |
Retry Triggers
A delivery is retried when:
- The endpoint returns a non-2xx HTTP status code
- The request times out (after 20 seconds)
- The connection fails or returns a network error
Delivery Status Flow
PENDING → DELIVERING → DELIVERED (success)
↓
FAILED (after 3 attempts)Endpoint Failure Tracking
Failed deliveries increment the endpoint’s failureCount. After consecutive failures:
- The delivery status is marked as
failed - The endpoint statistics are updated
- No automatic endpoint disabling occurs (manual intervention required)
Delivery Record
Each webhook delivery creates a record with:
| Field | Description |
|---|---|
status | pending, delivering, delivered, or failed |
attempts | Number of delivery attempts made |
statusCode | HTTP status code from the endpoint (if any) |
responseBody | Response body (truncated to 10 KB) |
responseTimeMs | Time taken for the HTTP request |
error | Error message if delivery failed |
deliveredAt | Timestamp of successful delivery |
Webhooks are delivered via SQS with at-least-once semantics. Your endpoint should be idempotent — processing the same event multiple times should have no side effects.
List Webhooks
GET /v1/webhooks
Required scopes: webhooks:read
curl https://api.voxburst.io/v1/webhooks \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx"Create Webhook
POST /v1/webhooks
Required scopes: webhooks:write
curl -X POST https://api.voxburst.io/v1/webhooks \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/voxburst",
"events": ["post.published", "post.failed"],
"secret": "your_webhook_secret"
}'Response
{
"id": "wh_abc123",
"url": "https://yourapp.com/webhooks/voxburst",
"events": ["post.published", "post.failed"],
"status": "ACTIVE",
"createdAt": "2026-02-20T10:00:00Z"
}Get Webhook
GET /v1/webhooks/:id
Required scopes: webhooks:read
curl https://api.voxburst.io/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx"Update Webhook
PATCH /v1/webhooks/:id
Update webhook URL, events, or status.
Required scopes: webhooks:write
curl -X PATCH https://api.voxburst.io/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"events": ["post.published", "post.failed", "account.error"]
}'Delete Webhook
DELETE /v1/webhooks/:id
Required scopes: webhooks:write
curl -X DELETE https://api.voxburst.io/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx"List Deliveries
GET /v1/webhooks/:id/deliveries
List delivery attempts for a webhook endpoint.
Required scopes: webhooks:read
curl https://api.voxburst.io/v1/webhooks/wh_abc123/deliveries \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx"Response
{
"deliveries": [
{
"id": "del_xyz789",
"eventType": "post.published",
"status": "delivered",
"attempts": 1,
"statusCode": 200,
"responseTimeMs": 143,
"deliveredAt": "2026-04-09T12:00:05Z"
}
]
}Get Delivery
GET /v1/webhooks/:id/deliveries/:deliveryId
Get the full detail for a single delivery attempt, including request and response bodies.
Required scopes: webhooks:read
curl https://api.voxburst.io/v1/webhooks/wh_abc123/deliveries/del_xyz789 \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx"Retry Delivery
POST /v1/webhooks/:id/deliveries/:deliveryId/retry
Manually re-deliver a specific event to the webhook endpoint.
Required scopes: webhooks:write
curl -X POST https://api.voxburst.io/v1/webhooks/wh_abc123/deliveries/del_xyz789/retry \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx"