Skip to main content

Get Airports - Lấy Danh Sách Sân Bay

API Endpoint: GET /api/v1/current/airports


📋 Overview

Lấy danh sách tất cả sân bay khả dụng để user chọn điểm đi/điểm đến.

Use Case:

  • Populate dropdown "Từ" (departure airport)
  • Populate dropdown "Đến" (arrival airport)
  • Search/filter airports by name or code

Result: 6,073 airports worldwide


🔌 API Specification

Endpoint

GET {{base_url}}/api/v1/current/airports

Headers

{
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer {access_token}"
}

Query Parameters

ParameterTypeRequiredDefaultDescription
pagenumber1Page number for pagination
limitnumber9999Number of items per page
qstring-Search by name or code (e.g., "Hanoi", "SGN")
departurestring-Filter by departure capability
airlinesstring[]-Filter by airline codes (e.g., ["VJ"])

Examples:

# Get all airports (recommended for initial load)
GET /api/v1/current/airports?page=1&limit=9999

# Search airports
GET /api/v1/current/airports?q=Hanoi&limit=10

# Filter by airline
GET /api/v1/current/airports?airlines=VJ&limit=9999

✅ Success Response

Status: 200 OK

{
"data": [
{
"id": "77e71f43-bb75-4e48-b6e6-0ce087359919",
"type": "airport",
"attributes": {
"id": "77e71f43-bb75-4e48-b6e6-0ce087359919",
"name": "Tan Son Nhat International Airport",
"code": "SGN",
"iata": "SGN",
"icao": "VVTS",
"domestic": true,
"active": true,
"iso_name": "Tan Son Nhat International Airport",
"city": "Ho Chi Minh City",
"country_name": "Vietnam",
"lat": 10.8188,
"lon": 106.6519,
"timezone": "7",
"tz": "Asia/Ho_Chi_Minh",
"airport_type": "airport",
"order_index": 0,
"search_count": 0,
"country": {}
}
},
{
"id": "31ba2fc7-d1dd-4373-a482-4dedd77e7852",
"type": "airport",
"attributes": {
"id": "31ba2fc7-d1dd-4373-a482-4dedd77e7852",
"name": "Noi Bai International Airport",
"code": "HAN",
"iata": "HAN",
"icao": "VVNB",
"domestic": true,
"active": true,
"iso_name": "Noi Bai International Airport",
"city": "Hanoi",
"country_name": "Vietnam",
"lat": 21.2212,
"lon": 105.8072,
"timezone": "7",
"tz": "Asia/Ho_Chi_Minh",
"airport_type": "airport",
"order_index": 0,
"search_count": 0,
"country": {}
}
}
]
}

Response Fields:

FieldTypeDescription
dataarrayArray of airport objects
data[].idstringUUID của airport
data[].typestringLuôn là "airport"
data[].attributesobjectAirport details

Attributes Object:

FieldTypeDescriptionExample
idstringAirport UUID"77e71f43-bb75..."
namestringTên đầy đủ"Tan Son Nhat International Airport"
codestringAirport code (IATA)"SGN"
iatastringIATA code"SGN"
icaostringICAO code"VVTS"
domesticbooleanSân bay nội địatrue
activebooleanĐang hoạt độngtrue
iso_namestringISO name"Tan Son Nhat..."
citystringThành phố"Ho Chi Minh City"
country_namestringQuốc gia"Vietnam"
latnumberLatitude10.8188
lonnumberLongitude106.6519
timezonestringUTC offset"7"
tzstringTimezone"Asia/Ho_Chi_Minh"
airport_typestringLoại"airport"
order_indexnumberThứ tự sắp xếp0
search_countnumberSố lần tìm kiếm0

💡 Example: cURL

curl -X GET "{{base_url}}/api/v1/current/airports?page=1&limit=9999" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"

🔍 Usage Examples

Example 1: Get All Airports (Initial Load)

// Get all airports for dropdown
const airports = await getAirports(accessToken);

// Build dropdown options
const options = airports.map((airport) => ({
value: airport.attributes.code,
label: `${airport.attributes.city} (${airport.attributes.code})`,
name: airport.attributes.name,
}));

Output:

[
{ value: "SGN", label: "Ho Chi Minh City (SGN)", name: "Tan Son Nhat..." },
{ value: "HAN", label: "Hanoi (HAN)", name: "Noi Bai International..." },
{ value: "DAD", label: "Da Nang (DAD)", name: "Da Nang International..." },
// ... 6,070 more
];

Example 2: Search Airports

# Search by city name
curl "{{base_url}}/api/v1/current/airports?q=Hanoi&limit=10" \
-H "Authorization: Bearer {token}"

Response: Returns airports matching "Hanoi" (HAN, etc.)


