Subscriptions
Watching a flight, what you can filter, the lifecycle of a subscription, and the logs behind it.
A subscription watches one flight on one date and delivers every change to one URL. Creating it is the second and last request a typical integration needs. A subscription belongs to the key that created it: another key cannot list, read or change it, and asking for it by id answers 404.
Creating one
POST /v1/subscriptions| Field | Required | Meaning |
|---|---|---|
carrier, flightNumber, date | yes | The flight, exactly as in a lookup. |
origin, destination, flightId | when ambiguous | Pick the leg. Required when the number operates more than one leg that day; the 400 tells you. |
webhookUrl | yes | https:// or http:// URL to POST to. Addresses that resolve to private, loopback or link-local ranges are refused. |
secret | no | Your own signing secret. One is generated when omitted and returned once, in this response. |
events | no | Change types to deliver, from the list of 23. Default: all of them. |
delayThresholdMinutes | no | Delay changes smaller than this are not delivered. 1 to 240, default 1. |
headers | no | Extra headers to send with every delivery, for example your own auth token. |
metadata | no | String map echoed in every webhook. Put your booking or order id here. |
Send an Idempotency-Key header to make the call safe to retry: the same key returns the same subscription instead of creating a second one.
{
"id": "sub_7fd9fa92faf3475db99b",
"status": "active",
"flightKey": "TK1848:2026-09-12@ATH-IST",
"carrier": "TK",
"flightNumber": "1848",
"date": "2026-09-12",
"webhookUrl": "https://yourapp.com/hooks/flights",
"secret": "whsec_Y0Cp2VtM9s8Lq2fXo1nD3a7MA0u",
"events": ["status.changed", "flight.departed", "..."],
"delayThresholdMinutes": 1,
"metadata": { "bookingId": "BK-1042" },
"flightResolved": true,
"createdAt": "2026-09-12T06:02:11.000Z",
"deliveredCount": 0,
"failedCount": 0,
"lastPolledAt": null,
"lastChangeAt": null,
"lastDeliveryAt": null
}Every later read shows the secret as secretHint (whsec_Y0Cp2...MA0u). GET /v1/subscriptions/{id}/secret reveals it again; POST /v1/subscriptions/{id}/secret/rotate replaces it.
Lifecycle
| Status | Meaning |
|---|---|
active | The flight was found and is being polled. |
pending | The flight is not published upstream yet. It is checked on a slow schedule; when it appears the subscription becomes active and you receive subscription.activated. Subscriptions can be created up to seven days ahead. |
paused | You paused it. No polling, no deliveries, nothing lost; resume continues. |
suspended | Twenty consecutive deliveries failed. Polling stops so a dead endpoint is not hammered forever; fix the endpoint and resume. |
completed | The flight arrived and the baggage carousel window passed, or the date went by without the flight ever appearing. subscription.completed is the last event. |
POST /v1/subscriptions/{id}/pause
POST /v1/subscriptions/{id}/resume
DELETE /v1/subscriptions/{id}Deleting removes the subscription and stops its deliveries. The events and deliveries already recorded are kept on our side for thirty days, so whether a particular webhook went out can still be checked after the fact. When the last subscription on a flight goes away, FlightByte stops polling that flight.
How often the flight is polled
You never schedule anything; the cadence follows the flight.
| Situation | Interval |
|---|---|
| More than 48 hours before departure | Every 12 hours |
| 24 to 48 hours | Every 6 hours |
| 6 to 24 hours | Hourly |
| 2 to 6 hours | Every 20 minutes |
| 45 minutes to 2 hours | Every 10 minutes |
| Under 45 minutes, boarding, or departed | Every 3 minutes |
| In the air | Every 10 minutes, every 3 minutes in the last 45 |
| Landed, waiting for the gate | Every 2 minutes |
| At the gate | Every 5 minutes for 45 minutes, for the baggage carousel, then completed |
| Cancelled | Every 30 minutes for a while, in case it is reinstated |
Not published yet (pending) | Every 6 hours far out, hourly within two days, every 15 minutes on the day |
The full decision function, with the reasons behind each row, is in How adaptive polling works.
Many subscriptions on the same leg share one poll; adding subscribers never adds upstream load.
Updating
PATCH /v1/subscriptions/{id}webhookUrl, events, delayThresholdMinutes, headers and metadata can change at any time. The flight itself cannot; create a new subscription for a different flight.
Listing
GET /v1/subscriptions?status=active&carrier=TK&flightNumber=1848&date=2026-09-12&limit=50&offset=0Returns { "total", "data": [...] }. All filters are optional.
Test events
POST /v1/subscriptions/{id}/testSends a subscription.test event through the real pipeline, signed with the real secret, and returns its eventId. Use it to prove an endpoint before the first real change.
Deliveries and events
Everything FlightByte sent, and how it went, is readable from the API.
GET /v1/subscriptions/{id}/deliveries?limit=50
GET /v1/subscriptions/{id}/events?limit=20A delivery record:
{
"eventId": "evt_2f0c8a4e-6f1d-4d0d-9a3b-0f1e2d3c4b5a",
"attempt": 2,
"status": "failed",
"httpStatus": 500,
"error": "HTTP 500",
"durationMs": 3,
"at": "2026-09-12T11:41:07.000Z",
"changeTypes": ["departure.estimated.changed", "delay.increased"]
}events returns the exact payloads that were sent, so you can replay one into a local receiver or see what a field looked like at the time. Delivery records are kept for thirty days.