Best API to Access Guangzhou Baiyun International Airport (CAN) Flights Schedules Data in 2025
You need dependable, developer-friendly access to departure and arrival schedules for a single, busy hub—Guangzhou Baiyun International Airport—so you can build boards, alerts, and planning tools that stay accurate throughout the day. By the end of this guide you’ll query FlightLabs’ schedules endpoint for CAN, parse the JSON you care about, group flights by hour, and understand how to handle time zones, pagination, and near‑term planning windows.
About Guangzhou Baiyun International Airport (CAN)
Guangzhou Baiyun International Airport serves Guangzhou, Guangdong, China. Its IATA code is CAN and its ICAO code is ZGGG. As a major gateway in southern China, developers often track CAN’s schedules to power airport displays, connection planning, cargo routing, and corporate travel dashboards.
Which FlightLabs endpoints matter for CAN schedules?
For departure and arrival schedules specifically, the core is the Flight Schedules endpoint. Depending on your product, you can pair it with real-time status or model-driven delay insights. Here is how these endpoints align by use case:
| Use case | Endpoint | What you get |
|---|---|---|
| Daily board for CAN (departures/arrivals) | Flight Schedules | Scheduled times, terminals, airline/flight metadata for planning and displays |
| Live updates and disruptions | Real-time Flight Tracking | Current status such as en-route and updated timing |
| Look ahead beyond static schedules | Future Flights | Forward-looking flight listings for planning windows |
| Risk scoring and alerting | Flight Delay Predictions | Signals to prioritize alerts when likelihood of delay increases |
We’ll anchor the rest of this guide on the schedules endpoint, and show how to keep it aligned with live status.
Getting CAN departures and arrivals: schedules endpoint
The schedules endpoint returns an array of flights with the fields your app will use for boards and planning. Authentication uses an API key. If you don’t have one yet, you can request it here: Get your FlightLabs API key.
Example: departures from CAN
This curl example shows how to call the schedules endpoint. Refer to the FlightLabs documentation for available filters to narrow by airport (CAN) and direction (departures):
curl -G "https://www.goflightlabs.com/flights-schedules" \
--data-urlencode "api_key=YOUR_API_KEY"
In your production code, apply the documentation’s query parameters to scope the response to CAN departures within your desired time window. The response structure below demonstrates the fields you’ll consume when the departure airport is CAN.
Example: arrivals into CAN
Arrivals use the same endpoint. Use the documentation’s filters to target arrivals into CAN:
curl -G "https://www.goflightlabs.com/flights-schedules" \
--data-urlencode "api_key=YOUR_API_KEY"
In both cases, you’ll receive an array of schedule objects. The next section shows a representative JSON payload that includes CAN in the relevant fields.
Sample schedules JSON for Guangzhou (illustrative values)
The following response is consistent with the documented schema for schedules. Field values are illustrative and demonstrate CAN both as a departure and as an arrival airport.
{
"success": true,
"data": {
"schedules": [
{
"flight_number": "CZ3101",
"departure": {
"airport": "CAN",
"scheduled": "2025-03-20T01:20:00Z",
"terminal": "2"
},
"arrival": {
"airport": "PEK",
"scheduled": "2025-03-20T03:55:00Z",
"terminal": "3"
},
"aircraft": {
"type": "Airbus A321",
"registration": "B-1234"
},
"airline": {
"name": "China Southern Airlines",
"iata": "CZ"
}
},
{
"flight_number": "HU7890",
"departure": {
"airport": "SHA",
"scheduled": "2025-03-20T02:10:00Z",
"terminal": "1"
},
"arrival": {
"airport": "CAN",
"scheduled": "2025-03-20T04:35:00Z",
"terminal": "2"
},
"aircraft": {
"type": "Boeing 737-800",
"registration": "B-5678"
},
"airline": {
"name": "Hainan Airlines",
"iata": "HU"
}
},
{
"flight_number": "CX382",
"departure": {
"airport": "HKG",
"scheduled": "2025-03-20T05:00:00Z",
"terminal": "1"
},
"arrival": {
"airport": "CAN",
"scheduled": "2025-03-20T06:10:00Z",
"terminal": "2"
},
"aircraft": {
"type": "Airbus A330-300",
"registration": "B-HLV"
},
"airline": {
"name": "Cathay Pacific",
"iata": "CX"
}
}
]
}
}
What to use in your app:
- flight_number: Display on boards and in alerts.
- departure.airport and arrival.airport: Filter to CAN; pair with city labels in your UI.
- departure.scheduled and arrival.scheduled: ISO 8601 with Z suffix; these are UTC.
- departure.terminal and arrival.terminal: Useful for terminal-level boards and wayfinding.
- airline.name and airline.iata: Show branding and enable filters by carrier.
- aircraft.type and aircraft.registration: Optional context for enthusiasts, ops teams, or equipment-planned services.
Note: Schedules do not include live status, gate changes, or delay durations. Use the real-time endpoint when you need state like en-route, estimated times, and position.
Code: group CAN flights by hour for boards and staffing
The snippet below fetches schedules, filters to CAN either as an origin or destination, and groups by the UTC hour of the scheduled time. You can adapt it to separate arrivals and departures into different columns.
/**
* Node.js example (requires node >=18 for fetch)
* Replace YOUR_API_KEY and apply the documentation's filters to scope to CAN and your time window.
*/
async function fetchSchedules() {
const url = new URL("https://www.goflightlabs.com/flights-schedules");
url.searchParams.set("api_key", "YOUR_API_KEY");
// Add filtering params per FlightLabs documentation to target CAN departures/arrivals and date window.
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
if (!json.success) throw new Error("API returned success=false");
return json.data.schedules || [];
}
// Group schedules by UTC hour (arrivals vs departures separated)
function groupByHour(schedules, kind = "departures") {
const isDeparture = (sch) => sch?.departure?.airport === "CAN";
const isArrival = (sch) => sch?.arrival?.airport === "CAN";
const pickTime = (sch) => {
if (kind === "departures" && isDeparture(sch)) return sch.departure.scheduled;
if (kind === "arrivals" && isArrival(sch)) return sch.arrival.scheduled;
return null;
};
const buckets = new Map();
for (const sch of schedules) {
const iso = pickTime(sch);
if (!iso) continue;
const d = new Date(iso); // ISO 8601 Z - interpreted as UTC by JS Date
const hourKey = d.toISOString().slice(0, 13) + ":00Z"; // e.g., 2025-03-20T04:00Z
if (!buckets.has(hourKey)) buckets.set(hourKey, []);
buckets.get(hourKey).push({
flight_number: sch.flight_number,
airline_iata: sch.airline?.iata,
airline_name: sch.airline?.name,
terminal: kind === "departures" ? sch.departure?.terminal : sch.arrival?.terminal,
from: sch.departure?.airport,
to: sch.arrival?.airport,
scheduled: iso
});
}
// Sort buckets chronologically and flights within each bucket
return Array.from(buckets.entries())
.sort(([a], [b]) => a.localeCompare(b))
.map(([hour, flights]) => ({
hour,
flights: flights.sort((x, y) => x.scheduled.localeCompare(y.scheduled))
}));
}
(async () => {
const schedules = await fetchSchedules();
const depByHour = groupByHour(schedules, "departures");
const arrByHour = groupByHour(schedules, "arrivals");
console.log("CAN departures grouped by hour:");
console.log(JSON.stringify(depByHour, null, 2));
console.log("CAN arrivals grouped by hour:");
console.log(JSON.stringify(arrByHour, null, 2));
})().catch(err => {
console.error(err);
process.exit(1);
});
How to think about polling, time zones, and caching
- Time standards: The schedules payload uses ISO 8601 with a trailing Z, which indicates UTC. Convert to Asia/Shanghai for end-user displays if needed, but store UTC to simplify comparisons and cross-airport workflows.
- Polling cadence: Schedules change less frequently than live status. For boards and staffing, a periodic refresh aligned to your operational window is typical. If you need frequent updates about delays or gate/terminal adjustments, complement schedules with the real-time endpoint and poll that on a short interval appropriate for your plan; maintain client-side caching to reduce redundant calls.
- Caching: Cache schedule pages per request signature. When you merge with real-time data, treat schedules as the base layer and overlay live changes; expire cache entries when you detect significant updates (e.g., terminal change) or at a fixed TTL.
Handling cancellations, diversions, and status changes
Raw schedules are a plan, not a live truth source. To detect cancellations, diversions, or rolling delays you should read the real-time endpoint and reconcile by flight_number and date. Typical flow:
- Load schedule set for CAN (departure- or arrival-scoped) for your window.
- For each scheduled flight within a near-term horizon (for example, the next few hours), query real-time details.
- If the live status indicates a material change, update the board: swap scheduled with estimated times, and annotate with status.
The real-time example schema includes flight.status and has separate departure.scheduled vs. actual and arrival.scheduled vs. estimated fields you can use for display logic.
Pagination and result windows
Schedules responses can be large for a hub like CAN. The API supports pagination. Use the documentation’s pagination fields and parameters to iterate through result pages deterministically and to avoid skipping items during refresh cycles. A common pattern is:
- Request page 1 for your time window and airport filter.
- Process and cache results with an index keyed by flight_number plus date.
- Advance through subsequent pages until no more results remain.
- On refresh, re-fetch from page 1 and diff against your cache to detect additions or updates.
How far ahead schedules are available depends on the data source and airline publishing cycles. For fixed planning windows beyond the immediate horizon, pair schedules with the Future Flights endpoint to pre-fetch CAN flights further in advance, then refresh closer to day-of-operation.
Use cases for CAN tied to the response fields
- Terminal-specific arrival boards: Use arrival.terminal and arrival.scheduled to mount screens by terminal at CAN. Filter to arrival.airport = CAN and sort by time.
- Departure delay monitoring: Combine departure.scheduled from schedules with live timestamps from the real-time endpoint (departure.actual or arrival.estimated) to calculate deltas; if the difference exceeds your SLA threshold, trigger alerts.
- Schedule sync to ops tools: Store flight_number, airline.iata, departure.airport, arrival.airport, and both scheduled timestamps to keep internal rosters, crew assignments, and gate planning aligned with CAN’s published plan. Refresh on a cadence, and reconcile with live status for exceptions.
Practical integration notes specific to CAN
- Airport codes: Always filter on the IATA code CAN for Guangzhou Baiyun International Airport. If your workflow uses ICAO, keep ZGGG in a lookup table but query with the IATA code when using fields named airport in schedules.
- Terminals: The schedules payload includes terminal values where available. Not all entries will have a terminal; build your UI to handle missing fields gracefully.
- Sorting: For departures from CAN, sort by departure.scheduled ascending; for arrivals into CAN, sort by arrival.scheduled. When you layer in live data, prefer actual/estimated times for ordering near real-time boards.
End-to-end workflow for a CAN schedules board
- Fetch schedules filtered to departures with departure.airport = CAN for your time window. Paginate until complete.
- Normalize timestamps to UTC internally; convert to Asia/Shanghai for display.
- Group by hour (as shown in the code) and render lists with flight_number, airline.iata, destination or origin, and terminal.
- For the next N hours, enrich the same flights via the real-time endpoint to surface status and live time adjustments.
- Refresh schedules periodically; update deltas in your cache, and re-render only changed rows to keep the UI smooth.
A balanced look at FlightLabs for this CAN use case
Technically, the schedules endpoint is straightforward to integrate: it returns compact JSON with the core fields you need for airport boards and planning tools, and it aligns cleanly with the real-time endpoint for operational truth. The separation between planned data (schedules) and actuals (real-time) helps you control polling costs and cache behavior. If you also need forecasting or looking further ahead, the Future Flights and Flight Delay Predictions endpoints slot in without changing the JSON you already parse.
From an integration perspective, key considerations include how you handle pagination at CAN’s scale, how you normalize time zones across your surfaces, and how you reconcile schedule rows with live state. Because the data is delivered over a simple REST interface with a single API key, you can deploy quickly across backend services and edge caches, then add targeted real-time polling only where it adds value (e.g., soon-to-depart flights).
Complete curl and field mapping recap
Use the schedules endpoint for CAN departures and arrivals (apply filtering parameters per the docs):
# Departures (apply filters to target CAN)
curl -G "https://www.goflightlabs.com/flights-schedules" \
--data-urlencode "api_key=YOUR_API_KEY"
# Arrivals (apply filters to target CAN)
curl -G "https://www.goflightlabs.com/flights-schedules" \
--data-urlencode "api_key=YOUR_API_KEY"
- Use departure.airport = CAN when building the departures view; use arrival.airport = CAN for arrivals.
- Use departure.scheduled and arrival.scheduled for board ordering; timestamps are UTC (Z).
- Use terminal values where present to direct passengers and staff to the correct area.
- Join with the real-time endpoint to add status and live time adjustments near departure/arrival.
Where to find parameters and filters
Filters, pagination controls, and optional fields are documented here: FlightLabs documentation. Use those details to scope by airport (CAN), flight direction, and time ranges, and to iterate through all pages reliably.
FAQ
How do I limit results to departures or arrivals for CAN?
Use the schedules endpoint with query parameters documented by FlightLabs to filter by airport code (CAN) and direction (departures vs. arrivals). The examples above show the response structure you will receive.
What timezone are schedule times in?
The sample schedule shows ISO 8601 timestamps with a Z suffix, which indicates UTC. Convert to local time (e.g., Asia/Shanghai) for end-user displays.
How should I handle cancellations or diversions?
Schedules are planned times. To show real status, query the real-time endpoint and replace or annotate scheduled times with actual/estimated fields, plus status.
Is there pagination for busy periods at CAN?
Yes. The schedules endpoint supports pagination. Consult the documentation for the specific parameters and iterate through all pages for your time window.
How often should I refresh?
Refresh schedules periodically based on your UI’s SLA and cache them. For near-term flights, poll the real-time endpoint more frequently to capture rolling updates.
Build your CAN schedules integration now. Review filters and pagination in the docs, then request credentials to start coding: Get your FlightLabs API key.