Callback Delivery
When a subscribed event fires, SkyLink sends an HTTP POST to your registered url with Content-Type: application/json.
Important: Your endpoint must respond with 2xx within ~30 seconds — slow handlers count toward the 10 consecutive failure auto-disable limit described on the Webhooks hub.
Request body
The payload merges delivery metadata with the current Flight Status fields (same departure / arrival shape):
{
"event_type": "gate_changed",
"timestamp": "2026-06-16T14:25:00Z",
"webhook_id": "00000000-0000-0000-0000-000000000001",
"flight_number": "BA 123",
"airline": "British Airways",
"status": "En Route",
"departure": {
"airport": "EGLL",
"airport_full": "London Heathrow Airport",
"scheduled_time": "10:30",
"scheduled_date": "11 Feb",
"actual_time": "10:35",
"actual_date": "11 Feb",
"terminal": "5",
"gate": "A12",
"checkin": ""
},
"arrival": {
"airport": "KJFK",
"airport_full": "John F Kennedy International Airport",
"scheduled_time": "14:45",
"scheduled_date": "11 Feb",
"estimated_time": "14:50",
"estimated_date": "11 Feb",
"terminal": "7",
"gate": "B15",
"baggage": ""
}
}| Field | Type | Required | Description |
|---|---|---|---|
event_type | string | Yes | Which subscribed event fired — see Event types |
timestamp | string (ISO 8601) | Yes | When SkyLink detected the change and queued delivery — use for idempotency |
webhook_id | string | Yes | Subscription UUID from create/list |
flight_number | string | Yes | Current flight number (display format, may include a space) |
airline | string | Yes | Airline display name |
status | string | Yes | Current status label — same semantics as Flight Status |
departure | object | Yes | Departure block — field-for-field match with Flight Status |
arrival | object | Yes | Arrival block — field-for-field match with Flight Status |
Gate, terminal, and baggage fields may be empty strings when not published — handle them the same way as in Flight Status integration notes.
Client types
Includes WebhookDelivery and subscription shapes — same bundle as Subscriptions:
"""Webhook subscription models."""from __future__ import annotationsfrom dataclasses import dataclass@dataclassclass WebhookCreateRequest: url: str event_types: list[str] filters: dict[str, str]@dataclassclass WebhookSubscription: id: str url: str event_types: list[str] filters: dict[str, str] active: bool@dataclassclass WebhookListResponse: count: int webhooks: list[WebhookSubscription]@dataclassclass WebhookEventTypesResponse: event_types: list[str]@dataclassclass WebhookDelivery: """Inbound POST body SkyLink sends to your callback URL.""" event_type: str timestamp: str webhook_id: str flight_number: str airline: str status: str departure: dict[str, str] arrival: dict[str, str]Integration
A webhook handler receives POST requests from SkyLink, verifies the payload, stores idempotency state, and returns 2xx quickly. The example below implements a minimal handler in Python (FastAPI) and TypeScript (Express), demonstrates deduplication, and re-enables a subscription via PATCH after recovery from auto-disable.
"""Minimal webhook payload handler - validates shape and extracts gate changes."""from dataclasses import dataclass@dataclassclass GateChange: flight_number: str event_type: str airport: str gate: strdef parse_gate_change(payload: dict) -> GateChange | None: """Return a gate change summary when event_type is gate_changed.""" if payload.get("event_type") != "gate_changed": return None dep = payload.get("departure") or {} arr = payload.get("arrival") or {} gate = dep.get("gate") or arr.get("gate") or "" airport = dep.get("airport") or arr.get("airport") or "" return GateChange( flight_number=str(payload.get("flight_number", "")), event_type=str(payload.get("event_type", "")), airport=airport, gate=gate, )SAMPLE_PAYLOAD = { "event_type": "gate_changed", "timestamp": "2026-06-16T14:25:00Z", "webhook_id": "00000000-0000-0000-0000-000000000001", "flight_number": "BA 123", "airline": "British Airways", "status": "En Route", "departure": {"airport": "EGLL", "gate": "A12"}, "arrival": {"airport": "KJFK", "gate": "B15"},}if __name__ == "__main__": change = parse_gate_change(SAMPLE_PAYLOAD) print(change if change else "No gate change in payload")Implementation notes
Important: Deduplicate by flight_number + event_type + timestamp — the same change may be delivered more than once across poll cycles.
Recovery after auto-disable. Fix your endpoint, then PATCH the subscription with { "active": true } — see Enable / Disable webhook. SkyLink does not replay missed events.
HTTPS only. Your callback URL must be publicly reachable over TLS.
Error responses
Delivery failures (non-2xx or timeout) increment the consecutive failure counter on the subscription. After 10 failures, SkyLink auto-disables the subscription — plan-gate 403 on create: Webhooks hub.