SFO Flight Schedule API: San Francisco Departures as JSON
You need a reliable way to render San Francisco International Airport (SFO) departures in your app, dashboard, or data pipeline. By the end of this guide, you’ll be able to query the FlightLabs schedules API for SFO, parse the JSON, handle status changes and time zones, and ship a departures board that stays current without burning through requests.
What the SFO departures schedule contains and when to use it
The SFO departures schedule is the live board for flights leaving San Francisco (IATA: SFO). It is useful when you need:
- Airport displays and kiosks that refresh every few minutes.
- Travel apps that notify passengers when a gate or departure time changes.
- Logistics and corporate travel dashboards that track outbound movement from SFO.
- Data products that normalize flight identifiers and statuses across airlines.
FlightLabs returns this data as JSON over REST, authenticated with an API key. You can filter to SFO by using the correct airport parameter so you only receive departures from San Francisco. The same JSON shape applies whether you pull SFO or a different airport.
Get access and keys
To make requests, create an account, start the trial, and copy your API key:
- Register for the 7‑day trial (Starter plan is $24.99/mo after the trial). Use: Register
- Copy your access_key from your dashboard.
- Call the schedules endpoint with iataCode=SFO to fetch San Francisco departures.
- Persist flight_iata and status in your store to power diffs and notifications.
You can also explore parameters and field definitions in the Documentation and test requests in the MCP console.
Make the schedules request
The following official sample shows the request shape. It is for a different airport (JFK) so you can see a real response format and fields. To get SFO departures instead, use iataCode=SFO when you call the schedules endpoint with your own key.
curl "https://api.goflightlabs.com/flights-schedules?access_key=YOUR_ACCESS_KEY&iataCode=SFO&type=departure"
Understand the JSON response
The JSON below is the official sample for JFK on a specific date. SFO returns the same structure and keys, so you can build your parser against this and simply switch the filter to iataCode=SFO in production. Do not interpret rows with dep_iata: JFK as San Francisco data—they are only demonstrating the format.
{
"success": true,
"type": "departure",
"data": [{"airline_iata": "TG", "flight_iata": "TG6173", "dep_iata": "JFK", "arr_iata": "BKK", "status": "scheduled"}]
}
What to focus on in the response:
- success: Indicates whether the API could fulfill the request. If false, handle the error message and retry/back off as needed.
- flight_iata: The public flight identifier (e.g., UA123). Store this to reconcile updates between polls and to display to users.
- status: High-level live state you’ll surface on your board (commonly includes scheduled, active, delayed, cancelled, landed, diverted, etc.). Use this to decide how to style the row and whether to send a push.
- dep_iata / arr_iata: The origin and destination airports. For SFO departures, dep_iata will be SFO.
- Times: Scheduled and updated times for departure/arrival. Use these to compute delays, ETDs, and countdowns. Times are typically provided with local time context; normalize to UTC server-side to avoid drift when you aggregate across airports.
- Terminal and gate: Useful for passenger wayfinding. These fields can change late; favor the most recent value on every poll.
- Codeshares: Multiple marketing carriers may map to the same operating flight. Use flight_iata plus an operating identifier (if present) to deduplicate rows for your UI or to group codeshares.
Request SFO departures in code
The Python snippet below demonstrates how to call the schedules endpoint, filter for iataCode=SFO, and extract fields commonly shown on a departures board. Use the same endpoint and parameters as in the curl sample above, substituting iataCode=SFO and your access_key.
# pip install requests
import os
import time
import requests
from datetime import datetime, timezone
API_KEY = os.getenv("FLIGHTLABS_KEY", "YOUR_API_KEY")
# Use the exact schedules endpoint URL from the curl sample above.
# Replace the JFK-specific parameter in that URL with iataCode=SFO to fetch San Francisco departures.
API_URL = "PASTE_THE_SCHEDULES_ENDPOINT_URL_FROM_THE_CURL_SAMPLE_HERE"
def to_utc(iso_ts):
if not iso_ts:
return None
# Normalize any provided timestamp string to a Python UTC datetime for reliable comparisons
dt = datetime.fromisoformat(iso_ts.replace("Z", "+00:00"))
return dt.astimezone(timezone.utc)
def fetch_sfo_departures(page=1):
# Query parameters typically include your access_key and an airport filter.
# Ensure the filter targets SFO, e.g., iataCode=SFO.
params = {
"access_key": API_KEY,
"iataCode": "SFO",
"page": page # If pagination is supported, iterate pages until exhausted.
}
r = requests.get(API_URL, params=params, timeout=20)
r.raise_for_status()
data = r.json()
if not data or (isinstance(data, dict) and not data.get("success", True)):
# When success is false, log the error details and return an empty list
return [], {"success": False, "error": data}
return data, {"success": True}
def normalize_row(row):
# Field names below are illustrative based on the official sample shape.
# Always check keys against the JSON you receive.
flight = row.get("flight_iata") or row.get("flight")
status = row.get("status")
dep_airport = row.get("dep_iata")
arr_airport = row.get("arr_iata")
# Pull representative time fields (scheduled/estimated/actual) if present.
# Convert to UTC for consistent comparisons.
scheduled_dep = to_utc(row.get("dep_time") or row.get("departure_time"))
estimated_dep = to_utc(row.get("dep_time_estimated") or row.get("estimated_departure_time"))
actual_dep = to_utc(row.get("dep_time_actual") or row.get("actual_departure_time"))
terminal = row.get("dep_terminal") or row.get("terminal")
gate = row.get("dep_gate") or row.get("gate")
return {
"flight_iata": flight,
"status": status,
"dep_iata": dep_airport,
"arr_iata": arr_airport,
"scheduled_dep_utc": scheduled_dep.isoformat() if scheduled_dep else None,
"estimated_dep_utc": estimated_dep.isoformat() if estimated_dep else None,
"actual_dep_utc": actual_dep.isoformat() if actual_dep else None,
"terminal": terminal,
"gate": gate
}
def main():
departures, meta = fetch_sfo_departures(page=1)
if not meta["success"]:
print("API error:", meta.get("error"))
return
# Some responses are paginated; iterate pages if required.
rows = departures if isinstance(departures, list) else departures.get("data") or departures.get("results") or []
board = [normalize_row(r) for r in rows if isinstance(r, dict)]
# Example: print key fields for your departures board
for item in board:
print(
item["flight_iata"], item["status"], item["dep_iata"], "→", item["arr_iata"],
"T:", item["terminal"], "G:", item["gate"],
"ETD:", item["estimated_dep_utc"] or item["scheduled_dep_utc"]
)
if __name__ == "__main__":
main()
Notes on the example:
- Use the schedules endpoint and parameters exactly as shown in the curl sample. Swap the airport filter to iataCode=SFO.
- The normalizer anticipates typical keys found in schedules data. Keep it defensive: check for missing keys and nulls.
- Store flight_iata and status on each poll so you can compute diffs (e.g., status changed from scheduled → active, gate changed, ETD shifted).
Time zones, polling, caching, and reliability
Time zones: Flight times in schedules are anchored to local airport time; always convert to UTC on the backend. This prevents offset mistakes when you merge data from multiple airports or display to users in different time zones. Keep both local and UTC in your model if you render localized clocks.
Polling frequency: For a departures board, polling every 60–120 seconds is typical. Departure gates and times can change late; if you need near-live gate pushes, consider shorter intervals when a flight is within 2 hours of scheduled departure and longer intervals for flights further out.
Caching: Cache raw responses for a short TTL (e.g., 30–60 seconds) to protect your rate budget when multiple services read the same board. Diff against your last snapshot to emit events only when something important changes (status, terminal, gate, ETD).
Handling cancellations and diversions: If status indicates cancelled or diverted, ensure your UI conveys this clearly and stops showing countdowns. Diverted departures are rare but possible in complex operations; mark them distinctly and avoid conflating with delays.
Codeshares: If the response includes codeshare indicators, group them so you don’t show duplicate rows. Canonicalize to the operating carrier/flight if the data provides it; otherwise group all marketing identifiers that share the same aircraft movement window.
Filtering and pagination for SFO
Filtering: Use iataCode=SFO to limit the dataset to San Francisco departures. Depending on your use case, you may also filter by time windows or airline if those parameters are available in the endpoint. When in doubt, keep your initial pull simple (airport-only) and slice client-side by scheduled time.
Pagination: Schedules endpoints typically paginate when an airport has many flights. Inspect the response for pagination metadata or use an explicit page parameter. Iterate pages until no further data is returned. Merge all pages before you render to avoid chopping the board mid-page.
Sorting: After merging pages, sort by earliest estimated departure time (fallback to scheduled if estimated is missing). If a status implies the aircraft has pushed back or departed, pin it to the bottom or hide it according to your UX.
Error handling and edge cases
- success=false: Treat this as an operational error. Log the response payload, back off for a short interval, and retry. If you detect a persistent error, degrade gracefully by serving your last cached board and a banner stating it’s delayed.
- Missing values: Terminals and gates often start as null or change to null on operational rollbacks. Display placeholders (e.g., “TBD”) and avoid collapsing rows just because a field is temporarily unknown.
- Network timeouts: Set client timeouts and retries. Timeouts help keep your worker pool healthy during transient issues.
- Data freshness: Stamp each row with the time you received it. If your board lags beyond your SLA (for example, you haven’t refreshed in 10 minutes), display a subtle “Last updated at …” marker.
Go live checklist for SFO departures
1) Account and key
Start the 7‑day trial and copy your access_key from your dashboard: Register
2) Request SFO schedules
Use the schedules endpoint from the curl sample and set iataCode=SFO. Keep your key out of client-side code; proxy requests through your server.
3) Persist identifiers
Store flight_iata and status so you can detect changes across polls and send targeted updates to clients.
4) Build the board
Render rows with flight_iata, destination, status, scheduled and estimated departure times, terminal, and gate. If you need a quick sanity check while coding, read the SFO board with your trial key via: Register
Operational tips for production
- Normalize times to UTC on ingest, and store local times for display only.
- Use short polling windows for flights departing soon; back off for flights more than 6 hours out.
- Compute a delay metric from scheduled vs. estimated/actual times and surface it in your UI.
- De-duplicate codeshares so you don’t show multiple rows for one physical departure.
- Log every status transition per flight_iata for audits and customer support.
- Keep a small local cache keyed by flight_iata plus scheduled departure date to avoid duplicate notifications.
FAQ
How do I switch the official JFK sample to SFO?
Use the same endpoint as shown in the curl sample and change the airport filter to iataCode=SFO. The JSON fields are the same for SFO as in the JFK example.
Which fields should I persist to track changes?
At minimum, store flight_iata and status. If you need more precise diffs, also persist scheduled and estimated departure times, terminal, and gate.
What time zone are the schedule times in?
Treat schedule and estimate fields as local to the airport. Convert to UTC immediately on ingest for comparisons and aggregations, and keep the local string for user display.
How often should I poll for a live departures board?
A 60–120 second interval works well for most boards. Increase frequency for flights departing within two hours to catch late gate or ETD updates.
How do I handle cancelled or diverted flights?
Use status to detect cancellations or diversions. Mark cancelled flights clearly and stop countdowns; for diversions, show a distinct state and avoid treating them as standard delays.
Ready to pull SFO departures as JSON and ship your board? Start your 7‑day trial, get an API key, and make your first call today: Register. For parameter details and field references, visit the Documentation and try test queries in the MCP.