Live and bookable — pre-production, and no payment

These endpoints work against real American Airlines inventory: a search returns real offers and you can create a real booking with a carrier PNR. Two limits are worth knowing before you build against them.

  • Orders are pre-production. They are genuine reservations in the airline's pre-production system, not commercial tickets — nobody flies on them. Cancel what you create; anything left over expires on its own payment time limit.
  • Payment and ticketing cannot complete. An order is created as an unpaid hold, which is the normal agency flow, but ticketing is inhibited on this IATA number, so POST /v1/orders/{orderID}/commit returns 502. Everything up to and including the reservation works.
Shopping

Search offers (streaming)

The same search delivered progressively over Server-Sent Events — show offers as each airline answers.

POST/v1/shopping/offers/streamRequires X-API-Key
Identical request body, validation, caching, look-to-book accounting and rate limit as POST /v1/shopping/offers. The only difference is delivery: each connector's batch is pushed the moment it lands instead of waiting for the slowest airline.SSE rather than WebSockets because the stream is one-way, short-lived and rides on a plain HTTP response — so it passes through proxies and CDNs unchanged and inherits the same auth middleware.Event protocol, in order| Event | Payload | When |
|---|---|---|

| search | {"search_id":"srch_…","expires_at":"…"} | always first |

| offers | {"offers":[…]} | 0..n times, one per connector batch |

| done | {"total":115} | terminal, on success |

| error | {"error":"…"} | terminal, on failure |
Batches are not deduplicated across connectors — key on offer_id as you accumulate. A cache hit emits the whole result set as a single offers event, so your client code path is identical either way.Note: the "Try it" panel below renders the raw event stream as text rather than parsed JSON, because the response is text/event-stream, not application/json.

Request example

curl --request POST \
  --url https://api.norba.io/v1/shopping/offers/stream \
  --header "X-API-Key: $NORBA_KEY" \
  --header "Content-Type: application/json" \
  --data '{ "origin": "BCN", "destination": "JFK", "departure_date": "2026-10-20", "adults": 1, "cabin_class": "economy", "currency": "EUR", "max_stops": 0 }'

Response example

Response example
event: search
data: {"search_id":"srch_01K2M8ZC3AC5N8XWQ7R4YB","expires_at":"2026-08-14T10:14:52Z"}

event: offers
data: {"offers":[{"offer_id":"AA-X2E80EC16-…|X2E80EC16-…-1-1","airline":"AA","total_amount":380.62,"currency":"EUR"}]}

event: done
data: {"total":115}

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.

Request body

(same as POST /v1/shopping/offers)objectRequired
Byte-for-byte the same schema — origin, destination, departure_date, return_date, adults, children, infants, cabin_class, currency, max_stops, legs.
POST /v1/shopping/offers/stream — Search offers (streaming)