Building Resilient Flight Workflows: Null, Partial and Late Data
Real flight data has holes — a missing ETA, no terminal yet, an arrival not confirmed. A good integration never breaks on a null. Here is a practical playbook: the fallback ladder, when to lean on a monitor, and the buffers that keep a dispatch or alert working when a field is empty.
Flight data is live, and live data is uneven. A field that's populated for one flight is empty for the next; an arrival time that's there at noon was null an hour earlier. The difference between a flight integration that feels solid and one that pages you at 3am is almost entirely how it handles the holes. This playbook is the defensive-integration checklist: what to read when the obvious field is empty, when to stop guessing and let a monitor tell you, and the buffers that keep a pickup or an alert working even when a value hasn't arrived yet.
Rule 1 — the fallback ladder
Never read a single field and assume it's there. For any time, climb down from the most real value to the least, and remember which rung you landed on:
# arrival — prefer the most real value present arr = gateArrivalTimes.actual or gateArrivalTimes.estimated or gateArrivalTimes.scheduled confirmed = gateArrivalTimes.actual is not None if arr is None: # genuinely nothing yet — don't crash; defer and let a monitor fill it (Rule 3) schedule_recheck()
The same ladder works for departure. The key is that a null at the top rung is normal, not an error — it just means you use the next rung and note that the value is still provisional.
Rule 2 — treat missing detail fields as "not yet," not "never"
Gate, terminal and baggage belt are published progressively — often empty hours ahead and filled closer to the day. A null terminal is almost never "this flight has no terminal"; it's "not assigned yet." So render around it gracefully and re-check as departure approaches, rather than showing a broken field:
terminal = arrival.terminal # may be null well before the day show = terminal or "Terminal TBA" # fill in when it publishes
The same applies to gates and baggage belts: display a placeholder, and let the value replace it when it's known.
Rule 3 — when the value isn't there, let a monitor deliver it
If your workflow is waiting on a value — an ETA that hasn't firmed up, a terminal not yet published — don't sit in a polling loop hoping to catch it. Create a monitor and let the update arrive:
curl -X POST "https://api.flightnerve.com/monitor/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "flight": "EK72", "date": "20260803", "monitor": { "sensitivity_min": 15 } }'
Now a firming arrival estimate, a gate assignment, or a landing lands on your webhook the moment it exists — so the hole fills itself and your workflow proceeds on real data instead of a guess.
Rule 4 — an airborne flight with no arrival time
Occasionally a flight is clearly in the air but the arrival estimate is thin. Two safe moves: read the live progress, and fall back to the schedule with a buffer.
# live minutes-to-arrival for an airborne flight GET https://api.flightnerve.com/track/YOUR_KEY?num=72&name=EK&date=20260803 → { "etaMinutes": 24, "estArrival": 1785686640, "phase": "descent" }
If even that is unavailable, use the scheduled arrival plus a buffer, and let a monitor upgrade you to the real time when it appears. Never hard-fail a dispatch because one field was momentarily empty.
Rule 5 — buffer for the ground, not the flight
The arrival time is gate arrival; a passenger still has to taxi, clear immigration, and collect a bag. Bake a fixed post-arrival buffer into your dispatch instead of padding the flight time — that way you stage against the real arrival and add the predictable ground delay separately:
curb_time = arrival_eta + POST_ARRIVAL_BUFFER # e.g. +20 min domestic, +40 intl
Rule 6 — make your handlers idempotent
Updates arrive more than once — a re-sent webhook, a re-read on retry. Key every action to the flight and the change so acting twice is harmless: store the monitoring_id (and the event) you've already handled, and no-op on a repeat. A resilient workflow can receive the same update five times and dispatch exactly one driver.
The checklist
- Climb the ladder — actual → estimated → scheduled; a top-rung null is normal.
- Detail fields are "not yet" — placeholder for a null terminal/gate/belt, then fill in.
- Wait with a monitor, not a polling loop.
- Airborne but no ETA → live
etaMinutes, else scheduled + buffer. - Buffer the ground, separate from the flight time.
- Idempotent handlers — act once no matter how many times an update lands.
Frequently asked questions
Is a null time an error?
No. It means that value hasn't happened or been published yet — use the next rung of the ladder (estimated, then scheduled) and treat the number as provisional.
Why is the terminal empty for a flight that clearly uses one?
It usually isn't assigned yet. Show a placeholder and re-check closer to departure, or let a monitor push the terminal when it publishes.
How do I stop polling just to catch a value that isn't there yet?
Create a monitor. The moment the estimate firms up, the gate is assigned, or the flight lands, the update arrives on your webhook — no loop required.
What should I dispatch on if there's no arrival estimate at all?
Use live etaMinutes from /track for an airborne flight; if that's absent too, use the scheduled arrival with a buffer and upgrade when a real estimate arrives.
How do I avoid double-dispatching on repeated updates?
Make handlers idempotent — key each action to the monitoring_id and the specific change, and no-op if you've already handled it.
Resilient flight integration isn't about perfect data — it's about never breaking on imperfect data. Climb the ladder, treat holes as "not yet," let monitors fill the gaps, and buffer the parts you can't see. Do that and a missing field becomes a shrug, not an incident.
