Observe & engage
Webhooks
Subscribe to signed events, verify the raw payload, acknowledge quickly, and let PostGate retry outages.
4
Endpoint summary
All operations in this resource, with the minimum accepted key scope.
Method & endpointPurposeScope
GET
/api/webhooksList webhook endpoints
readPOST
/api/webhooksCreate a subscription and reveal its secret
fullPOST
/api/webhooks/{id}/testQueue a test delivery
fullDELETE
/api/webhooks/{id}Delete a subscription
full01
Create a subscription
Subscribe only to events your product uses. The signing secret is returned once; save it before discarding the response.
Terminal post eventsPostGate API
curl -X POST https://postgate.studio/api/webhooks \
-H "Authorization: Bearer $POSTGATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://app.example.com/webhooks/postgate",
"events": ["post.published", "post.partial", "post.failed"]
}'02
Verify the raw request body
PostGate signs
<timestamp>.<raw-body> with HMAC-SHA256. Parse the t and v1 values from X-PostGate-Signature, reject stale timestamps, and compare digests in constant time. The stable event ID is also sent as X-PostGate-Event-Id.Signature shapePostGate API
t=1785254400,v1=4f7c...9a2e03
Acknowledge before doing work
Verify, persist or enqueue, and return a 2xx response. Delivery is retried when your endpoint times out or returns a non-2xx status. Consumers should deduplicate by the event
id.Test the complete path
Use
POST /api/webhooks/{id}/test after deployment and whenever you rotate infrastructure.04
Use a stable event envelope
Events contain
id, type, occurred_at, and a resource-specific data object. Keep unknown fields when relaying events so your own pipeline remains forward compatible.05
Event catalog
Subscribe any subset of these topics in events[]. post.insights and profile.stats_updated use the same names PostProxy consumers already expect.
post.draft/post.scheduled— a post was created in that state.post.published/post.partial/post.failed— a post reached a terminal state.post.insights— a new hourly analytics snapshot exists for a published target:post_id,targets[](target_id,platform,platform_post_id,metrics),captured_at.profile.connected/profile.disconnected— a profile was connected or disconnected.profile.expiring— a profile’s authorization is nearing expiry.profile.expired— a profile’s token expired with no way to refresh it. Carriesreason: "token_expired".profile.reauth_required— a refresh attempt was rejected by the provider (revoked access, changed password, or an authorization error surfaced while publishing). Carriesreason:refresh_failed,revoked, orpublish_auth_error.profile.stats_updated— a new hourly follower/analytics snapshot exists for a profile:profile_id,platform,followers,follower_delta,metrics,captured_at.stats.updated— PostGate’s generic analytics event, covering both post targets and profiles.comment.created/message.received— inbound engagement arrived.
Both profile.expired and profile.reauth_required fire once per authorization state transition, not on every maintenance sweep; a profile that reconnects and later breaks again fires a new event.