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
confirmedwith an emptytickets[]and a warning saying why. Readstatusandtickets[], 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-KeyAssigns 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"
}
}
]
}Path parameters
orderIDstringRequiredCanonical order ID.
Example:
AA001Y1XD7ZA6Request body
seatsarray<object>RequiredEach with
segment_id, passenger_id, and seat_id (or row + column).paymentobjectRequired on a ticketed order:
method, currency, amount, card.Error codes
400seats is required, a payment.card.… validation message, or payment.amount is less than the airline's price for these extras.409illegal_transition — the order can no longer be serviced.422extra_not_priced — the seat was not on the map this API served for the order.502The airline refused the assignment.
503coming_soon — order writes disabled.