Reference

Webhooks

SocialSpool sends signed HTTP events to registered webhook URLs when post lifecycle state changes occur. Configure webhook endpoints in the dashboard under workspace settings.

Event types

Every event has a type field that identifies what happened:

  • post.created: a new post was created (draft, scheduled, or publish-now).
  • post.scheduled: a post was scheduled with a future publish time.
  • post.queued: a publish job was enqueued in pg-boss.
  • post.published: a target published successfully. Contains the platform post ID and URL.
  • post.failed: a target failed to publish. Contains the error message from the platform.
  • post.canceled: a scheduled post was canceled before publishing.
Payload format

All webhook payloads follow the same envelope structure:

{
  "id": "evt_01HZ...",
  "type": "post.published",
  "created_at": "2026-06-01T12:00:05Z",
  "data": {
    "post_id": "post_01HZ...",
    "target_id": "pt_01HZ...",
    "workspace_id": "ws_01HZ...",
    "platform": "x",
    "status": "published",
    "platform_post_id": "987654321",
    "platform_post_url": "https://x.com/acme/status/987654321",
    "published_at": "2026-06-01T12:00:05Z"
  }
}

The data content varies by event type. The post.failed event includes an error field in data.

Delivery
  • Events are delivered as HTTP POST requests with Content-Type: application/json.
  • Each event includes a Socialspool-Signature header for verification. See the webhook signature verification page.
  • SocialSpool expects a 200 OK response within 10 seconds. Non-200 responses and timeouts trigger retries.
  • Retries are exponential: 10s, 30s, 2m, 5m, 15m, 1h, 4h, 12h. After 24 hours the event is dropped.
Best practices
  • Respond with 200 OK as quickly as possible. Process the event asynchronously in your own queue if needed.
  • Verify the Socialspool-Signature header before trusting the payload.
  • Expect duplicate deliveries. Use the event id for idempotent processing.
  • Store the event id to detect and skip duplicates.