Best API to Access Singapore Changi Airport (SIN) Flights Schedules Data in 2025
You need dependable departure and arrival schedules for Singapore Changi Airport so you can power boards, send timely alerts, and keep your apps in sync. By the end of this guide you’ll query the FlightLabs schedules endpoint for Singapore Changi (IATA: SIN, ICAO: WSSS), parse the JSON, group results by hour, and combine schedules with live status when you need it.
Why focus on Singapore Changi (SIN)
Singapore Changi Airport (IATA: SIN, ICAO: WSSS) is a major international hub located in the Changi area of Singapore. Developers track SIN to support connection-heavy itineraries, global logistics operations, and passenger-facing experiences where accurate gate, terminal, and timing data matter.
Endpoints you’ll use for SIN schedules and status
FlightLabs exposes multiple endpoints that work together for planning and operations around an airport like SIN. Below is a technical comparison to help you choose the right calls for your use case.
| Endpoint | Primary purpose | Key fields you’ll rely on | When to use for SIN |
|---|---|---|---|
| Flight Schedules | Planned departure/arrival times, terminals | data.schedules[].flight_number, departure.scheduled, arrival.scheduled, departure.terminal, arrival.terminal, airline, aircraft | Build daily boards, sync near-future schedules, plan gates/turns |
| Real-time Flight Tracking | Live status and estimates | data.flight.status, departure.actual, arrival.estimated, terminals, gates, position | Overlay status on schedules, handle delays, diversions, cancellations |
| Future Flights | Upcoming planned operations | Similar to schedules (high-level planning fields) | Capacity planning and forecasting beyond the current day |
| Flight Delay Predictions | Predictive insights | Prediction/analytics fields (varies by model) | Proactive notifications before delays materialize |
| Flight History | Historical operations | Past status and timing fields | Post-op analytics and SLA reporting for SIN routes |
How to call the schedules endpoint for SIN
The schedules endpoint returns structured JSON with planned times and basic flight context. Authentication uses an API key. If you’re not yet set up, create your key here: Register. Refer to parameter options in the Documentation.
Arrivals into SIN (example cURL)
The following shows a complete request to the schedules endpoint. Values in the JSON are illustrative and focus on arrivals where arrival.airport is SIN.
curl -s "https://www.goflightlabs.com/flights-schedules?api_key=YOUR_API_KEY"
{
"success": true,
"data": {
"schedules": [
{
"flight_number": "SQ321",
"departure": {
"airport": "LHR",
"scheduled": "2025-03-10T21:10:00Z",
"terminal": "2"
},
"arrival": {
"airport": "SIN",
"scheduled": "2025-03-11T17:55:00Z",
"terminal": "3"
},
"aircraft": {
"type": "Airbus A350-900",
"registration": "9V-SMF"
},
"airline": {
"name": "Singapore Airlines",
"iata": "SQ"
}
},
{
"flight_number": "TR7",
"departure": {
"airport": "SYD",
"scheduled": "2025-03-11T02:00:00Z",
"terminal": "1"
},
"arrival": {
"airport": "SIN",
"scheduled": "2025-03-11T08:00:00Z",
"terminal": "1"
},
"aircraft": {
"type": "Airbus A321neo",
"registration": "9V-NCB"
},
"airline": {
"name": "Scoot",
"iata": "TR"
}
}
]
}
}
What to use: arrival.airport to ensure SIN, arrival.scheduled for the UTC arrival time, arrival.terminal for passenger flow and signage, plus airline and flight_number for display labels. Times are ISO 8601 in UTC (“Z”). Convert to Asia/Singapore for local boards.
Departures from SIN (example cURL)
This request targets the same endpoint. The example JSON highlights departures where departure.airport is SIN.
curl -s "https://www.goflightlabs.com/flights-schedules?api_key=YOUR_API_KEY"
{
"success": true,
"data": {
"schedules": [
{
"flight_number": "SQ942",
"departure": {
"airport": "SIN",
"scheduled": "2025-03-11T01:40:00Z",
"terminal": "2"
},
"arrival": {
"airport": "DPS",
"scheduled": "2025-03-11T04:25:00Z",
"terminal": "I"
},
"aircraft": {
"type": "Boeing 787-10",
"registration": "9V-SCA"
},
"airline": {
"name": "Singapore Airlines",
"iata": "SQ"
}
},
{
"flight_number": "TR384",
"departure": {
"airport": "SIN",
"scheduled": "2025-03-11T03:15:00Z",
"terminal": "1"
},
"arrival": {
"airport": "BKK",
"scheduled": "2025-03-11T04:40:00Z",
"terminal": "1"
},
"aircraft": {
"type": "Airbus A320",
"registration": "9V-TAZ"
},
"airline": {
"name": "Scoot",
"iata": "TR"
}
}
]
}
}
What to use: departure.airport to match SIN, departure.scheduled to drive gate calls, departure.terminal for signage and curbside routing, and arrival.airport for downstream connection logic.
Key fields in schedules and how they map to real use
The schedules payload is intentionally concise so you can render it quickly and enrich later if needed.
- flight_number: The unique flight designator you’ll show on boards and join with real-time status.
- departure.scheduled / arrival.scheduled: ISO 8601 UTC; convert to Asia/Singapore when presenting locally.
- departure.terminal / arrival.terminal: Use to segment signage by terminal or route rideshare traffic.
- airline.name and airline.iata: For airline branding and filter controls in your UI.
- aircraft.type and registration: Useful for equipment notifications and operational planning.
Combining SIN schedules with live status (cancellations, diversions, gates)
Schedules show plan; real-time shows reality. Join scheduled flights with the real-time endpoint using the flight number and airline code for live status, actual and estimated times, and gate detail.
{
"success": true,
"data": {
"flight": {
"iata": "SQ942",
"icao": "SIA942",
"number": "942",
"status": "en-route",
"departure": {
"airport": "SIN",
"scheduled": "2025-03-11T01:40:00Z",
"actual": "2025-03-11T01:48:00Z",
"terminal": "2",
"gate": "E7"
},
"arrival": {
"airport": "DPS",
"scheduled": "2025-03-11T04:25:00Z",
"estimated": "2025-03-11T04:33:00Z",
"terminal": "I",
"gate": "—"
},
"position": {
"latitude": -6.1,
"longitude": 106.7,
"altitude": 36000,
"speed": 470,
"heading": 110
}
}
}
}
What to use: status for cancellation/diversion logic, departure.actual and arrival.estimated for live countdowns, and terminal/gate pairs for wayfinding. If a flight is cancelled or diverted, the status field will reflect that so you can suppress it on boards or trigger alerts.
Grouping SIN flights by hour (JavaScript example)
This sample fetches schedules and groups them by the hour of departure or arrival. It filters client-side for SIN and handles UTC-to-local conversions. Adapt this in your app to generate hourly boards.
async function fetchSchedules() {
const url = "https://www.goflightlabs.com/flights-schedules?api_key=YOUR_API_KEY";
const res = await fetch(url);
if (!res.ok) throw new Error("Failed to fetch schedules");
const json = await res.json();
return (json.data && json.data.schedules) || [];
}
// Group an array of schedule items by hour using a getter for the timestamp field
function groupByHour(items, getIso) {
const groups = {};
for (const it of items) {
const iso = getIso(it);
if (!iso) continue;
const d = new Date(iso); // ISO 8601 UTC input
const key = d.toISOString().slice(0, 13) + ":00Z"; // normalize to UTC hour
if (!groups[key]) groups[key] = [];
groups[key].push(it);
}
return groups;
}
(async () => {
const schedules = await fetchSchedules();
// Filter arrivals into SIN
const sinArrivals = schedules.filter(s => s.arrival && s.arrival.airport === "SIN");
// Filter departures from SIN
const sinDepartures = schedules.filter(s => s.departure && s.departure.airport === "SIN");
// Group by hour based on scheduled time
const arrivalsByHour = groupByHour(sinArrivals, s => s.arrival && s.arrival.scheduled);
const departuresByHour = groupByHour(sinDepartures, s => s.departure && s.departure.scheduled);
// Example: render a compact board
for (const [hour, flights] of Object.entries(arrivalsByHour)) {
console.log("Arrivals hour (UTC):", hour, "count:", flights.length);
for (const f of flights) {
console.log(
`${f.flight_number} ${f.airline?.iata || ""} from ${f.departure?.airport} ` +
`arr ${f.arrival?.scheduled} T${f.arrival?.terminal || "-"}`
);
}
}
for (const [hour, flights] of Object.entries(departuresByHour)) {
console.log("Departures hour (UTC):", hour, "count:", flights.length);
for (const f of flights) {
console.log(
`${f.flight_number} ${f.airline?.iata || ""} to ${f.arrival?.airport} ` +
`dep ${f.departure?.scheduled} T${f.departure?.terminal || "-"}`
);
}
}
})().catch(console.error);
Note: The schedules payload doesn’t carry a real-time status field. For live boards, join each flight with the real-time endpoint to determine status and update ETAs/ETDs.
Additional JSON examples you’ll likely need
Airport information (SIN)
Use this to resolve timezone and terminal context once per session, then cache.
{
"success": true,
"data": {
"airport": {
"iata": "SIN",
"icao": "WSSS",
"name": "Singapore Changi Airport",
"location": {
"lat": 1.3644,
"lon": 103.9915,
"city": "Singapore",
"country": "Singapore"
},
"timezone": "Asia/Singapore",
"terminals": [
"1",
"2",
"3",
"4"
],
"runways": [
{
"length_ft": 13123,
"width_ft": 197,
"surface": "asphalt",
"designator": "02L/20R"
}
],
"weather": {
"temp_c": 30,
"visibility_km": 10,
"wind": {
"speed_kts": 8,
"direction_deg": 120
}
}
}
}
}
Another SIN arrivals schedules example
{
"success": true,
"data": {
"schedules": [
{
"flight_number": "CX635",
"departure": {
"airport": "HKG",
"scheduled": "2025-03-11T02:25:00Z",
"terminal": "1"
},
"arrival": {
"airport": "SIN",
"scheduled": "2025-03-11T06:15:00Z",
"terminal": "1"
},
"aircraft": {
"type": "Airbus A330-300",
"registration": "B-LAJ"
},
"airline": {
"name": "Cathay Pacific",
"iata": "CX"
}
}
]
}
}
Another SIN departures schedules example
{
"success": true,
"data": {
"schedules": [
{
"flight_number": "SQ26",
"departure": {
"airport": "SIN",
"scheduled": "2025-03-11T23:55:00Z",
"terminal": "3"
},
"arrival": {
"airport": "FRA",
"scheduled": "2025-03-12T05:55:00Z",
"terminal": "1"
},
"aircraft": {
"type": "Boeing 777-300ER",
"registration": "9V-SWJ"
},
"airline": {
"name": "Singapore Airlines",
"iata": "SQ"
}
}
]
}
}
Practical tips: time zones, polling, caching, and pagination
- Time zones: All sample times shown in schedules and real-time are ISO 8601 with Z (UTC). For local boards at SIN, convert to Asia/Singapore. For connections, normalize both legs to UTC first to avoid DST edge cases at origin/destination.
- Polling strategy: Schedules change less frequently than live status. A common pattern is to refresh schedules periodically (e.g., every 15–30 minutes during operational hours) and poll the real-time endpoint more frequently for flights in the next 3–4 hours. Adjust cadence to your application’s SLA.
- Caching: Cache airport info (timezone, terminals) daily. Cache schedules at the hour granularity; bust cache for a given flight when real-time status indicates a significant change (delay, gate change, cancellation).
- Handling cancellations/diversions: Schedules do not include status. Use real-time’s status field and estimated/actual times to override scheduled boards and send alerts. If status indicates “cancelled,” remove or mark the flight prominently; if “diverted,” annotate the new arrival airport.
- Pagination: The schedules dataset can be large for a hub like SIN. Consult the Documentation for the current pagination scheme and iterate through pages when building a complete daily board. In batch jobs, persist a page cursor or offset to resume safely.
- How far ahead: Availability windows vary. For planning beyond the current horizon, complement schedules with the Future Flights endpoint.
Three SIN-specific use cases you can ship now
1) Arrival boards for Terminal 1 vs. Terminal 3
Use arrival.airport === "SIN" to filter, then group by arrival.terminal. Display arrival.scheduled (local time) and airline/flight_number. For operational screens, add real-time arrival.estimated to reflect current timing.
2) Delay alerts and gate change notifications
For departures where departure.airport === "SIN", fetch live status and compare departure.actual vs departure.scheduled. If the difference crosses your threshold, push a user alert. When real-time indicates a new gate (departure.gate), notify subscribed passengers or ground staff immediately.
3) Schedule sync for connection planning
Combine schedules for inbound flights to SIN with outbound departures to compute minimum connection windows. Use arrival.scheduled of inbound and departure.scheduled of outbound in UTC, and enrich with airline and terminal values to prioritize same-terminal connections.
Operational checklist for a robust SIN integration
- Normalize all times to UTC internally; render in Asia/Singapore for SIN-facing UIs.
- Join schedules to real-time by flight_number and airline.iata (or by the iata/icao fields from real-time) to obtain status and gate fields.
- Cache airport metadata for SIN (timezone, terminals) and schedule pages. Evict cache on status change.
- Implement graceful empty states if a page has no schedules (overnight lulls) or if a flight is cancelled.
- Log and retry transient errors; backoff on polling loops to respect quotas and reduce duplicate work.
Testing the integration with SIN examples
When validating your app logic, start with a small time slice and verify formatting and grouping, then expand.
- Call schedules and filter for arrival.airport === "SIN".
- Group by hour and render two consecutive hours to test pagination and grouping.
- Pick one flight_number and fetch real-time to verify the join and status overlay.
- Toggle your clock to confirm UTC/local rendering is correct for late-night rollovers.
Environment and tooling links
- Create your API key: Register
- Explore request/response options: Documentation
- Manage keys, quotas, and logs: MCP
FAQ
How do I get only flights for SIN without over-fetching?
Use the schedules endpoint and apply the appropriate filters described in the Documentation. If you can’t filter server-side in your environment, fetch a constrained time window and filter client-side by departure.airport or arrival.airport equal to "SIN".
What time zone are the schedule timestamps in?
The examples show ISO 8601 UTC (Z). Convert to Asia/Singapore when rendering locally. Keep UTC in storage and for calculations (e.g., connection checks).
How do I detect cancellations or diversions?
Join the schedules result with the real-time endpoint using flight_number and airline identifiers. The real-time payload’s status field reflects cancellations and diversions and includes actual/estimated times and gate updates.
How frequently should I poll?
Poll the schedules endpoint less frequently (e.g., every 15–30 minutes during operating hours) and poll the real-time endpoint more frequently for flights departing or arriving within the next few hours. Apply backoff and caching to reduce load.
How far into the future can I see SIN flights?
Consult the Documentation for the current schedule horizon. For planning beyond that window, combine with the Future Flights endpoint.
Ready to build your SIN departure and arrival boards, alerts, and planning tools? Create your key and start querying: Register. For request options and field details, keep the Documentation open as you code.