Sandbox: real offers, real PNRs, no 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 orders are never ticketed. A paid order comes back confirmed with an empty tickets[] and a warning saying why. Read status and tickets[], not the HTTP code — that is the check production relies on too.
Servicing

Assign seats on an order

Give each traveller a seat from the map, paying for it where the booking is already ticketed.

POST/v1/orders/{orderID}/seatsRequires X-API-Key
Assigns seats on an existing booking. Each seat names its segment_id, the passenger (passenger_id, the order's id for them), and either the designator (seat_id: "17A") or its row and column; it is priced from the map GET /v1/orders/{orderID}/seats served, and a seat that map did not show is 422 extra_not_priced.Payment follows the booking's state, as for services: none on a hold (settled at issuance), required on a ticketed order and floored at the catalogue price of the seats (400 when short).The response is the updated canonical Order, persisted, with seats[] as the airline now holds them; the timeline records seats_assigned.> Not every carrier allows a paid seat to be added after booking — the airline's own page says whether it does. A refusal comes back as the airline's (502) with the order untouched; sell seats inside POST /v1/orders on those carriers.

Request example

curl --request POST \
  --url https://api.norba.io/v1/orders/{orderID}/seats \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Content-Type: application/json" \
  --data '{ "seats": [ { "seat_id": "17A", "segment_id": "SEG-2", "passenger_id": "PAX96101" } ] }'

Response example

Response example
{
  "order_id": "AA001Y1XD7ZA6",
  "status": "confirmed",
  "seats": [
    {
      "seat_id": "17A",
      "row": 17,
      "column": "A",
      "segment_id": "SEG-2",
      "passenger_id": "PAX96101",
      "price": {
        "amount": 23,
        "currency": "EUR"
      }
    }
  ]
}

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

orderIDstringRequired
Canonical order ID.
Example: AA001Y1XD7ZA6

Request body

seatsarray<object>Required
Each with segment_id, passenger_id, and seat_id (or row + column).
paymentobject
Required on a ticketed order: method, currency, amount, card.

Error codes

400
seats is required, a payment.card.… validation message, or payment.amount is less than the airline's price for these extras.
409
illegal_transition — the order can no longer be serviced.
422
extra_not_priced — the seat was not on the map this API served for the order.
502
The airline refused the assignment.
503
coming_soon — order writes disabled.
POST /v1/orders/{orderID}/seats — Assign seats on an order