Create Webhook
Endpoint: POST /webhooks
Body
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Must be HTTPS and cannot target private/internal addresses. |
events | string[] | Yes | Any of: post.published, post.failed, post.partial. |
workspace_id | string | No | Team account scope. |
Response
Returns webhook metadata and secret once:
{
"data": {
"id": "uuid",
"url": "https://example.com/webhooks/postixly",
"events": ["post.published", "post.failed"],
"active": true,
"created_at": "2026-03-23T18:00:00.000Z",
"secret": "returned_once_only"
}
}
Delivery headers
When events are delivered, the worker sends:
X-Social-Publisher-EventX-Social-Publisher-Signature: sha256=<hmac>
Signature is HMAC-SHA256 over the raw JSON body using the webhook secret.
Delivery payload
All events share this top-level structure:
{
"event": "post.published",
"account_id": "account-uuid",
"post_id": "post-uuid",
"timestamp": "2026-03-23T18:00:00.000Z",
"data": { ... }
}
The data field varies by event:
post.published / post.partial
{
"event": "post.published",
"account_id": "account-uuid",
"post_id": "post-uuid",
"timestamp": "2026-03-23T18:00:00.000Z",
"data": {
"published": 2,
"failed": 0,
"total": 2
}
}
post.failed
{
"event": "post.failed",
"account_id": "account-uuid",
"post_id": "post-uuid",
"timestamp": "2026-03-23T18:00:00.000Z",
"data": {
"failed": 2,
"total": 2
}
}
| Field | Description |
|---|---|
event | post.published, post.failed, or post.partial |
account_id | Account that owns the post |
post_id | UUID of the post |
timestamp | ISO 8601 time of delivery |
data.published | Number of targets that succeeded (absent on post.failed) |
data.failed | Number of targets that failed |
data.total | Total number of targets |
Event meanings:
post.published— all targets published successfully (failed === 0)post.failed— all targets failed (published === 0)post.partial— mixed results (failed > 0andpublished > 0)
To get per-target error details, call
GET /posts/:idafter receiving a webhook.