Platform

Should I use webhooks, polling, or streaming?

Four mechanisms can tell your code that something happened, and the choice is usually decided by one question before any of the trade-offs matter: who needs to know, your server or a person looking at a screen?

What are the four options?

MechanismDirectionAuthenticates withSurvives your downtime
WebhooksBird posts to your serverAn API key on your endpoint's signing secretYes, retried for about a day
RealtimeBird pushes to a connected clientAn app key in client code, with your backend signing private channelsNo
SSE streamBird streams to a browser sessionA dashboard session cookieNo
PollingYou ask BirdAn API keyNot applicable

When are webhooks the right answer?

Whenever your own server is the thing that needs to react, which is most integrations.

Webhooks are the only option here with delivery guarantees. A failed delivery is retried eight times over roughly 27.5 hours, every attempt carries the same webhook-id so you can deduplicate, and anything that fails past the schedule can be replayed. So a deploy, a database failover or an outage on your side costs you nothing permanent, which is not true of any of the other three.

The costs are real and worth stating. You need a publicly reachable HTTPS endpoint, you have five seconds to respond, and delivery is at-least-once and unordered, so your handler has work to do. How failed webhooks are retried covers the schedule and the ordering rule, and handling duplicate webhooks covers the handler.

When should I use Realtime instead?

When the thing that needs to know is a browser or an app, and a request would be the wrong shape.

Realtime pushes over WebSockets: your server publishes to a named channel and every subscribed client receives it without asking. That is the mechanism for order status on a page somebody is watching, a chat message, a dashboard tile, or a background job finishing.

It is not a substitute for webhooks, for one structural reason: there is no retry. Both guides say so plainly, that Realtime does not replay events published while a client was disconnected and that a client which drops during delivery can miss the event.

The one exception proves the rule rather than softening it. A cache channel remembers its latest event and replays that to each new subscriber, which is how a view renders current state on reconnect. It stores only the most recent event and keeps no history, so a client that missed two updates gets the latest state and never sees the one in between. The platform's remedy for a gap is always the current state, never the events you missed. So Realtime is for what a person sees now, and webhooks are for what your system must not lose.

Two details shape the design. The app key ships inside client code, so a public channel is readable by anyone who has your page; private- and presence- channels ask your backend to sign each subscription instead. And Realtime has webhooks of its own, telling your server when a channel becomes occupied or vacated and when members come and go, which are configured in the dashboard rather than through the public webhooks API.

Does Bird have an SSE endpoint?

Yes, and it is almost certainly not what you want.

GET /v1/events/stream opens a Server-Sent Events stream that notifies you when API resources change, carrying the resource type, id and timestamp so you can then read the resource for its current state. The catch is the credential: it accepts a dashboard session rather than an API key, and its own API reference says to use webhooks with API-key authentication. It exists to keep a dashboard fresh, not to back an integration.

So if you were hoping to avoid running an HTTP endpoint by holding a stream open instead, that is not a path Bird offers today. The answer is webhooks, or polling.

When is polling actually correct?

Three cases, and the first is not a compromise.

When no public event exists for the thing you care about. Toll-free verification is the clear example: there is no public webhook event for its state, so reading the verification on a schedule is the intended way to learn a decision landed, not a workaround. Read it with bird sms tfn verifications get on the command line or the equivalent agent tool rather than looking for it in the API reference, because that operation is not in the public API bundle.

When you cannot accept an inbound request. Local development, a network that will not expose an endpoint, or a compliance boundary that forbids one. Polling needs nothing but outbound access.

When you only need state, not every transition. If what you want is "what is true now", one read answers it. Events tell you about changes, and reconstructing current state from a stream of changes is more work than asking.

What to watch is the rate limit. Reads and lists bucket per acting credential within your organization, so a tight polling loop spends the budget of the key running it rather than the whole organization's, and a 429 tells you to back off. Poll on an interval matched to how quickly you actually need the answer.

Webhooks and Realtime have the full detail on the first two, and rate limits covers what a polling loop is spending.

Développez sur le même réseau.

Une clé API de test est disponible immédiatement. La production est activée dès que vous ajoutez un moyen de paiement et vérifiez un expéditeur.

Commencez avec un seul canal.
Ajoutez les autres quand vous êtes prêt.

Une clé API de test est disponible immédiatement. L'accès production se débloque dès que vous ajoutez un moyen de paiement et vérifiez un expéditeur.

Vous utilisez Claude Code, Cursor ou Codex ? Copiez un prompt de configuration et votre agent installe la CLI Bird et les compétences pour vous. Choisissez le vôtre :

Cursor