For travel apps · Itinerary managers, trip planners, corporate travel tools

Push the change, not the schedule.

A travel app already knows the user’s flights, usually because somebody forwarded a booking email. What it has to earn is the moment the gate moves: a notification that arrives before the user walks to the wrong pier, and does not arrive for every two-minute drift in the estimate.

This page is both halves: turning what the email said into a flight you can trust, then one subscription per distinct flight and a few lines of routing to every user on it.

The two notifications that lose users

The one that arrives late

The gate changed at 13:02. The poller runs every ten minutes. The push lands at 13:11, after the user read it off the board and after the app lost its reason to exist.

The one that never stops

The estimate moved from 14:05 to 14:07 to 14:04. Three pushes in eleven minutes. The user turns notifications off, and now the cancellation at 14:30 is silent too.

The first is a polling problem; the second is a filtering problem. A subscription with typed events and a delay threshold solves both at once, and the polling schedule tightens to three minutes at the gate on its own.

From a forwarded booking to a watched flight

An itinerary starts as an email. Four fields from it are the identity of the flight; everything else is a display value that FlightByte will replace.

What a booking email gives you and what FlightByte adds
StepWhat you doWhat comes back
ParseKeep carrier, flight number, local departure date and origin. Keep the destination too.The identity of the flight. Times and terminals from the email are display values only.
ConfirmLook the flight up with the origin as the leg selector, if it departs within the live window.Terminals, gate when assigned, aircraft and tail, operating airline, every codeshare number, local times. Further out: 404, keep the email's values.
MergeCheck the number against the aliases of flights you already watch, then store this leg's codeshares as aliases.Two users on one aircraft under two numbers become one watched flight.
WatchSeven days before departure, subscribe once per distinct flight with your own id in metadata.active, or pending until the airline publishes; subscription.activated then carries the full snapshot.

The date needs no conversion: FlightByte addresses a flight by the local departure date at the origin, which is the date printed on the confirmation. The origin is your leg selector, so a number that flies twice a day is never a guess. The full pipeline, with the alias table and the daily job, is in From a booking email to a watched flight.

How to wire it

Five steps. The receiver is thirty lines; the rest is a table you already have.

01

Subscribe per distinct flight, not per user

When a flight comes within seven days of departure, subscribe to it once, keyed by its flightKey. Fifty users on the same flight are one subscription; your own table says who they are. Put your own key in metadata so the webhook tells you which row to fan out from, and use one shared secret so the receiver verifies everything against one setting.

POST /v1/subscriptions
x-api-key: $FLIGHTBYTE_KEY
idempotency-key: trips:TK1848:2026-09-12:ATH

{
  "carrier": "TK",
  "flightNumber": "1848",
  "date": "2026-09-12",
  "origin": "ATH",
  "webhookUrl": "https://api.yourapp.com/hooks/flights",
  "secret": "$FLIGHTBYTE_WEBHOOK_SECRET",
  "delayThresholdMinutes": 10,
  "events": [
    "departure.gate.changed", "departure.terminal.changed",
    "delay.increased", "delay.decreased", "flight.cancelled",
    "flight.departed", "arrival.estimated.changed", "arrival.baggage.changed"
  ],
  "metadata": { "flightRef": "flt_8c1e" }
}
02

Verify, deduplicate, answer, then work

Check the signature against the raw body, drop anything older than five minutes, look the event id up in a processed table, answer 204, and hand the event to a queue. Sending a thousand pushes from inside the request handler is how a slow APNs afternoon turns into retries. The signature guide has the receiver in seven frameworks.

03

Turn each change into copy

A flight.updated delivery carries the changes and the full snapshot. Map each change type to a sentence, read the times from the snapshot in the airport’s local zone, and send one push per delivery even when it carries three changes: “Gate B14, now departing 14:40” is one notification, not two.

YourAppnow
TK1848 · Gate changed to B14
Athens → Istanbul · departing 14:40, 35 min late
04

Fan out from your table

The webhook names the flight; your table names the users. Send to every device on that flight, in the language and zone each user chose, and mark the trip with the new gate so the app shows it on the next open too. A user who added the flight after the subscription existed joins the table, not the subscription.

05

Let it end

After the aircraft is at the gate and the belt is published, FlightByte sends subscription.completed. Archive the flight, keep the trip. A user who deletes a flight leaves your table; the subscription is deleted only when the table for that flight is empty.

What to push, and the copy

Eight of the 23 change types. The rest are noise to a passenger: aircraft swaps, codeshare lists, runway times.

