Know when they land, not when they were supposed to.
A transfer has one hard fact in it: the moment the passenger walks out of arrivals. Everything else, the driver’s timing, the free waiting window, the apology, hangs off that. FlightByte began inside an airport transfer service that needed that fact reliably. This page is how it is wired.
The two ways a pickup goes wrong
The driver waits
The aircraft is forty minutes late and nobody told dispatch. The driver has been at the door since the scheduled time, the parking meter is running, and the next job is now late too.
The passenger waits
The aircraft landed early, the passenger has no bag to collect, and they are standing at the door looking for a name board that is still fifteen minutes away. This is the one that becomes a review.
Both come from the same gap: the pickup time on the job is a guess made at booking, and the flight moves. Polling a status endpoint every few minutes for every booking closes the gap, expensively. A subscription closes it once.
How we run it
Five steps, all of them in a backend that existed before FlightByte did. Nothing here is a demo.
One subscription per pickup, at booking time
When a booking with a flight number is saved, the backend subscribes to that flight on that date with the arrival airport as the leg selector. The idempotency key means a retried request cannot create a second subscription; the secret is our own, so every delivery verifies against one setting rather than a secret per row.
POST /v1/subscriptions
x-api-key: $FLIGHTBYTE_KEY
idempotency-key: airport-backend:TK1848:2026-09-12:IST
{
"carrier": "TK",
"flightNumber": "1848",
"date": "2026-09-12",
"destination": "IST",
"webhookUrl": "https://ops.example.com/api/flights/flightbyte/<route-secret>",
"secret": "$FLIGHT_WEBHOOK_SECRET",
"events": [
"status.changed", "flight.arrived", "flight.cancelled",
"flight.diverted", "flight.reinstated",
"arrival.scheduled.changed", "arrival.estimated.changed",
"arrival.actual.changed", "delay.increased", "delay.decreased"
],
"metadata": { "source": "airport-backend" }
}Verify, then trust the lookup, not the push
The receiver checks the signature against the raw body and the timestamp, answers 204, and treats the webhook as a trigger: it looks the flight up again with its own key and applies that snapshot to every booking on the flight. The push says something changed; the lookup is the truth the messages are written from. That costs one request per event and removes a whole class of ordering bugs.
Tell dispatch, in the dispatcher's clock
Two messages matter. Landed: the aircraft is on the ground, the free waiting time has started, here is the driver, or, loudly, here is the missing driver. Delayed: sent when the delay crosses twenty minutes, once per crossing, not on every drift. Times are printed in the airport city’s zone, because that is the clock the driver works to.
Athens → Istanbul
Landed 10:52 · 22 min late
A. Passenger · 2 pax · Mercedes Vito
Keep a small net under it
Webhooks replaced the polling, but not the paranoia. A sweep still runs every five minutes, and only around the pickup itself: from twenty minutes before to four hours after. It exists for the pushes that did not arrive, a deploy in the wrong minute, a network blip, a provider that gave up after its retries. It asks about a handful of flights, not every booking on the books, so it never turns back into the thing the subscriptions replaced.
Let it end
After the aircraft is at the gate and the baggage window has passed, FlightByte completes the subscription on its own and sends subscription.completed. A cancelled booking unsubscribes explicitly. Nothing is watched for longer than it is worth.
The events we subscribe to, and why
Ten of the 23. Gate and baggage changes are left out on purpose: a driver at the arrivals door does not act on them, and every delivery is one your receiver has to handle.
| Event | Why it is on the list |
|---|---|
flight.arrived | The passenger is on the ground. The free waiting time starts now. |
arrival.estimated.changed | The landing moved. Dispatch re-times the driver before the driver notices. |
arrival.actual.changed | The landing happened at a time other than the estimate said. |
delay.increased | Only when it crosses our threshold; small drifts are noise to a dispatcher. |
delay.decreased | An early aircraft is the one that catches everybody out. |
flight.cancelled | Stop the driver. Call the customer. |
flight.diverted | The passenger is landing somewhere else. Everything changes. |
flight.reinstated | A cancelled flight came back; so does the pickup. |
status.changed | Anything else worth a second look, without a message of its own. |
arrival.scheduled.changed | The airline moved the timetable itself, days out. |
A pickup, minute by minute
| When | What happens | Who does it |
|---|---|---|
| Booking made, 4 days out | Subscription created. Flight not published yet, so it sits as pending. | Your backend |
| 2 days out | Flight appears upstream; subscription activates. subscription.activated delivered. | FlightByte |
| Day of, 06:00 | Polling tightens as departure nears: hourly, then every 15 minutes. | FlightByte |
| 08:40 | Departure slips 25 minutes; arrival estimate moves. delay.increased delivered. | FlightByte → dispatch |
| 08:41 | Delayed message: pickup re-timed, driver told before leaving the depot. | Your backend |
| 10:52 | Aircraft on the ground. flight.arrived delivered within the polling interval. | FlightByte → dispatch |
| 10:52 | Landed message with the actual time and the driver line. | Your backend |
| 11:37 | Gate arrival and baggage window pass. subscription.completed. | FlightByte |
What it costs a transfer business
One booking is one watched flight. The plan follows the number of pickups with a flight attached.
Nine cents a pickup.
Under four cents a pickup, against a transfer that sells for far more.
About two and a half cents a pickup; extra pickups at three cents each rather than a wall.
Full plans on the pricing page.
Questions transfer operators ask
The same flight number flies twice a day. Which one gets watched?
origin or destination. A transfer always knows the arrival airport, so we subscribe with destination set to it. If the number is still ambiguous FlightByte refuses with a 400 and the legs, rather than guessing and watching the wrong aircraft.What if our server is down when the aircraft lands?
The flight is not published yet when the booking is made. Does the subscription fail?
pending, checked on a slow schedule, and activated the moment the flight appears, with a subscription.activated webhook. If the date passes and it never appears you receive subscription.completed, so you know rather than wonder.Do we need gate and baggage events?
Other uses
Wire it into your dispatch this week.
A key, the quickstart, and the subscribe request above. The receiver is thirty lines.
A free key in a minute, no card. On a paid plan? Request a key