Webhook Subscriptions
Create, list, enable, disable, and delete webhook subscriptions on your API key. Each subscription monitors one flight_number and delivers matching events to your HTTPS callback URL — see Callback Delivery for the inbound POST body. Plan limits and polling interval: Webhooks hub.
Requirements
x-api-key on every request (direct subscription). Learn more →Create webhook
Register an HTTPS URL to receive POST requests when subscribed events fire for a filtered flight.
Requirements
Pro, Ultra, or Mega — BASIC cannot create webhooks
Learn more →Send POST with a JSON body.
https://data.skylinkapi.com/v3.1/webhooks| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS callback URL SkyLink will POST to |
event_types | string[] | Yes | One or more event type strings (see Event types) |
filters | object | Yes | Must include flight_number — IATA flight number to monitor, e.g. BA123 |
{
"url": "https://your-server.example.com/webhook",
"event_types": ["flight_delayed", "flight_landed", "gate_changed"],
"filters": {
"flight_number": "BA123"
}
}201 Created — returns the created subscription object:
{
"id": "00000000-0000-0000-0000-000000000001",
"url": "https://your-server.example.com/webhook",
"event_types": ["flight_delayed", "flight_landed", "gate_changed"],
"filters": { "flight_number": "BA123" },
"active": true
}| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Subscription UUID — use as webhook_id in patch/delete paths |
url | string | Yes | Registered callback URL |
event_types | string[] | Yes | Subscribed events |
filters | object | Yes | Filter object (includes flight_number) |
active | boolean | Yes | Whether deliveries are enabled |
Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Header Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST "https://data.skylinkapi.com/v3.1/webhooks" \ -H "Content-Type: application/json" \ -d '{ "event_types": [ "flight_delayed", "flight_landed", "gate_changed" ], "filters": { "flight_number": "BA123" }, "url": "https://your-server.example.com/webhook" }'null{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}List webhooks
Returns all webhook subscriptions associated with your API key.
https://data.skylinkapi.com/v3.1/webhooks{
"count": 1,
"webhooks": [
{
"id": "00000000-0000-0000-0000-000000000001",
"url": "https://your-server.example.com/webhook",
"event_types": ["status_changed"],
"filters": { "flight_number": "BA123" },
"active": true
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
count | integer | Yes | Number of subscriptions returned |
webhooks | array | Yes | Subscription objects (same shape as create response) |
Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Header Parameters
Response Body
application/json
application/json
curl -X GET "https://data.skylinkapi.com/v3.1/webhooks"null{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}Enable / Disable webhook
Toggle a subscription on or off without deleting it. Use this to resume deliveries after fixing a failed endpoint — see Callback Delivery.
Send PATCH with the subscription id in the path.
https://data.skylinkapi.com/v3.1/webhooks/{webhook_id}| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_id | string (path) | Yes | Subscription UUID from create/list |
| Body field | Type | Required | Description |
|---|---|---|---|
active | boolean | Yes | true to resume deliveries, false to pause |
{ "active": false }200 OK — returns the updated subscription object (same fields as create response).
Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Path Parameters
Header Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X PATCH "https://data.skylinkapi.com/v3.1/webhooks/00000000-0000-0000-0000-000000000001" \ -H "Content-Type: application/json" \ -d '{ "active": true }'null{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}Delete webhook
Permanently remove a subscription. You can only delete webhooks created with your API key.
https://data.skylinkapi.com/v3.1/webhooks/{webhook_id}| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_id | string (path) | Yes | Subscription UUID |
204 No Content — empty body on success.
Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Path Parameters
Header Parameters
Response Body
application/json
curl -X DELETE "https://data.skylinkapi.com/v3.1/webhooks/00000000-0000-0000-0000-000000000001"{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}Event types
Returns the supported webhook event type strings for the event_types array when creating a subscription.
https://data.skylinkapi.com/v3.1/webhooks/events{
"event_types": [
"flight_boarding",
"flight_cancelled",
"flight_delayed",
"flight_landed",
"gate_changed",
"status_changed"
]
}| Event | Trigger |
|---|---|
status_changed | Catch-all — any tracked field changed |
flight_delayed | Status indicates delay or departure time changed |
flight_cancelled | Flight cancelled |
flight_boarding | Boarding in progress |
flight_landed | Flight landed / arrived |
gate_changed | Departure or arrival gate changed |
Fetch supported event type strings once at startup and store them in your subscription form dropdown.
import osimport requestsBASE = "https://data.skylinkapi.com/v3.1"HEADERS = { "x-api-key": os.getenv("SKYLINK_API_KEY") or os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}def list_webhook_event_types() -> list[str]: """Return supported webhook event type strings.""" r = requests.get(f"{BASE}/webhooks/events", headers=HEADERS, timeout=(10, 15)) r.raise_for_status() return r.json()["event_types"]if __name__ == "__main__": import json print(json.dumps(list_webhook_event_types(), indent=2))Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Response Body
application/json
curl -X GET "https://data.skylinkapi.com/v3.1/webhooks/events"nullClient types
"""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
Production webhook integrations register a subscription per tracked flight (or reuse one URL with server-side routing), verify incoming deliveries, and pause subscriptions when trips complete. The example below lists event types, lists existing subscriptions, and demonstrates create/patch/delete helpers with timeouts.
Your callback endpoint should respond with 2xx quickly. See Callback Delivery for the inbound POST body and handler examples.
import osimport requestsBASE = "https://data.skylinkapi.com/v3.1"HEADERS = { "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}def list_webhook_event_types() -> list[str]: """Return supported webhook event type strings.""" r = requests.get(f"{BASE}/webhooks/events", headers=HEADERS, timeout=(10, 15)) r.raise_for_status() return r.json()["event_types"]def list_webhooks() -> dict: """List webhook subscriptions for the current API key.""" r = requests.get(f"{BASE}/webhooks", headers=HEADERS, timeout=(10, 15)) r.raise_for_status() return r.json()def create_webhook(*, url: str, event_types: list[str], flight_number: str) -> dict: """Create a webhook subscription for a single flight.""" body = { "url": url, "event_types": event_types, "filters": {"flight_number": flight_number.upper().replace(" ", "")}, } r = requests.post(f"{BASE}/webhooks", headers=HEADERS, json=body, timeout=(10, 20)) r.raise_for_status() return r.json()def set_webhook_active(webhook_id: str, *, active: bool) -> dict: """Enable or disable a webhook without deleting it.""" r = requests.patch( f"{BASE}/webhooks/{webhook_id}", headers=HEADERS, json={"active": active}, timeout=(10, 15), ) r.raise_for_status() return r.json()def delete_webhook(webhook_id: str) -> None: """Permanently delete a webhook subscription.""" r = requests.delete(f"{BASE}/webhooks/{webhook_id}", headers=HEADERS, timeout=(10, 15)) r.raise_for_status()if __name__ == "__main__": import json events = list_webhook_event_types() print(json.dumps(events, indent=2))Implementation notes
Important: Use a publicly reachable HTTPS endpoint. Local development typically requires a tunnel (ngrok, Cloudflare Tunnel).
Important: The same gate or status may fire multiple events across polls — dedupe by flight_number + event_type + timestamp in your handler.
Recovery after auto-disable. Fix your endpoint, then PATCH the subscription with { "active": true } to resume deliveries. SkyLink does not replay missed events.
Error responses
Plan-gate 403: Webhooks hub. Endpoint-specific:
404 — not found or not owned
{
"detail": "Webhook not found or not owned by you"
}Returned by patch and delete when the webhook_id is unknown or belongs to another API key.