API quickstart

Integrate address-to-address direct-flight search into your own product with the AirportFusion REST API. This guide takes you from zero to your first successful request.

1. Create an account and an API key

  1. Sign up (or sign in) and open the Developer dashboard.
  2. Go to API keys → Create key, give it a name (e.g. "staging"), and pick a plan — the Free plan needs no payment details.
  3. Copy the key immediately: it is shown only once. We store just a hash of it.

Keys look like af_live_xxxxxxxx…. The first 12 characters (the prefix) stay visible in your dashboard so you can tell keys apart.

2. Authenticate

Send the key with every request, either as a Bearer token or an X-Api-Key header:

curl -H "Authorization: Bearer af_live_YOUR_KEY" \
  "https://your-airportfusion-host/api/v1/search?origin=Lyon&destination=Lisbon&originRadiusKm=100&destRadiusKm=150"

3. Your first search

GET /api/v1/search accepts:

| Parameter | Required | Description | | --- | --- | --- | | origin | yes | Address, city, landmark or lat,lon | | destination | yes | Same as origin | | originRadiusKm | yes | One of 50, 100, 150, 200, 300, 500, 1000 | | destRadiusKm | yes | Same options | | departureDate | no | YYYY-MM-DD, not in the past | | passengers | no | 1–9, default 1 | | locale | no | en, fr, es, zh — affects AI advice language |

4. Read the response

All endpoints return a consistent envelope:

{
  "ok": true,
  "data": {
    "searchId": "…",
    "origin": { "displayName": "Lyon, France", "lat": 45.76, "lon": 4.83 },
    "destination": { "displayName": "Lisboa, Portugal", "lat": 38.72, "lon": -9.14 },
    "originAirports": [ { "iata": "LYS", "distanceKm": 22.1 } ],
    "destinationAirports": [ { "iata": "LIS", "distanceKm": 6.9 } ],
    "routes": [
      {
        "id": "…",
        "flight": { "airlineCode": "TP", "estimatedDurationMinutes": 155, "estimatedPrice": 178.0 },
        "totals": { "estimatedCost": 214.5, "estimatedMinutes": 305, "currency": "EUR" },
        "score": 8.7
      }
    ],
    "meta": { "routeCount": 12, "durationMs": 840 }
  }
}

Errors use the same envelope with ok: false:

{ "ok": false, "error": { "code": "validation_error", "message": "originRadiusKm must be one of …" } }

5. Rate limits and quotas

Every response includes rate-limit headers:

  • X-RateLimit-Limit, X-RateLimit-Remaining — your per-minute window;
  • on 429, Retry-After tells you when to retry.

Monthly quotas reset on the 1st of each calendar month (UTC). Track live usage in the dashboard.

6. Error codes to handle

| HTTP | Code | Meaning | | --- | --- | --- | | 401 | invalid_api_key | Missing, revoked or malformed key | | 422 | validation_error | Bad parameters — details in error.details | | 429 | rate_limited | Per-minute limit hit — respect Retry-After | | 429 | quota_exceeded | Monthly quota exhausted — upgrade or wait | | 500 | internal_error | Our fault — safe to retry with backoff |

7. Good citizenship

  • Cache identical searches on your side for up to 24 hours.
  • Remember every value is an estimate — display it as such to your users.
  • Free/Starter/Pro integrations must show a "Powered by AirportFusion" attribution (see API Terms).

Questions? The developer support channel in your dashboard is the fastest way to reach us.