Browse docs
Register a social media webhooks endpoint#
curl -X POST https://api.skedcast.com/v1/webhooks \
-H "Authorization: Bearer sked_live_YOUR_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/skedcast/events",
"events": ["target.published", "target.failed", "media.ready", "media.failed"]
}'The events that matter most for a posting integration#
target.published/target.failed— the outcome of one destination (per-account, per-platform).media.ready/media.failed— an uploaded asset finished (or failed) transcoding.account.reauth_required— a connected account's token needs the owner to reconnect.post.canceled— a still-pending post was canceled before it published.
Delivery guarantees#
Delivery is at-least-once with exponential-backoff retries — dedupe on the payload's id, which is stable across retries. An endpoint is paced (rate-limited per minute) so a bulk schedule's burst of events can't overwhelm your server; a held event arrives a little later, never dropped, unless the limit stays exceeded for over an hour.
Verifying the signature#
Every delivery carries X-SkedCast-Signature: t=<unix-seconds>,v1=<hex>. Recompute HMAC-SHA256(secret, "<t>.<rawBody>") over the exact raw request body, using your endpoint's signing secret, and constant-time-compare the hex digest to v1. Reject if it doesn't match, or if |now − t| exceeds ~300 seconds (replay protection). The full worked example with code is in the dedicated signature-verification guide.
FAQ
- What if I can't expose a public HTTPS endpoint?
- Poll instead: GET /media/:id (ready flag), GET /post-targets (per-destination status), GET /accounts (health). Everything a webhook tells you is also readable on demand.
- Why might I receive the same event twice?
- Delivery is at-least-once — if your endpoint processed an event but SkedCast never saw a 2xx response, it retries. Dedupe on the payload id, which stays the same across retries.