Quickstart

Authenticate, search every connected airline, price an offer and book it.

Open
N-109
010203041 · SearchPOST /v1/shopping/offers2 · PricePOST /v1/offers/price3 · BookPOST /v1/orders4 · Pay · ticketedPOST /v1/orders/{id}/commit

One JSON API over HTTPS for every connected airline. No SDK needed: use any HTTP client.

Base URL: https://api.norba.io/v1


Authentication

Send your API key in the X-API-Key header on every request.

Getting Your API Key

  1. Sign up at norba.io
  2. Go to Dashboard → API Keys
  3. Click Create API Key
  4. Store it as a secret

Set Up the Client

curl --request GET \
  --url https://api.norba.io/v1/monitoring/airlines \
  --header "X-API-Key: $NORBA_KEY"

Key format: nbr_live_ prefix for production, nbr_test_ for the sandbox. New accounts start in the sandbox; production keys follow an approved go-live request. Restrictions and rotation: Authentication.


Key Concepts

  • Aviation Data — Airports, airlines, route networks and aircraft types.
  • Environments — A sandbox key reaches the airlines' test systems, a production key the live ones.
  • Orders — Bookings held at the airline, paid now or later.
  • Servicing — Seats, extras, changes, cancellations and refunds, each quoted first.
  • Shopping — Search returns offers that expire. Nothing is reserved.
  • Webhooks — Signed events when an order changes.

Step 1: Get Your API Key

Sign up, then create a sandbox key in the dashboard.

Step 2: Search for Flights

One request returns offers from every connected airline that serves the route, cheapest first.

curl --request POST \
  --url https://api.norba.io/v1/shopping/offers \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "origin": "LHR",
    "destination": "JFK",
    "departure_date": "2027-06-15",
    "adults": 1,
    "max_stops": 0
  }'

Save the offer_id value — you'll need it for the next step.

Which airlines answer

Every connected airline that serves the route is asked; there is no per-request carrier filter. meta.airlines lists who answered. The airlines available today are on Airline Integrations.

Step 3: Price the Offer

Pricing confirms the fare and returns a new offer_id. Book that one; a search offer ID is refused.

cURL
curl --request POST \
  --url https://api.norba.io/v1/offers/price \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "offer_ids": ["AA-X2E80EC16-51FD-48AD-924B.1-1|X2E80EC16-51FD-48AD-924B.1-1-1"],
    "airline": "AA"
  }'

Book before price_guaranteed_until passes.

Step 4: Create Your First Order

Send the priced offer ID with passengers and contact. You get back the order and the airline's PNR (passenger name record).

curl --request POST \
  --url https://api.norba.io/v1/orders \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: booking-7f3c2a" \
  --data '{
    "offer_id": "AA-P2E80EC16-51FD-48AD-924B-1|P2E80EC16-51FD-48AD-924B-1-1",
    "airline": "AA",
    "passengers": [
      {
        "id": "T1",
        "type": "ADT",
        "first_name": "JOHN",
        "last_name": "DOE",
        "date_of_birth": "1985-04-12",
        "gender": "M",
        "document": {
          "type": "P",
          "number": "XDA123456",
          "issuing_country": "GB",
          "expiry_date": "2032-05-30",
          "nationality": "GB"
        }
      }
    ],
    "contact": { "email": "john@example.com", "phone": "447700900123" }
  }'

Save the order_id and use the passenger IDs the order returns in later calls; they may differ from the ones you sent.

Holds and Payment

Without payment the order is an unpaid hold: confirmed until expires_at. Pay it with POST /v1/orders/{orderID}/commit.

cURL
curl --request POST \
  --url "https://api.norba.io/v1/orders/AA001Y1XD7ZA6/commit" \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Idempotency-Key: pay-AA001Y1XD7ZA6-1" \
  --header "Content-Type: application/json" \
  --data '{
    "payment": {
      "method": "CARD",
      "currency": "EUR",
      "amount": 380.62,
      "card": {
        "number": "4111111111111111",
        "holder": "JOHN DOE",
        "expiry_month": 11,
        "expiry_year": 2030,
        "cvv": "123",
        "brand": "VISA"
      }
    }
  }'
Before you go live
  • A ticket exists only once tickets[] is non-empty: check it, not the HTTP code. Sandbox tickets are test documents.
  • Writes that pay, cancel or refund need an Idempotency-Key (else 400 idempotency_key_required). Reuse it on retries.

What's Next?

Norba API Docs — Flight Search & Booking in One REST API