Airports API and database
9,095 airports with IATA and ICAO codes, type, country and coordinates, free to use as an API (JSON, GeoJSON, vector tiles) or as a CSV download. Public domain. Copy it into your own project to add lounges, photos or descriptions and serve it from your own API.
Builds your app on your own copy of the Airports dataset, with Spatibase as the backend
Help me build an app on a copy of the free Airports dataset from Spatibase (a CMS and API for places), with Spatibase as the app's backend.
Read the guide first: https://spatibase.com/agents/quickstart.md
Below, "spatibase ..." means "npx --yes spatibase@0.1 ..." (Node 18.3 or newer).
The dataset
- Airports: https://spatibase.com/datasets/airports/
- A shared, read-only public copy, no key needed. Look at it first: https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries?limit=3
- Its typed OpenAPI file: https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/openapi.json
- Fields (the keys under "fields" in an entry; the title is the entry's own title):
- title (text): Airport name, for example Václav Havel Airport Prague
- ident (identifier): OurAirports identifier, unique; mostly the ICAO code, for example LKPR
- iata_code (text): IATA code (3 letters); empty for airports without one, for example PRG
- icao_code (text): ICAO code (4 characters); may be empty, for example LKPR
- gps_code (text): GPS code, for example LKPR
- local_code (text): Code used locally
- airport_type (choice): large_airport, medium_airport, small_airport or seaplane_base, for example large_airport
- scheduled_service (boolean): Has scheduled airline service, for example true
- elevation_ft (number): Elevation in feet, for example 1247
- continent (choice): AF, AN, AS, EU, NA, OC or SA, for example EU
- country_code (text): ISO 3166-1 alpha-2 country code, for example CZ
- country (text): Country name, for example Czechia
- region_code (text): ISO 3166-2 region code, for example CZ-10
- region (text): Region name, for example Praha
- municipality (text): Town or city served, for example Prague
- website (link): Airport website, for example https://www.prg.aero/
- wikipedia (link): Wikipedia article, for example https://en.wikipedia.org/wiki/Václav_Havel_Airport_Prague
- Licence: Public domain (https://ourairports.com/data/#data-license). No attribution required; a credit is appreciated.
- Good to know about the data: Not for navigation. Provided as is, without warranty. Do not use it for flight planning or anything safety-critical.
1. Ask me what the app is for, unless it is stated under "What to build" at the end. Ask whether I want every airport or only some: one value of a filter field (for example continent = EU) or an area (bbox: minLng,minLat,maxLng,maxLat). A temporary project holds 1,000 entries, so choose a filter or area that fits.
2. Show me a short report and wait for my OK: what you will import and how many entries match (a dry run tells you), the fields of my own you would add, the app you would build and the files it touches, and that the data will be public but unlisted and deleted after 24 hours unless I keep it.
3. Create a temporary project: spatibase create "<app name>" --ref dataset-airports
Import the dataset into it, a dry run first: spatibase call import_dataset '{"dataset":"airports","filter":{"field":"continent","value":"EU"},"dryRun":true}'
Read the counts, then run it again with "dryRun":false. The entries arrive as drafts. spatibase call list_datasets names the fields you can filter by.
4. Add my own fields and data: spatibase describe shows the imported type and its apiKey; write a small model file in .spatibase/ and run spatibase model <file> (it adds missing fields to the existing type); import my own rows if I have a file (spatibase import <file> --type <apiKey> --publish). Then spatibase publish and spatibase verify.
5. Build the app on my project's Content Delivery API: the address that create printed (it ends in /delivery/v1/projects/<my project id>, not the public copy's id) and its typed OpenAPI file at <address>/openapi.json. Generate types from that file, never guess field names, keep loading and error states, and show a credit to OurAirports (appreciated, not required).
6. Ask for my email and run spatibase keep <email>, so I can keep the project (it is deleted after 24 hours otherwise).
Finish with the live API URL, how many entries were imported and with which filter, what you built and when the project expires.Live from the endpoints below. Zoom in and click an airport. Snapshot of October 22, 2026.
Copy-paste endpoints
Public, no API key, CORS open to any origin. Open one in your browser.
JSONPaged entries with all fields. Up to 500 per page.
GeoJSONFeatureCollection of points; up to 5,000 per request.
TileJSONVector tiles (layer entries) for MapLibre, Mapbox GL and QGIS.
OpenAPIThis dataset’s typed OpenAPI 3.1 document, for generated clients.
Filters
Combine them freely. near takes longitude,latitude and radius in metres; add sort=distance to order by distance. All query parameters
Code samples
Look up an airport, or draw them all on your own map.
Look up an airport by its IATA code
curl "https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries?filter[iata_code]=PRG"const res = await fetch('https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries?filter[iata_code]=PRG')
const { data } = await res.json()
console.log(data[0].title, data[0].fields.icao_code)import requests
r = requests.get("https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries", params={"filter[iata_code]": "PRG"})
airport = r.json()["data"][0]
print(airport["title"], airport["fields"]["icao_code"])Show the airports on your map
map.addSource('airports', { type: 'vector', url: 'https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/tiles.json' })
map.addLayer({
id: 'airports',
type: 'circle',
source: 'airports',
'source-layer': 'entries',
paint: { 'circle-radius': 4, 'circle-color': '#3b82f6' },
})map.addSource('airports', { type: 'geojson', data: 'https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries.geojson?filter[airport_type]=large_airport&limit=5000' })
map.addLayer({ id: 'airports', type: 'circle', source: 'airports', paint: { 'circle-radius': 4 } })fetch('https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries.geojson?filter[airport_type]=large_airport&limit=5000')
.then((r) => r.json())
.then((data) => L.geoJSON(data, {
onEachFeature: (f, layer) => layer.bindPopup(f.properties.title),
}).addTo(map))Build an app on the airports with your coding agent
Paste one prompt into Claude Code, Codex or Cursor. It already knows the fields, the filters and the licence.
Your own copyThe agent makes a temporary Spatibase project, imports the airports you choose (all of them, or one country or area), adds your own fields, builds the app on its API and asks for your email so you can keep it. No account needed to start.
Help me build an app on a copy of the free Airports dataset from Spatibase (a CMS and API for places), with Spatibase as the app's backend.
Read the guide first: https://spatibase.com/agents/quickstart.md
Below, "spatibase ..." means "npx --yes spatibase@0.1 ..." (Node 18.3 or newer).
The dataset
- Airports: https://spatibase.com/datasets/airports/
- A shared, read-only public copy, no key needed. Look at it first: https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/entries?limit=3
- Its typed OpenAPI file: https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/openapi.json
- Fields (the keys under "fields" in an entry; the title is the entry's own title):
- title (text): Airport name, for example Václav Havel Airport Prague
- ident (identifier): OurAirports identifier, unique; mostly the ICAO code, for example LKPR
- iata_code (text): IATA code (3 letters); empty for airports without one, for example PRG
- icao_code (text): ICAO code (4 characters); may be empty, for example LKPR
- gps_code (text): GPS code, for example LKPR
- local_code (text): Code used locally
- airport_type (choice): large_airport, medium_airport, small_airport or seaplane_base, for example large_airport
- scheduled_service (boolean): Has scheduled airline service, for example true
- elevation_ft (number): Elevation in feet, for example 1247
- continent (choice): AF, AN, AS, EU, NA, OC or SA, for example EU
- country_code (text): ISO 3166-1 alpha-2 country code, for example CZ
- country (text): Country name, for example Czechia
- region_code (text): ISO 3166-2 region code, for example CZ-10
- region (text): Region name, for example Praha
- municipality (text): Town or city served, for example Prague
- website (link): Airport website, for example https://www.prg.aero/
- wikipedia (link): Wikipedia article, for example https://en.wikipedia.org/wiki/Václav_Havel_Airport_Prague
- Licence: Public domain (https://ourairports.com/data/#data-license). No attribution required; a credit is appreciated.
- Good to know about the data: Not for navigation. Provided as is, without warranty. Do not use it for flight planning or anything safety-critical.
1. Ask me what the app is for, unless it is stated under "What to build" at the end. Ask whether I want every airport or only some: one value of a filter field (for example continent = EU) or an area (bbox: minLng,minLat,maxLng,maxLat). A temporary project holds 1,000 entries, so choose a filter or area that fits.
2. Show me a short report and wait for my OK: what you will import and how many entries match (a dry run tells you), the fields of my own you would add, the app you would build and the files it touches, and that the data will be public but unlisted and deleted after 24 hours unless I keep it.
3. Create a temporary project: spatibase create "<app name>" --ref dataset-airports
Import the dataset into it, a dry run first: spatibase call import_dataset '{"dataset":"airports","filter":{"field":"continent","value":"EU"},"dryRun":true}'
Read the counts, then run it again with "dryRun":false. The entries arrive as drafts. spatibase call list_datasets names the fields you can filter by.
4. Add my own fields and data: spatibase describe shows the imported type and its apiKey; write a small model file in .spatibase/ and run spatibase model <file> (it adds missing fields to the existing type); import my own rows if I have a file (spatibase import <file> --type <apiKey> --publish). Then spatibase publish and spatibase verify.
5. Build the app on my project's Content Delivery API: the address that create printed (it ends in /delivery/v1/projects/<my project id>, not the public copy's id) and its typed OpenAPI file at <address>/openapi.json. Generate types from that file, never guess field names, keep loading and error states, and show a credit to OurAirports (appreciated, not required).
6. Ask for my email and run spatibase keep <email>, so I can keep the project (it is deleted after 24 hours otherwise).
Finish with the live API URL, how many entries were imported and with which filter, what you built and when the project expires.Quick prototypeThe agent builds a read-only prototype straight on the public API above. Nothing to set up and nothing to keep; copy the dataset into your own project when you want to add data.
I am building an app on the free Airports dataset from Spatibase. Use the Spatibase Content Delivery API as the data source. It is read-only and returns published content only.
Project
- Project id: f7f53b91-4e86-4a73-9f50-70f4bff43652
- API base URL: https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652
- Access: public. No key is needed, and the API can be called straight from the browser.
The dataset
- Airports, a free public dataset: https://spatibase.com/datasets/airports/
- Licence: Public domain (https://ourairports.com/data/#data-license). No attribution required; a credit is appreciated.
- Good to know about the data: Not for navigation. Provided as is, without warranty. Do not use it for flight planning or anything safety-critical.
- Fields (the keys under "fields" in an entry):
- title (text): Airport name, for example Václav Havel Airport Prague
- ident (identifier): OurAirports identifier, unique; mostly the ICAO code, for example LKPR
- iata_code (text): IATA code (3 letters); empty for airports without one, for example PRG
- icao_code (text): ICAO code (4 characters); may be empty, for example LKPR
- gps_code (text): GPS code, for example LKPR
- local_code (text): Code used locally
- airport_type (choice): large_airport, medium_airport, small_airport or seaplane_base, for example large_airport
- scheduled_service (boolean): Has scheduled airline service, for example true
- elevation_ft (number): Elevation in feet, for example 1247
- continent (choice): AF, AN, AS, EU, NA, OC or SA, for example EU
- country_code (text): ISO 3166-1 alpha-2 country code, for example CZ
- country (text): Country name, for example Czechia
- region_code (text): ISO 3166-2 region code, for example CZ-10
- region (text): Region name, for example Praha
- municipality (text): Town or city served, for example Prague
- website (link): Airport website, for example https://www.prg.aero/
- wikipedia (link): Wikipedia article, for example https://en.wikipedia.org/wiki/Václav_Havel_Airport_Prague
- Filters that work here, for example: filter[continent]=EU, filter[iata_code]=PRG, filter[airport_type]=large_airport, near=<lng>,<lat>&radius=<metres>&sort=distance, bbox=<minLng>,<minLat>,<maxLng>,<maxLat>, q=<name search>
- This public copy is shared and read-only. To add my own data or fields, or for a busy app, I copy it into my own project: https://app.spatibase.com/signup?dataset=airports&ref=ds-airports
Read these first
- This project's typed OpenAPI file, with my real field names and types: https://api.spatibase.com/delivery/v1/projects/f7f53b91-4e86-4a73-9f50-70f4bff43652/openapi.json
- The general OpenAPI file of the API: https://api.spatibase.com/delivery/v1/openapi.json
- The docs, written for AI agents: https://spatibase.com/llms.txt (every docs page is also Markdown, for example https://spatibase.com/docs/reference/delivery-api.md)
Generate TypeScript types or a typed client from the typed OpenAPI file before writing app code. Take field names from it, never guess them.
Endpoints (all GET, relative to the base URL)
- /entries: entries as JSON, paged (limit up to 500). Filters: type, group, q (title search), filter[<field>]=value or filter[<field>][<op>]=value (eq, ne, gt, gte, lt, lte, in, contains, exists), bbox, near + radius (meters), sort (for example title, -publishedAt, distance), include=references
- /entries.geojson: the same entries and filters as a GeoJSON FeatureCollection (up to 5000)
- /entries/<entryId>: one entry
- /tiles.json: TileJSON for vector tiles (tiles at /tiles/{z}/{x}/{y}.pbf, one layer "entries"; filters type, subtypes, group)
- /types, /groups, /groups/<groupKey> (entries in the order I arranged them), /feature-types
Good to know
- An entry has id, type, title, geometry (GeoJSON, can be null) and fields keyed by each field's API key.
- Image URLs are absolute; add ?w=800&fmt=webp to get a resized image.
- Responses are cacheable (ETag and 304; about a minute in the browser, up to five minutes at the CDN). CORS is open. Errors look like { "error": { "code", "message" } }.
- For maps, use MapLibre GL JS with the vector tiles or the GeoJSON, or Leaflet with the GeoJSON.
- Regenerate the types when I tell you I changed my content model.Plain text for agents: your own copy, quick prototype. How it works
What is in each airport
Every airport is one entry with a point location. Field names are the keys in the API (under fields) and the CSV columns.
| Field | Kind | Meaning | Example |
|---|---|---|---|
title | text | Airport name | Václav Havel Airport Prague |
ident | identifier | OurAirports identifier, unique; mostly the ICAO code | LKPR |
iata_code | text | IATA code (3 letters); empty for airports without one | PRG |
icao_code | text | ICAO code (4 characters); may be empty | LKPR |
gps_code | text | GPS code | LKPR |
local_code | text | Code used locally | |
airport_type | choice | large_airport, medium_airport, small_airport or seaplane_base | large_airport |
scheduled_service | boolean | Has scheduled airline service | true |
elevation_ft | number | Elevation in feet | 1247 |
continent | choice | AF, AN, AS, EU, NA, OC or SA | EU |
country_code | text | ISO 3166-1 alpha-2 country code | CZ |
country | text | Country name | Czechia |
region_code | text | ISO 3166-2 region code | CZ-10 |
region | text | Region name | Praha |
municipality | text | Town or city served | Prague |
website | link | Airport website | https://www.prg.aero/ |
wikipedia | link | Wikipedia article | https://en.wikipedia.org/wiki/Václav_Havel_Airport_Prague |
Download the whole dataset
Static snapshot files, for spreadsheets, QGIS or your own database.
- airports.csv (1.7 MB)One row per airport, latitude and longitude columns included. Opens in Excel, Google Sheets, QGIS.
- airports.geojson (4.5 MB)RFC 7946 FeatureCollection of points, every field as a property. Loads in MapLibre, Leaflet, QGIS, geopandas.
Open the files in our free tools: Map from Excel or CSV, CSV to GeoJSON converter, GeoJSON validator
Public domain, from OurAirports
- Source
- OurAirports: airports.csv, countries.csv and regions.csv
- Licence
- Public domain. No attribution required; a credit is appreciated.
- Snapshot
- October 22, 2026. Not updated live.
- Use
- Not for navigation. Provided as is, without warranty. Do not use it for flight planning or anything safety-critical.
Copy it and make it yours
The API above is read-only. A copy is yours to change.
Your own project. The dataset lands in your account as a normal project with the airport type, all fields and every airport, already published.
Your own API. You get your own endpoints (JSON, GeoJSON, vector tiles, OpenAPI) on your project id, and API keys if you want it private.
Add what the dataset lacks. Add fields such as lounge information, photos, terminal maps, a description or opening hours, and fill them in the editor.
Edit and publish. Fix a name, hide an airport, add your own. Only what you publish reaches your API.
Free to copy. Copying costs nothing and nothing you change affects the public dataset or anyone else’s copy.
Questions about the airports API
Is the airports API free?
Yes. The endpoints on this page are public, need no API key and cost nothing. The data is public domain, so you can also download the CSV or GeoJSON and host it yourself. If you copy it into your own Spatibase project, the copy is free too; your own project follows the normal plan limits.
How many airports are in the dataset, and which ones?
9,095 airports: every OurAirports record that is not closed, is a large, medium or small airport or a seaplane base, and either has an IATA code or has scheduled airline service. Heliports, balloon ports and closed airfields are left out. The full OurAirports list also holds tens of thousands of small airstrips; this is the part people look up codes for.
How often is it updated?
It is a snapshot taken on October 22, 2026, not a live feed. Airports open, close and change codes slowly, but if you need today’s state, check the source at OurAirports. The snapshot date is also in the page’s structured data and in meta.json next to the downloads.
Does it include flights, schedules or runways?
No. It is reference data: codes, names, type, location, country and region, website. There is no flight, delay or airline data, and it is not for navigation: do not use it for flight planning or any safety-critical purpose.
Can I use it commercially?
Yes. OurAirports releases its data into the public domain, so there is no attribution requirement and no restriction on commercial use. A credit to OurAirports is still appreciated. The data comes without any warranty.
What are the rate limits and how is it cached?
Responses are cacheable (ETag and conditional requests, CORS open to any origin), so a browser or CDN in front of it rarely hits the server twice. There is no published request quota for this public dataset, but it is shared by everyone: for a busy app, copy it into your own project (or download the file) so your traffic is your own.
How is this different from api-ninjas, airportdb.io or AirLabs?
Those are hosted lookups behind an API key, usually with a request cap. Here the data is public domain and you can take it with you: download it, or copy it into a Spatibase project of your own where you can add fields such as lounge info, photos or descriptions and serve everything from your own API, with your own URL. It is a content API, not a flight-data service.
What does “Copy into your account” do?
It creates a new project in your Spatibase account with the airport type, all fields and all airports, already published. You get your own API URL, can edit entries in the editor, add elements to the airport type and publish your changes. Nothing you change touches the public dataset.