Sandbox orders are test bookings

Sandbox keys reach the airlines’ test systems: nobody flies on these orders and no booking fee is charged. Check status and tickets[], not the HTTP code.

Servicing

Add extras to an order

Buy bags, meals or other ancillaries against an existing booking, at the airline's price.

POST/v1/orders/{orderID}/servicesRequires X-API-Key

Adds extras to an order. Each entry names a service_id from GET /v1/orders/{orderID}/services as ancillary_offer_id, and the passenger. The price is the catalogue's; an extra not listed there is 422 extra_not_priced.

  • On an unpaid hold, the extras are added and paid with the fare.
  • On a ticketed order, send a payment covering the extras, in the order's currency.
  • A cancelled, refunded or failed order is 409 illegal_transition.

Returns the updated Order. Idempotency. Idempotency-Key is required when a payment is sent (400 idempotency_key_required without it) and works as on POST /v1/orders. Another write still running on the order is 409 order_busy (Retry-After: 5). A refusal from the airline is 422; 503 airline_unreachable means nothing was sent (retry with the same key); 502 extras_outcome_unknown means the answer was lost: do not resend.

Request example

curl --request POST \
  --url https://api.norba.io/v1/orders/{orderID}/services \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Idempotency-Key: 3f2b8c1e-6d4a-4e9b-9a57-0c1d2e3f4a5b" \
  --header "Content-Type: application/json" \
  --data '{ "ancillaries": [ { "ancillary_offer_id": "AA-SVC…|ITEM…", "passenger_id": "PAX96101" } ], "payment": { "method": "CARD", "currency": "EUR", "amount": 45.00, "card": { "number": "4111111111111111", "holder": "AGENCY TRAVEL SL", "expiry_month": 11, "expiry_year": 2029 } } }'

Response example

Response example
{
  "order_id": "AA001Y1XD7ZA6",
  "status": "ticketed",
  "total_amount": 425.62,
  "ancillaries": [
    {
      "ancillary_offer_id": "AA-SVC…|ITEM…",
      "type": "bag_checked",
      "name": "1st checked bag",
      "price_amount": 45,
      "currency": "EUR",
      "passenger_id": "PAX96101"
    }
  ]
}

Authorization

X-API-KeystringRequired

Your API key from the dashboard. A missing or invalid key answers 401; see Authentication.

Path parameters

orderIDstringRequired

Canonical order ID.

Example: AA001Y1XD7ZA6

Request body

ancillariesarray<object>Required

Each with ancillary_offer_id (the service_id shown), passenger_id (the order's passenger id), optional segment_ids.

paymentobject

Required on a ticketed order: card, amount, currency, as on POST /v1/orders.

Error codes

400

idempotency_key_required, payment_method_not_allowed, ancillaries is required, payment.amount is less than the airline's price for these extras, payment.currency must be …, the currency of this order, or another validation message.

404

order_not_found — not this account's order in this key's environment.

409

illegal_transition, order_busy, idempotency_key_in_flight, idempotency_key_reused, or extras_outcome_unknown (with attempt_id: do not buy again).

422

extra_not_priced, hold_expired, or airline_refused.

502

extras_outcome_unknown with attempt_id: the answer was lost. Do not resend.

503

airline_unreachable or ledger_unavailable (Retry-After: 5, nothing was sent), or coming_soon.

POST /v1/orders/{orderID}/services — Add extras to an order