Built for the receiving end

The watching, the diffing, and the delivering.

Pulled out of a product that runs on it, so the hard parts of a flight webhook are already written.

[ 01 / 02 ]·Core
Cadence follows the flight

Three minutes at the gate, twelve hours a week out. Each flight is polled on a schedule that tightens as departure nears and lets go after the baggage belt. A flight three weeks out never costs what one at the gate does.

How adaptive polling works
Every attempt on record

Signed, retried, logged. Every delivery carries an HMAC-SHA256 signature and a timestamp, is retried with backoff up to eight times, and is written down with its status and latency.

Verifying signatures, done right
TK1848 · next poll in 3 min · departure imminent
  1. More than 48 h to departure12 h
  2. 24 to 48 h6 h
  3. 6 to 24 h1 h
  4. 2 to 6 h20 min
  5. 45 min to 2 h10 min
  6. Under 45 min, boarding, off the gate3 min
  7. In the air10 min
  8. Last 45 min of the flight3 min
  9. Landed, waiting for the gate2 min
  10. At the gate, no belt yet5 min
  11. Belt known, 45 min passedstop
EventHTTPLatency
  • subscription.created20061 ms
  • flight.updated20084 ms
  • flight.updated50210,004 ms
  • flight.updated20093 ms
  • flight.updated20077 ms
  • flight.updated429212 ms
  • flight.updated20088 ms
  • flight.updated200102 ms
  • subscription.completed20058 ms
  • subscription.created20061 ms
  • flight.updated20084 ms
  • flight.updated50210,004 ms
  • flight.updated20093 ms
  • flight.updated20077 ms
  • flight.updated429212 ms
  • flight.updated20088 ms
  • flight.updated200102 ms
  • subscription.completed20058 ms
POST /v1/subscriptions[ 400 ]
{  "carrier": "TK",  "flightNumber": "1",  "date": "2026-09-12"}
400 Bad Request[ 2 legs ]
TK1 operates two legs on that date. Pass origin, destination or flightId; FlightByte does not guess.
  • SAW → AMSmorning
  • IST → JFKafternoon
POST /v1/subscriptions/sub_7fd9fa92…/test[ 202 ]
  1. subscription.testsigned with the real secret, sent through the real pipeline
  2. POST https://yourapp.com/hooks/flightsattempt 1 · 200 · 63 ms
  3. GET /v1/subscriptions/sub_7fd9fa92…/deliveriesthe attempt, its status and its latency, readable back

Prove the endpoint before the first real change, then read the payload back exactly as it was sent.

Honest at the edges

One number, two legs, no guessing. TK1 flies SAW–AMS in the morning and IST–JFK in the afternoon. A subscription without a selector gets a 400 with both legs; pass origin, destination or flightId and the key is canonical from then on.

Flight number ambiguity
Test before you ship

A real event, on demand. Send a test event through the real pipeline, signed with the real secret, then read the payload and the delivery back from the API. Prove the endpoint before the first gate change.

Test events and the delivery log
[ 02 / 02 ]·Events
23 change types

Everything a flight does, as events

Typed, filterable, and carrying the full snapshot plus exactly what changed since the last delivery.

  • Lifecyclestatus.changedthe code or phase moved, for any reason
  • Lifecycleflight.departedleft the gate or the runway
  • Lifecycleflight.arrivedreached the gate
  • Lifecycleflight.cancelledcancelled
  • Lifecycleflight.divertedlanding somewhere other than planned
  • Lifecycleflight.reinstateda cancellation reversed
  • Wheredeparture.gate.changeddeparture gate moved
  • Wheredeparture.terminal.changeddeparture terminal moved
  • Wherearrival.gate.changedarrival gate moved
  • Wherearrival.terminal.changedarrival terminal moved
  • Wherearrival.baggage.changedbelt assigned or changed
  • Whendeparture.scheduled.changedthe timetable itself moved
  • Whendeparture.estimated.changedthe estimate moved
  • Whendeparture.actual.changedit actually left
  • Whenarrival.scheduled.changedthe timetable itself moved
  • Whenarrival.estimated.changedthe estimate moved
  • Whenarrival.actual.changedit actually arrived
  • How latedelay.increasedgrew past your threshold
  • How latedelay.decreasedand shrank back
  • Whataircraft.changedthe type changed
  • Whataircraft.tail.changedthe airframe changed
  • Whatroute.changedorigin or destination changed
  • Whatcodeshares.changedthe codeshare list changed
  • In every deliveryflight: { …the full snapshot… }plus from, to, and a delta for every change
Seven days ahead

Subscribe before the airline does. Book the watch when the booking is made. Until the flight is published the subscription waits as pending, and you get subscription.activated the moment it appears.

The subscription lifecycle
Suspended, not spammed

A dead endpoint is not hammered. Eight retries with backoff per delivery. Twenty straight failures and the subscription is suspended, with an event telling you so; one call resumes it, and the log says what you missed.

Retries and suspension
  1. T−7 d
    subscription.createdstatus: pending · checked every 6 h
  2. T−3 d
    subscription.activatedthe flight appeared upstream · status: active
  3. T−18 h
    flight.updateddeparture.scheduled.changed · the timetable moved
  4. T+45 min
    subscription.completedbelt known, grace window passed
One delivery, eight attempts
  1. 1 · 4 s→
  2. 2 · 8 s→
  3. 3 · 16 s→
  4. 4 · 32 s→
  5. 8 · …
Twenty in a row, then
subscription.suspended→POST /v1/subscriptions/{id}/resume

Polling stops so a dead endpoint is not hammered; the events log tells you what you missed.

Get started

Ready to watch a flight?

An API key, the docs, and two requests stand between you and your first webhook.

A free key in a minute, no card. On a paid plan? Request a key