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
ticketedwith test ticket and EMD numbers intickets[]; a hold comes backconfirmedwith none. Readstatusandtickets[], not the HTTP code — that is the check production relies on too.
Refund order
Cancel the order and mark it refunded. Returns 202 Accepted.
/v1/orders/{orderID}/refundRequires X-API-KeyCancels the order at the airline where it is still open, records the local status as refunded, and answers **202 Accepted** with {order_id, status, refund_amount, penalty_amount, currency}.
The amounts are the airline's quote immediately before the cancellation — the same figures GET /v1/orders/{orderID}/refund-eligibility reports — asked for at that moment because a closed order cannot be quoted afterwards. They are recorded in the order's timeline (refunded event) so the figure the traveller was told and the figure the carrier settles can be compared later. When the quote fails the refund still proceeds and the amounts are simply omitted.
Norba moves no money. On every carrier connected here the cancellation IS the refund: the connector accepts the airline's cancel offer, which undoes the documents, and the airline returns the fare less its penalty to the original form of payment on its own settlement cycle. Reconcile the actual amount with the airline or your BSP settlement. Only a ticketed, partially cancelled, disrupted or already-cancelled order can be refunded; a hold has nothing to give back and is 409.
Idempotency. Send an Idempotency-Key (up to 128 characters) and keep it across retries, as on every write: a repeat returns the recorded answer. A key still in flight, or another write still running on the order (409 order_busy), answers 409 with Retry-After. A refusal from the airline is 422 airline_refused; a refund that never reached the airline is 503 airline_unreachable with Retry-After.
Takes no request body. ?airline= is optional: the airline comes from your stored order, not from this parameter. A value that disagrees with the persisted carrier is refused with 400 airline does not match the order.
Request example
curl --request POST \
--url https://api.norba.io/v1/orders/{orderID}/refund \
--header "X-API-Key: $NORBA_KEY"Response example
{
"order_id": "AA001Y1XD7ZA6",
"status": "refunded",
"refund_amount": 355.62,
"penalty_amount": 25,
"currency": "EUR"
}Path parameters
orderIDstringRequiredCanonical order ID.
AA001Y1XD7ZA6Query parameters
airlinestringIATA code. Optional — inferred from your stored order. A value that disagrees with the persisted carrier is refused with 400 airline does not match the order.
AAError codes
400airline does not match the order — only returned when a supplied ?airline= disagrees with the persisted carrier; omitting it is fine.
409illegal_transition — a hold, a pending or a failed order cannot be refunded; order_busy or idempotency_key_in_flight (with Retry-After); idempotency_key_reused; or refund_outcome_unknown (code, with attempt_id).
422airline_refused — the airline rejected the cancellation behind the refund.
502Only with code: "refund_outcome_unknown", attempt_id and Retry-After: the refund reached the airline and its answer was lost — read the order back with ?refresh=true before sending it again.
503coming_soon — order writes disabled; or airline_unreachable with Retry-After — nothing reached the airline.