Browse docs
Register an 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) processing.account.reauth_required: a connected account needs its owner to reconnect.post.canceled: a 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.
SkedCast limits how fast it delivers to one endpoint, so a burst of events from a bulk schedule can arrive a little later instead of all at once. A held event is delivered later, unless your endpoint stays over its limit for more than an hour.
Verifying the signature#
Every delivery carries X-SkedCast-Signature: t=<unix-seconds>,v1=<hex>[,v1=<hex>…]. The signature verification guide has the full code.
- Sign
"<t>.<rawBody>"with HMAC-SHA256 and your endpoint's signing secret, over the exact raw request body. - Accept the delivery if the hex digest matches any
v1entry, compared in constant time. - Reject it if nothing matches or if |now − t| is more than 300 seconds (replay protection).
FAQ
- What if I can't expose a public HTTPS endpoint?
- Poll instead: GET /v1/media/{id} (the ready flag), GET /v1/post-targets (per-destination status) and GET /v1/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.