Data API
Free, unauthenticated JSON. Every wait carries a source_type (airport-api, crowdsourced, sensor are measured; predicted is modeled) and a data_tier (live, near-live, predicted). Where no real source exists you get no number, never a default. Please cache responses and keep request rates modest. Machine-readable spec: /openapi.json.
Endpoints
GET/api/v1/airports
Airport list, or ranked typeahead search with ?q=.
q(query) — City, name, state or IATA code. Returns up to `limit` ranked matches.limit(query) — 1–20, default 8 (only with q).
Cache: 5 min when q is set
curl -s https://preboard.ai/api/v1/airports?q=atlGET/api/v1/airports/{code}
Airport, checkpoints and current waits (each wait carries source_type and data_tier).
code(path) — IATA code, e.g. ATL
Cache: none
curl -s https://preboard.ai/api/v1/airports/ATLGET/api/v1/airports/{code}/live
Per-checkpoint, per-lane current waits with trend, confidence and source.
code(path) — IATA code
Cache: 10 s
curl -s https://preboard.ai/api/v1/airports/DFW/liveGET/api/v1/airports/{code}/pattern
Typical standard-lane wait by local hour and day of week, from MEASURED history only. `publishable` is false until ≥14 days of data exist.
code(path) — IATA code
Cache: 10 min
curl -s https://preboard.ai/api/v1/airports/JFK/patternGET/api/v1/airports/{code}/history
Raw readings (≤7 days, `hours`) or hourly rollups (`days`, up to 365).
code(path) — IATA codehours(query) — 1–168 (raw)days(query) — 1–365 (rollup)checkpoint(query) — Optional checkpoint id
Cache: 1–5 min
curl -s https://preboard.ai/api/v1/airports/MIA/history?days=30GET/api/v1/airports/{code}/predict
4-hour forecast (15-minute steps). Only exists where real history supports it.
code(path) — IATA code
Cache: 1 min
curl -s https://preboard.ai/api/v1/airports/PHL/predictGET/api/v1/map/overview
All airports with worst current measured standard wait (null when no live data).
Cache: 60 s (KV)
GET/api/v1/map/worst
Airports with the longest measured waits right now.
limit(query) — 1–50, default 10
Cache: 30 s
GET/api/v1/stats/national
National aggregates over fresh measured waits.
Cache: 60 s
GET/api/v1/coverage
Which airports have real, fresh measurements right now, by source, and which do not.
Cache: 60 s
curl -s https://preboard.ai/api/v1/coverageGET/api/v1/leave-by
When to leave / arrive: deterministic plan. Security uses a Live/Traveler reading only when security starts within 2 hours; further out it uses the 'Typical' measured wait for that hour of the week, otherwise a clearly labeled 'Estimated' baseline (the current reading is returned as security.live_now_minutes for reference). Also accepts POST with the same fields as JSON. Anonymous: 30 req/min/IP; with X-API-Key: your key's limit.
airport(query) — IATA code (required)departure_time(query) — ISO 8601 with timezone offset (required), e.g. 2026-10-12T08:30:00-04:00flight_type(query) — domestic | internationalprogram(query) — none | precheck | clear | bothchecked_bags(query) — 0–10kids(query) — 0–8travel_minutes(query) — Door-to-airport minutes; enables leave_home_atcushion(query) — standard | extra
Cache: none
curl -s https://preboard.ai/api/v1/leave-by?airport=ATL&departure_time=2026-10-12T08:30:00-04:00&program=precheck&travel_minutes=35GET/api/v1/door-to-gate
One door-to-gate answer: every leg (drive, parking, bags, security, walk, gate, cushion) with its own source and confidence, FAA disruption status, arrive_by_options (80/90% on-time) and a prediction_id. Same parameters as leave-by plus drive_minutes and parking_minutes (caller-supplied; Preboard does not know traffic).
airport(query) — IATA codedeparture_time(query) — ISO 8601 with offsetdrive_minutes(query) — 0-600, optionalparking_minutes(query) — 0-120, optional
Cache: none
curl -s https://preboard.ai/api/v1/door-to-gate?airport=ATL&departure_time=2026-10-12T08:30:00-04:00&program=precheck&drive_minutes=35&parking_minutes=10GET/api/v1/door-to-gate/ics
Same inputs as door-to-gate; returns a leave-by calendar event (.ics, text/calendar) with a 15-minute reminder and every leg in the notes.
Cache: none
curl -s https://preboard.ai/api/v1/door-to-gate/ics?airport=SEA&departure_time=2026-10-14T18:10:00-07:00&drive_minutes=35POST/api/v1/pilot-requests
Request a pilot / API key (organization, contact, use case). Stored for review; we reply by email.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/pilot-requests -H 'content-type: application/json' -d '{"org":"Acme Parking","contact_name":"Jo","email":"jo@acme.example","use_case":"Show leave-by time in booking confirmations","airports":"ATL,ORD","expected_rpm":60}'POST/mcp
Model Context Protocol server (Streamable HTTP, JSON responses). Public tools: get_wait, leave_by, door_to_gate, compare_checkpoints, coverage, track_record, report_outcome, faa_delays, airport_conditions, border_waits, check_in_info. When enabled, trip tools (list_trips, add_trip, get_trip_plan, delete_trip, import_trip_email) with Authorization: Bearer pba_.... GET returns 405.
Cache: none
curl -s -X POST https://preboard.ai/mcp -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'GET/embed
Embeddable leave-by card (HTML, no JS/cookies). Params: a, d (ISO or epoch minutes), f=d|i, p=n|p|c|b, b, k, t, theme=light|dark, tz.
a(query) — IATA coded(query) — Departure ISO with offset or epoch minutes UTC
Cache: 60 s
curl -s https://preboard.ai/embed?a=ATL&d=2026-10-12T08:30:00-04:00&p=p&t=35POST/api/v1/devices
Register an iOS device for future alerts (no push is sent yet). Returns a one-time device_secret. 10 req/min/IP.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/devices -H 'content-type: application/json' -d '{"apns_token":"0000000000000000000000000000000000000000000000000000000000000000","airport":"ATL","threshold_minutes":45,"timezone":"America/New_York"}'PUT/api/v1/devices/{id}
Update alert preferences. Authorization: Bearer <device_secret>.
id(path) — device_id
Cache: none
curl -s -X POST https://preboard.ai/api/v1/devices/{id} -H 'content-type: application/json' -d '{"airport":"ATL","threshold_minutes":60}'POST/api/v1/trips/parse
Stateless: extract flight-leg CANDIDATES from pasted confirmation text or .ics contents. Nothing is stored. Confirm before saving.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/trips/parse -H 'content-type: application/json' -d '{"text":"Flight DL 1234 Atlanta (ATL) to Los Angeles (LAX) Departs Oct 20, 2026 8:30 AM"}'GET/api/v1/devices/{id}/trips
List this device's upcoming trips. Authorization: Bearer <device_secret>.
id(path) — device_id
Cache: none
POST/api/v1/devices/{id}/trips
Save a confirmed trip (max 20; no names, confirmation codes or credentials). Authorization: Bearer <device_secret>.
id(path) — device_id
Cache: none
curl -s -X POST https://preboard.ai/api/v1/devices/{id}/trips -H 'content-type: application/json' -d '{"airport":"ATL","departure_time":"2026-10-20T08:30:00-04:00","carrier":"DL","number":"1234","destination":"LAX","program":"precheck","checked_bags":1,"kids":0,"source":"paste"}'GET/api/v1/devices/{id}/trips/{tripId}
One trip with an automatic current leave-by and carrier check-in links. Authorization: Bearer <device_secret>.
id(path) — device_idtripId(path) — trip id
Cache: none
DELETE/api/v1/devices/{id}/trips/{tripId}
Delete a trip. Authorization: Bearer <device_secret>.
id(path) — device_idtripId(path) — trip id
Cache: none
DELETE/api/v1/devices/{id}
Delete this device record and token (Delete my data). Authorization: Bearer <device_secret>.
id(path) — device_id
Cache: none
GET/api/v1/accuracy
Public track record: our predicted security waits vs later measured waits (n, mean error, % within 5/10 min). Numbers are published only after enough predictions are scored; otherwise it reports that it is still collecting.
Cache: 5 min
curl -s https://preboard.ai/api/v1/accuracyPOST/api/v1/outcomes
Report how long security actually took for a prediction_id returned by leave-by. Anonymous; 20/hour per reporter; only after the predicted security time. Body: {prediction_id, actual_minutes 0-300}. Used to score and improve estimates.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/outcomes -H 'content-type: application/json' -d '{"prediction_id":"00000000-0000-0000-0000-000000000000","actual_minutes":18}'GET/api/v1/health
Service and feed health.
Cache: 10 s
GET/api/v1/airports/{code}/checkpoints
Checkpoints for an airport with their current waits (each wait carries its source).
code(path) — IATA code
Cache: none
curl -s https://preboard.ai/api/v1/airports/ATL/checkpointsGET/api/v1/airports/{code}/context
Airport-day context from open public sources, each part labeled by the server: weather (METAR/TAF + active NWS alerts, official), CBP customs processing waits by hour (TYPICAL from recent weeks, NOT live) and live airport rail departures where a feed exists. Any part is null when no source exists.
code(path) — IATA code
Cache: 1–10 min per source
curl -s https://preboard.ai/api/v1/airports/JFK/contextGET/api/v1/border-waits
CBP land-border crossing waits (CBP-published), optionally filtered.
border(query) — canada | mexicoq(query) — Port name filter
Cache: 5 min
curl -s https://preboard.ai/api/v1/border-waits?border=canadaPOST/api/v1/reports
Submit an anonymous traveler wait report. Shown only as 'Traveler reports' (never Live) once enough reports agree. lane_type: standard | precheck | clear; wait_minutes 0–300; note ≤280 chars. No location required. 10 per hour per IP. Returns 201 {id, status}.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/reports -H 'content-type: application/json' -d '{"airport_code":"ATL","checkpoint":"Main","lane_type":"standard","wait_minutes":15,"note":"optional"}'POST/api/v1/reports/flag
Flag a traveler report as wrong, spam, abusive or other (reports with enough flags are hidden). Returns 202 whether or not the id exists.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/reports/flag -H 'content-type: application/json' -d '{"report_id":"00000000-0000-0000-0000-000000000000","reason":"wrong"}'POST/api/v1/alerts/subscribe
Long-wait email alert sign-up (double opt-in). Requires consent:true (and a Turnstile token when configured). Email sending is currently switched off; sign-ups are stored and nothing is sent until it is enabled. Confirm/unsubscribe happen via the links in the emails (web forms).
Cache: none
curl -s -X POST https://preboard.ai/api/v1/alerts/subscribe -H 'content-type: application/json' -d '{"email":"you@example.com","airport":"ATL","consent":true}'POST/api/auth/apple/native
iOS Sign in with Apple: exchange an Apple identity token (+ SHA-256 of the raw nonce) for a Preboard session token. Returns {session_token, expires_at}; send it as Authorization: Bearer on /api/account calls. Accounts are optional.
Cache: none
curl -s -X POST https://preboard.ai/api/auth/apple/native -H 'content-type: application/json' -d '{"identity_token":"<Apple JWT>","nonce_sha256":"<hex>","full_name":"optional"}'POST/api/auth/logout
End the current session (cookie or Bearer token).
Cache: none
GET/api/account
Current account: {signed_in:false} when anonymous, otherwise the user's email, preferences and saved trips. Cookie or Bearer session.
Cache: none
PUT/api/account
Save trip preferences (validated; unknown keys dropped): home_airport, program, checked_bags, kids, drive_minutes, extra_cushion, flight_type, alerts. Bearer or same-origin cookie.
Cache: none
curl -s -X POST https://preboard.ai/api/account -H 'content-type: application/json' -d '{"prefs":{"home_airport":"CLT","program":"precheck","checked_bags":1,"drive_minutes":25}}'DELETE/api/account
Permanently delete the account: user, sign-in identities, sessions, preferences and trips.
Cache: none
GET/api/account/export
Download everything stored for this account as JSON.
Cache: none
POST/api/account/trips
Save a trip to the account (max 50). DELETE /api/account/trips?id=... removes one.
Cache: none
curl -s -X POST https://preboard.ai/api/account/trips -H 'content-type: application/json' -d '{"airport":"CLT","departure_time":"2026-10-20T08:30:00-04:00"}'DELETE/api/account/trips
Delete one saved trip (?id=).
id(query) — trip id
Cache: none
GET/api/v1/checkin
Public, stateless: when online check-in opens (and closes, where the airline publishes a cutoff) for a flight, plus the airline's own check-in page. Preboard never checks anyone in. Without parameters, lists the airline rules (each with the date it was verified).
carrier(query) — 2-character IATA airline code, e.g. DLdeparture_time(query) — ISO 8601 with offsetflight_type(query) — domestic | international
Cache: none (list: 1 h)
curl -s https://preboard.ai/api/v1/checkin?carrier=WN&departure_time=2026-11-20T08:30:00-05:00GET/api/v1/me/trips
The traveler's upcoming trips with check-in windows. Authorization: Bearer pba_<personal agent token> (scope trips:read). Off (404) until the trips/agent API is enabled. 60 req/min per token.
Cache: none
POST/api/v1/me/trips
Save a trip (scope trips:write). The same flight on the same day updates the existing trip. No names, confirmation codes or airline logins are accepted. Returns 201 saved / 200 updated with the check-in window.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/me/trips -H 'content-type: application/json' -d '{"airport":"ATL","departure_time":"2026-11-20T08:30:00-05:00","carrier":"DL","number":"1234","destination":"LAX","program":"precheck","checked_bags":1}'GET/api/v1/me/trips/{tripId}
One trip with a fresh leave-by plan (security labeled Live / Typical / Estimated as in /leave-by) and its check-in window (scope trips:read).
tripId(path) — trip id
Cache: none
DELETE/api/v1/me/trips/{tripId}
Delete a trip (scope trips:write).
tripId(path) — trip id
Cache: none
POST/api/v1/me/trips/import
Push a confirmation email the user's agent already has (raw .eml, HTML or text) or .ics contents. Reads schema.org FlightReservation JSON-LD, then microdata, then text. save:false (default, trips:read) previews; save:true (trips:write) saves high/medium-confidence legs and removes cancelled ones. Only airline, flight number, airports and times are kept; the email is never stored. Max ~1 MB.
Cache: none
curl -s -X POST https://preboard.ai/api/v1/me/trips/import -H 'content-type: application/json' -d '{"email":"<raw RFC 822 message or HTML>","save":false,"defaults":{"program":"precheck","checked_bags":1}}'GET/api/account/agent-tokens
List the signed-in user's personal agent tokens (never the token values). Off (404) until the trips/agent API is enabled.
Cache: none
POST/api/account/agent-tokens
Create a personal agent token for the user's own AI agent. Shown once; only its hash is stored. Body: name, scopes (trips:read, trips:write), days (1-365, default 90). Max 10 active. Same-origin cookie or Bearer session.
Cache: none
curl -s -X POST https://preboard.ai/api/account/agent-tokens -H 'content-type: application/json' -d '{"name":"My Claude","scopes":["trips:read","trips:write"],"days":90}'DELETE/api/account/agent-tokens
Revoke a personal agent token (?id=).
id(query) — token id
Cache: none
GET/api/account/trip-inbox
Whether the user has a private trip-forwarding address. Off (404) until email import is enabled.
Cache: none
POST/api/account/trip-inbox
Create or rotate the private forwarding address (trips+<alias>@preboard.ai), shown once. Forwarded airline confirmations become trips; the email is not stored.
Cache: none
DELETE/api/account/trip-inbox
Delete the forwarding address (mail to it is then dropped).
Cache: none
POST/a2a
A2A (Agent2Agent) JSON-RPC: SendMessage (v1.0) or message/send (v0.3), synchronous. Send one data part {skill, arguments}; skills are the MCP tools. No tasks, no streaming. Card: /.well-known/agent-card.json.
Cache: none
curl -s -X POST https://preboard.ai/a2a -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"role":"ROLE_USER","messageId":"1","parts":[{"data":{"skill":"check_in_info","arguments":{"carrier":"DL","departure_time":"2026-11-20T08:30:00-05:00"}}}]}}}'GET/.well-known/agent-card.json
A2A v1.0 Agent Card (also at /.well-known/agent.json).
Cache: 10 min
MCP server (for AI assistants)
Connect any MCP client to https://preboard.ai/mcp (Streamable HTTP, no auth, rate limited). Tools: get_wait, leave_by, compare_checkpoints, coverage, track_record, faa_delays (FAA-reported delays only; no modeled “delay risk”). All tools are read-only. Answers carry the labels Live, Traveler reports or Estimated; when there is no real data the tool says “No live data” instead of guessing. Every wait and leave-by answer includes a trust object (confidence, basis, data age, abstain, agent guidance, track record) and leave-by returns a prediction_id; arrive_by_options gives earlier arrive-by times with an on-time probability (basis calibrated or assumed); after a trip, report_outcome / POST /api/v1/outcomes reports the real wait. Step-by-step setup for ChatGPT, Claude, Gemini and Cursor: /ai. MCP prompts (plan_my_departure, airport_briefing), resources, and a leave-by calendar file (/api/v1/door-to-gate/ics). Discovery: llms.txt, server card. See the live track record and GET /api/v1/accuracy.
{ "mcpServers": { "preboard": { "url": "https://preboard.ai/mcp" } } }Embeddable leave-by widget
Fully isolated (sandboxed iframe, no cookies, no tracking). Paste where you want the card:
<script src="https://preboard.ai/embed.js" data-airport="ATL"
data-departure="2026-10-12T08:30:00-04:00" data-program="p" data-travel="35" async></script>Attributes: data-airport, data-departure (ISO with offset), data-flight (d|i), data-program (n|p|c|b), data-bags, data-kids, data-travel, data-theme (light|dark), data-tz, data-height.
API keys & pilots
Anonymous use is limited to 30 requests/minute per IP. Parking, hotel, rideshare, travel-management and booking teams can request a free pilot key with a higher per-key limit (send it as X-API-Key). We will also share accuracy statistics from our prediction log as the pilot runs.
Terms
Provided as-is, best effort, no SLA. Not affiliated with TSA. Attribution to PreBoard (preboard.ai) appreciated. Wait times are estimates; always allow extra time. Questions: see About.