Errors & blockers

Webhooks vs. polling for social post delivery status

When to subscribe to terminal webhooks and when polling GET /api/posts/{id} is the practical choice instead, per PostGate’s own delivery-lifecycle guidance.

Quick answer

Webhooks are the default: subscribe to post.published, post.partial, and post.failed, and PostGate pushes each terminal outcome — with platform post IDs and permalinks attached — the moment every target resolves, signed with HMAC-SHA256. Poll GET /api/posts/{id} only when webhooks aren't practical (short-lived scripts, local development, one-off batch jobs), with backoff, stopping once every target is terminal.

The create response for a post tells you PostGate accepted the request, not what happened at any destination — that only becomes knowable once delivery finishes, asynchronously, per target. There are exactly two ways to find out when that happens: ask repeatedly, or have PostGate tell you. PostGate supports both, and the docs are explicit about which one should be your default.

PostGate handles OAuth, publishing and delivery evidence for every network through one API. Start free or read the docs.

01

The default is webhooks, and the docs say so directly

Per Delivery lifecycle: "Subscribe to terminal webhooks for normal operation. If polling, back off between reads and stop when every target is terminal." Subscribe to post.published, post.partial, and post.failed — see Webhooks — and PostGate pushes each terminal outcome to your endpoint the moment every target resolves, carrying the platform post IDs and permalinks already attached, signed with HMAC-SHA256.

Subscribe to terminal post eventsPostGate API
curl -X POST https://api.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

What do webhooks win over polling?

  • Lower latency. Your product finds out the instant a terminal state is reached, instead of waiting for your next poll interval.
  • Less load, on both sides. No repeated GET calls against posts that haven't changed state yet.
  • No busy-waiting logic to build. You don't need to write and tune a polling loop, a backoff schedule, or a stop condition — PostGate calls you exactly once per terminal state.

The tradeoff: you take on running a public endpoint, verifying signatures on every request (see Webhook signature verification, explained), and handling redelivery correctly (see Webhook retry best practices).

03

When is polling still the practical choice?

The delivery docs frame polling as the fallback, not the forbidden option: "Poll only when webhooks are not practical." That covers a few real cases — a short-lived script or CLI tool with no public endpoint to receive callbacks, a local development environment before you've deployed anywhere reachable, or a one-off batch job where you already have to wait for the batch to finish and a webhook consumer would be more infrastructure than the job warrants.

Inspect one post on demandPostGate API
curl https://api.postgate.studio/api/posts/post_01JXYZ \
  -H "Authorization: Bearer $POSTGATE_API_KEY"
04

How do you poll correctly, if you have to?

If webhooks genuinely aren't practical for your setup, poll GET /api/posts/{id} with backoff between reads, and stop once every target in the response is terminal — don't keep polling a post that has already resolved. Read the full targets array, not just the aggregate status, since a partial result needs the same per-target handling whether you learn about it from a webhook or a poll — see Handling partial-success posts.

05

Webhooks as the primary signal, with occasional reconciliation polling as a safety net — GET /api/posts/{id} is a source of truth that doesn't depend on webhook delivery succeeding at all, useful for catching anything missed during an outage on your endpoint. See Dead letter queues for webhook delivery for how that reconciliation pattern fits into a webhook-first design.

Frequently asked questions

Which webhook events tell me a post finished delivering?

Subscribe to post.published, post.partial, and post.failed. PostGate pushes each terminal outcome to your endpoint the moment every target resolves, with the platform post IDs and permalinks already attached, and each delivery is signed with HMAC-SHA256 so you can verify it came from PostGate.

When is polling instead of webhooks acceptable?

The delivery docs frame polling as the fallback, not the forbidden option: "Poll only when webhooks are not practical." That covers a short-lived script or CLI tool with no public endpoint to receive callbacks, a local development environment before you have deployed anywhere reachable, or a one-off batch job where a webhook consumer would be more infrastructure than the job warrants.

How should I poll a post's status correctly?

Poll GET /api/posts/{id} with backoff between reads, and stop once every target in the response is terminal — don’t keep polling a post that has already resolved. Read the full targets array, not just the aggregate status, since a partial result needs the same per-target handling whether you learn about it from a webhook or a poll.

What are the tradeoffs of choosing webhooks?

Webhooks win on latency (you find out the instant a terminal state is reached), load (no repeated GET calls against unchanged posts), and simplicity (no polling loop, backoff schedule, or stop condition to build). The tradeoff is that you take on running a public endpoint, verifying signatures on every request, and handling redelivery correctly.

Do I still need polling if I use webhooks?

Most production integrations end up hybrid: webhooks as the primary signal, with occasional reconciliation polling as a safety net. GET /api/posts/{id} is a source of truth that doesn’t depend on webhook delivery succeeding at all, which makes it useful for catching anything missed during an outage on your endpoint.

Build it with PostGate

One API for every social platform your customers care about — sandboxed, documented, and ready today.

Start building Read the docs