Change types a travel app should push
EventPush copyNote
departure.gate.changedGate changed to B14The one users install the app for. Always send.
departure.terminal.changedTerminal changed to 2Rare, and it changes where the taxi goes.
delay.increasedNow departing 14:40, 35 min lateThreshold at 10 to 15 minutes; below that the airline will move it back.
delay.decreasedBack on time: departing 14:05Good news is a notification too, and early aircraft strand people at the gate.
flight.cancelledTK1848 is cancelledSend, and open the rebooking screen.
flight.departedTK1848 has departedFor the people at home, and for the Live Activity.
arrival.estimated.changedLanding 16:52, 20 min lateOnly past a threshold; the estimate drifts by a minute all afternoon.
arrival.baggage.changedBags on belt 7The last message of the trip, and the most appreciated.

What it costs an app

A watched flight is a distinct flight in your users’ upcoming trips, not a user. The plan follows that number.

Up to 100 flights / month
Hobby, $9

An indie app or a beta. Nine cents a flight, shared by everyone on it.

Up to 500 flights / month
Starter, $19

A few thousand active users on typical routes. Under four cents a flight.

Up to 2,000 flights / month
Growth, $49

Tens of thousands of users; extra flights at three cents each rather than a wall.

Monthly cost by distinct flights watched
Distinct flights a monthPlanMonthlyPer flight
100Hobby$99 cents
500Starter$19under 4 cents
2,000Growth$49under 2.5 cents
5,000Scale$99about 2 cents
10,000Scale plus 5,000 extra$199about 2 cents
MoreA conversationCustomQuotas shaped to your traffic

The count is distinct aircraft, after codeshares are merged, in the month they are subscribed. Followers are free: the fiftieth user on a flight costs nothing, so the cost per user falls as an app grows. Past a plan’s limit, extra flights are billed rather than refused, and nothing already being watched is dropped. Full plans on the pricing page; lookups for import and the trip screen are cached and included.

What it does not do

An itinerary app is assembled from several sources. These are the parts to get elsewhere.

What FlightByte covers and what it leaves to other sources
You may wantFlightByteNote
Status, times, gates, terminals, baggage beltYesScheduled, estimated and actual, in UTC and airport-local form, with typed change events.
Aircraft type and tail, operating airline, codesharesYesIn every snapshot; aircraft.changed and codeshares.changed when they move.
The airline's own history for the flightYesThe timeline, newest first, in the snapshot and on its own endpoint.
Live aircraft position and a map trackNoStatus and times, not where the aircraft is. Use an ADS-B source for the map.
On-time history and route reliability scoresNoLive window only: a few days back, a couple ahead. Keep your own history from the webhooks you receive.
Minimum connection timesNoYou get both flights kept current; the threshold per airport is yours.
Fares, seat maps, check-in linksNoNot flight status.

Guides for app teams

The three pieces of an itinerary integration, each written out in full.

Questions app teams ask

Can we confirm a flight the moment a booking is forwarded?
If it departs within the live window, a few days back to a couple of days ahead, yes: one lookup returns terminals, aircraft, the operating airline and every codeshare number. Further out the lookup answers 404 because no operational record exists yet. Keep what the email said, subscribe when the flight comes within seven days, and let subscription.activated confirm it with the full snapshot.
Two users hold different flight numbers for the same aircraft. Is that two watched flights?
Only if you let it be. The snapshot lists every other number for the leg under codeshares, so keep an alias table of the numbers a watched flight answers to and check a new booking against it before subscribing. Either number resolves to the same aircraft, and one subscription covers all of them.
Can we warn a user about a missed connection?
Yes, and it is yours to compute, because the fact lives between two flights. Subscribe to both, subtract the inbound arrival.bestTimeUtc from the outbound departure.bestTimeUtc on every delivery, and compare with a threshold per airport. FlightByte does not publish minimum connection times; the guide linked below has the state machine.
Does FlightByte send the push notification?
No. FlightByte sends a signed webhook to your server; your server sends the push through APNs, FCM or whatever you already use. That keeps the user, the device token and the wording on your side, where they belong.
Fifty users have the same flight in their trips. Is that fifty watched flights?
Not if you subscribe per distinct flight and fan out yourself. Keep a table of which users are on which flightKey, create one subscription per key, and send fifty pushes from one webhook. You pay for the flights your users fly, not for the number of users.
Users add flights months ahead. Subscriptions only go seven days out.
Store the flight on the trip and subscribe when it comes within seven days; a daily job that subscribes to everything departing in the next week is ten lines. Before that, nothing about the flight changes that a user needs a push for.
What about the user's time zone?
Every time in a snapshot carries utc, local and the airport's timezone. Show the local form for anything at the airport, the device zone for reminders; never convert local again.
Can I drive an iOS Live Activity from this?
Yes, and it maps well: flight.departed starts the flight state, arrival.estimated.changed updates the landing time, arrival.baggage.changed ends it with the belt. Update the activity from the same webhook that sends the push.

Other uses

Get started

Ship gate-change pushes this sprint.

A key, one subscription per flight, and a receiver you can copy. The fan-out is your table.

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