Outbound webhooks
Subscribe an HTTPS endpoint to publish + schedule events. HMAC-signed, retried with backoff.
Outbound webhooks
Outbound webhooks let Post-EZ notify your server when something happens in a user's account — a post published, a scheduled job failed, a credential expired. These are outbound by design: Post-EZ POSTs to a URL you register, you don't poll us.
Note: this page is about webhooks Post-EZ sends out. The/api/webhookspath under/api/*is for inbound webhooks from third-party platforms (Twitch EventSub, Ayrshare callbacks) and is not part of the public API contract.
Registering a webhook
Webhook endpoints are managed in Settings -> Webhooks. Each registration takes:
- A
target_url(HTTPS only —http://is rejected at save time). - A subset of
event_typesto subscribe to. - A
signing_secretthat Post-EZ generates for you. Copy it on creation, we show it once.
Event types
post.published— a scheduled or immediate post succeeded for at least one platform.post.failed— a scheduled post hit its retry ceiling and is now in a terminalfailedstate.schedule.created— a new row was added to the user's queue.credential.expiring— fires 72 hours before an OAuth token expires.
Delivery shape
Every delivery is a POST with Content-Type: application/json. The body is always:
{
"id": "evt_9a4b...",
"type": "post.published",
"occurred_at": "2026-05-22T18:00:01.000Z",
"data": { /* event-specific payload */ }
}The id is unique per delivery and stable across retries — use it for idempotency on your side.
Signing scheme
Every delivery carries two headers your endpoint should verify:
X-Postez-Signature—t=<unix_ts>,v1=<hmac>wherehmac = HMAC_SHA256(signing_secret, "<t>.<raw_body>").X-Postez-Event— convenience copy of thetypefield so you can route without parsing JSON.
Reject anything where the timestamp is more than 5 minutes off real time — that protects you from replay attacks if the secret ever leaks.
Retry ladder
Any non-2xx response (or a network error) triggers a retry. The schedule is exponential with jitter:
- +30 seconds
- +2 minutes
- +10 minutes
- +1 hour
- +6 hours
After the 5th failure the delivery is parked. The dashboard surfaces parked deliveries so you can manually replay. Total elapsed time before parking is roughly 7 hours and 12 minutes.
Verifying
curl -X POST https://your.app/webhooks/postez \
-H "X-Postez-Signature: t=1716399601,v1=abc123..." \
-H "X-Postez-Event: post.published" \
-H "Content-Type: application/json" \
-d '{"id":"evt_...","type":"post.published","data":{...}}'A 2xx within 10 seconds is considered delivered.