Sandbox: real offers, real PNRs, test tickets

In the sandbox these endpoints work against real carrier test inventory: a search returns real offers and you can create a real booking with a carrier PNR. Two things are worth knowing before you build against them.

  • Sandbox orders are test reservations. Nobody flies on them, and they raise no fee. Cancel what you create; anything left over expires on its own payment time limit.
  • Sandbox tickets are test documents. A paid order comes back ticketed with test ticket and EMD numbers in tickets[]; a hold comes back confirmed with none. Read status and tickets[], not the HTTP code — that is the check production relies on too.
Shopping

Offer seat map

Full seat map for an offer — rows, availability, price bands and decoded seat features.

GET/v1/offers/{offerID}/seatsRequires X-API-Key

Returns the airline's SeatAvailability for one offer as a canonical SeatMap, ready to drive an interactive seat picker. Pass segment_id to get the map of one flight of a multi-segment itinerary; the seats it returns carry that segment_id, which you repeat when buying.

The offer ID goes in the path and must be percent-encoded — same rule as the services endpoint. An order ID works here too when ?airline= is added (an order id has no AA- prefix to infer the carrier from): GET /v1/offers/AA001Y1XD7ZA6/seats?airline=AA. Prefer GET /v1/orders/{orderID}/seats, which is scoped to your agency.

A live BCN→JFK Boeing 777-200 map comes back as 24 rows, 240 seats, 190 available, across eight price bands from 23 to 145 EUR. Features are decoded to a stable vocabulary: accessible, aisle, bassinet, blocked, bulkhead, exit_row, extra_legroom, no_window, restricted_recline, window.

Buying a seat. Put the seat in the seats array of POST /v1/orders, alongside the flight. seat_id holds the human designator (17A); Norba resolves the seat's offer item from this map at booking time, so passing row, column and segment_id is enough.

After booking, use GET /v1/orders/{orderID}/seats and POST /v1/orders/{orderID}/seats instead: they are tenancy-scoped, price the seat from the order's own map, and pay for it where the booking is already ticketed. Assigning a paid seat to an existing order is still not available on every carrier — the airline's page says whether it is.

Results are cached per offer ID.

Request example

curl --request GET \
  --url https://api.norba.io/v1/offers/{offerID}/seats \
  --header "X-API-Key: $NORBA_KEY"

Response example

Response example
{
  "flight_id": "AA-P2E80EC16-51FD-48AD-924B-1",
  "airline": "AA",
  "aircraft": "772",
  "rows": 24,
  "seats": [
    {
      "seat_id": "17A",
      "row": 17,
      "column": "A",
      "cabin": "Economy",
      "available": true,
      "price": {
        "amount": 128.93,
        "currency": "EUR"
      },
      "features": [
        "window",
        "extra_legroom"
      ],
      "segment_id": "SGM010012275a20c"
    },
    {
      "seat_id": "17B",
      "row": 17,
      "column": "B",
      "cabin": "Economy",
      "available": false,
      "price": {
        "amount": 0,
        "currency": "EUR"
      },
      "features": [
        "blocked"
      ],
      "segment_id": "SGM010012275a20c"
    }
  ]
}

Authorization

X-API-KeystringRequired

Opaque API key issued from the Norba dashboard. Sent on every request as the X-API-Key HTTP header. Missing or invalid keys are rejected with 401 Unauthorized.

Path parameters

offerIDstringRequired

Canonical offer ID or order ID. Percent-encode it.

Example: AA-P2E80EC16-51FD-48AD-924B-1|P2E80EC16-51FD-48AD-924B-1-1

Query parameters

airlinestring

IATA code. Inferred from the ID prefix when omitted.

Example: AA

Response fields

flight_idstringRequired

Flight or offer reference the map belongs to.

airlinestringRequired

IATA airline code.

aircraftstring

Aircraft type code, e.g. 772.

rowsintegerRequired

Number of rows in the map.

seats[].seat_idstringRequired

Human seat designator, e.g. 17A.

seats[].rowintegerRequired

Row number.

seats[].columnstringRequired

Column letter.

seats[].cabinstring

Cabin name.

seats[].availablebooleanRequired

Whether the seat can be selected.

seats[].priceobject

{amount, currency} — 0 when free.

seats[].featuresarray<string>

accessible, aisle, bassinet, blocked, bulkhead, exit_row, extra_legroom, no_window, restricted_recline, window.

seats[].segment_idstringRequired

The segment this seat is on. Required when you buy the seat.

Error codes

400

unknown airline — no recognisable prefix and no ?airline=.

502

The airline rejected the reference.

GET /v1/offers/{offerID}/seats — Offer seat map | Norba API