Flights & Active Catalog
Flights & Active Catalog
Register a flight’s operational context and the titles actually loaded on the aircraft — so a passenger is never shown something that isn’t there.
Two endpoints, both idempotent and both machine-to-machine (no
X-Session-Id, no model call):
PUT /v1/flights/{flightInstanceId}— register or fully replace a flight’s operational context (route and schedule).PUT /v1/flights/{flightInstanceId}/active-catalog— fully replace the set of titles actually loaded on that aircraft.
They are disjoint. Registering a flight never disturbs its active catalog, and pushing an active catalog never changes the context.
Both are optional. An airline that flies one catalog everywhere can ignore this page entirely: a session with no flight binding, and a flight with no active-catalog push, see the full airline catalog exactly as before.
The order of operations
- Ingest your titles centrally — catalog ingestion. The active-catalog push only resolves external ids; it never creates titles.
- Register the flight (
PUT /v1/flights/{id}). - Push the active catalog (
PUT /v1/flights/{id}/active-catalog) — the flight must already be registered, or the push is a404. - Bind the session to the flight at session
setup, by sending
flightInstanceId.
The flight instance id
The same shape rule applies wherever a flight instance id appears — the route
segment on both endpoints, and flightInstanceId on a session-setup request:
- 1–128 characters, non-blank.
- No control characters.
- Otherwise free-form: a compact operational id such as
"NH0007-2026-07-27", not free text.
A bad value is 422 request.validation. The message names the field and
never echoes your value back.
Register a flight
Returns 204 No Content. Body cap: 64 KiB.
Idempotent, and a full replace. Sending the same request twice yields the same stored record, so it is always safe to retry. Sending a different body replaces the record — this is not a merge, so send the complete context every time.
It carries no passenger data by construction. There is no field on this shape for one.
The scheduled arrival time is what powers the server-derived remaining
flight time on search, for clients that don’t
send flightMinutesRemaining themselves.
Push the active catalog
Body cap: 2 MiB. This call is designed for the short boarding window: ids only — nothing is embedded or re-ingested here, so it is fast and retry-safe.
activeCount is not submitted − unresolved. It counts distinct
titles, so it is lower than the number of ids that resolved whenever
several external ids name the same title (separate ids for two encodes of
one film, say). Do not build a reconciliation check on
submitted == activeCount + unresolvedExternalIds.length — it is not an
identity.
Unresolved ids
Ids the platform cannot resolve to a known title are returned verbatim in
unresolvedExternalIds and are never guessed onto a similar title. The fix
is always the same: ingest those titles centrally
first, then push again.
Remember that an external id becomes resolvable only when the ingest batch that submitted it completes — see the ingestion guide for what “unresolved” does and does not tell you.
If nothing resolves, the flight’s active set becomes empty.
activeCount is 0, every id is echoed back, and a session bound to that
flight then sees no catalog at all on the narrowed surfaces. This is
fail-loud, not fail-safe: the push replaces the set with exactly the titles
the submitted ids resolved to, and an empty resolution is an empty set.
Check unresolvedExternalIds on every push.
What a flight binding changes: narrow-only
Once a flight has an active set, a session bound to that flight (via
flightInstanceId at session setup) has its results
intersected with that set on three surfaces:
- Natural-language search — every mode, semantic queries and the recommend-for-me lineup alike.
- Scored catalog serve (
POST). - Suggestions.
This is the passenger-honest guarantee, end to end: a flight-bound session cannot be shown a title that is not loaded on the aircraft, on any of those three surfaces.
Three things it never does:
- It never widens. The intersection can only ever narrow what the session already sees; it cannot reach outside your airline’s catalog.
- It never overrides the age gate. An active title that is age-inappropriate for the identified member stays hidden. Narrowing and child-safety compose; neither defeats the other.
- It never affects an unbound caller. A session with no flight binding, a flight with no push, and every sessionless machine-to-machine call keep full-catalog behavior exactly as before.
The unscored GET /v1/catalog/serve is never flight-bound. It accepts
no session locator, so there is no binding for it to resolve — it always
returns the full airline catalog, age-gated. Use the scored POST when you
want the flight’s active set.
Counts on a narrowed request
On a flight-narrowed request, totalItems (and search’s coverage
percentages) report the narrowed basis — the titles this request could
actually draw from, which is your visible catalog intersected with the
flight’s active set, before age-gate exclusion. ageExcludedCount counts the
age gate’s removals from that same basis, so on the serve surfaces
totalItems − ageExcludedCount is exactly the servable total.
Un-narrowed requests report unchanged numbers. The practical consequence:
totalItems is a per-request figure, not a library size — it equals your
airline catalog only when the request is not narrowed. If you display “N
titles available”, that is the right number for a bound session and the wrong
number to cache as a catalog statistic.
Request rate limits
Both flight routes are covered by per-client request-rate limits, each with
its own window, sized like the other partner write routes (catalog-ingest
job submission). The limits are deliberately generous
— sized so a boarding wave’s registrations and retries never see a 429.
Over the limit, both endpoints return 429 rate.limited in the standard
error envelope with a Retry-After header. Honor it and
back off. The numeric limits are deployment-tuned and are never disclosed in
the response.
Errors
Standard envelope.
Both endpoints: 422 request.validation (a malformed flightInstanceId,
or a body that breaks a rule above), 400 request.malformed (body not JSON,
or empty), 413 request.malformed (over the body cap), 401 / 403,
429 rate.limited, 500.
The active-catalog push additionally: 404 flight.not_found when no
flight is registered under that id — with an actionable message telling you
to register the flight first. Register, then push.
Full request and response schemas are in the API Reference.