Example 3: Filter Vietnam Domestic

const vietnamDomestic = airports.filter(
(a) =>
a.attributes.country_name === "Vietnam" && a.attributes.domestic === true,
);

console.log("Vietnam domestic airports:", vietnamDomestic.length);
// Output: ~22 airports (SGN, HAN, DAD, CXR, VCA, etc.)

CodeCityNameType
SGNHo Chi MinhTan Son Nhat InternationalDomestic
HANHanoiNoi Bai InternationalDomestic
DADDa NangDa Nang InternationalDomestic
CXRCam Ranh (Nha Trang)Cam Ranh InternationalDomestic
VCACan ThoCan Tho InternationalDomestic
HPHHai PhongCat Bi InternationalDomestic
VIIVinhVinh AirportDomestic
HUIHuePhu Bai InternationalDomestic
UIHQuy NhonPhu Cat AirportDomestic
VDOVan DonVan Don InternationalDomestic
DLIDa LatLien Khuong AirportDomestic
PQCPhu QuocPhu Quoc InternationalDomestic

🎯 Integration Flow

Step 1: Load Airports on App Start

// On app initialization
const airports = await getAirports(accessToken);
localStorage.setItem("airports", JSON.stringify(airports));

Step 2: User Selects Route

// User selects
const departure = "SGN"; // From dropdown
const arrival = "HAN"; // From dropdown

Step 3: Search Flights

// Use selected codes to search
await searchFlights({
diem_di: departure,
diem_den: arrival,
ngay_di: "01-11-2025",
nguoi_lon: 1,
});

⚠️ Important Notes

1. Response Format is JSON:API

{
"data": [
{
"id": "uuid",
"type": "airport", // ← JSON:API format
"attributes": { // ← Data is in attributes
"code": "SGN",
"name": "...",
...
}
}
]
}

Access data:

airport.attributes.code; // ✅ Correct
airport.code; // ❌ Wrong (undefined)

2. Filter Active Airports

const activeAirports = airports.filter((a) => a.attributes.active === true);

3. Domestic vs International

// Vietnam domestic only
const domestic = airports.filter(
(a) =>
a.attributes.country_name === "Vietnam" && a.attributes.domestic === true,
);

// International
const international = airports.filter((a) => a.attributes.domestic === false);

4. Code Usage

For flight search, use attributes.code:

{
"diem_di": airport.attributes.code, // "SGN"
"diem_den": airport.attributes.code // "HAN"
}

🐛 Troubleshooting

❌ Empty Response

Cause: Missing or invalid Authorization token

Solution:

// Ensure token is valid
const response = await getAirports(accessToken);
if (!response.data || response.data.length === 0) {
// Re-authenticate
accessToken = await authenticate();
response = await getAirports(accessToken);
}

❌ "Cannot read property 'code' of undefined"

Cause: Accessing airport.code instead of airport.attributes.code

Solution:

// ❌ Wrong
const code = airport.code;

// ✅ Correct
const code = airport.attributes.code;

📖 Frontend Integration Example

React Component

import { useEffect, useState } from 'react';
import { Select } from 'antd';

interface Airport {
id: string;
type: string;
attributes: {
code: string;
name: string;
city: string;
country_name: string;
};
}

function AirportSelector() {
const [airports, setAirports] = useState<Airport[]>([]);
const [loading, setLoading] = useState(false);

useEffect(() => {
loadAirports();
}, []);

async function loadAirports() {
setLoading(true);
const response = await fetch(
'{{base_url}}/api/v1/current/airports?page=1&limit=9999',
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);

const data = await response.json();
setAirports(data.data || []);
setLoading(false);
}

const options = airports.map(airport => ({
value: airport.attributes.code,
label: `${airport.attributes.city} (${airport.attributes.code})`
}));

return (
<Select
showSearch
loading={loading}
options={options}
placeholder="Chọn sân bay"
filterOption={(input, option) =>
option.label.toLowerCase().includes(input.toLowerCase())
}
/>
);
}

🔗 Next Steps

After getting airports, proceed to search flights:

// 1. Get airports
const airports = await getAirports(accessToken);

// 2. User selects SGN → HAN

// 3. Search flights
await searchFlights({
diem_di: "SGN",
diem_den: "HAN",
ngay_di: "01-11-2025",
nguoi_lon: 1,
tre_em: 0,
em_be: 0,
});

See next doc: 02-SEARCH-FLIGHTS.md


📝 Notes

  • Response chuẩn JSON:API format
  • 6,073+ airports worldwide (Vietnam + International)
  • Supports search, filter, pagination
  • Data hiếm khi thay đổi → có thể cache
  • Response size ~2.5MB → nên cache ở client
  • Vietnam domestic: ~22 airports