Skip to content
FX-Port/Docs
GuidesAPI referenceChangelog
Get API keys
  • Introduction
  • Quickstart
  • Security
  • Authentication
  • Environments and Postman
  • Sandbox
  • Conventions and naming
  • Legacy names and twins
  • Errors
  • Rate limits and fair use
  • Streaming search results
  • Use these docs with AI

Get started

Sandbox

How the sandbox works, the limits of the suppliers' own test systems and what to expect while testing.

Sandbox keys (fxp_test_...) connect to the test systems of our suppliers: Amadeus test, Duffel test, the hotel supplier's test contract and the eSIM supplier's sandbox. Nothing you do with a sandbox key moves your real balance, and sandbox data is kept apart from live data: a sandbox key never sees a live booking and the other way round.

The suppliers' test systems are not under FX-Port's control. They can have short outages, and some routes, airlines or hotels fail during pricing or booking in the sandbox although they work on live. When one supplier fails, the answer of FX-Port still arrives and the entry of that supplier says success: false. Wait and retry, or try another route.

What the sandbox does

BehaviourDetail
No balance debitFinancial operations are skipped: bookings do not charge your balance and GET /balances has nothing to show.
Real data structures, test faresFlight offers have the shape of live offers but come from test systems. Not every route exists.
Same limits as liveThe rate limits are the same, so load tests belong on a schedule, not in a loop.
No webhooksFX-Port does not call a URL of yours, in the sandbox or on live. Poll the booking: get booking for flights, booking detail for everything else.
environment everywhereEvery JSON body says "environment": "sandbox" and every response has the X-Environment: sandbox header.

GET /balances answers an envelope with an empty list, not a bare array:

{
  "environment": "sandbox",
  "success": true,
  "data": [],
  "meta": {
    "agencyId": "00000000-0000-0000-0000-000000000000",
    "environment": "sandbox",
    "financialOperationsEnabled": false,
    "message": "Sandbox bookings do not debit live balances; no sandbox balance ledger is exposed."
  }
}

Flights

The sandbox has two flight suppliers (see Suppliers):

SupplierRoutesNotes
duffel_1WorldwideInstant ticketing only. Duffel allows one booking per search: to book a second offer, search again (a second booking on the same search fails with offer_request_already_booked). Offers are randomised and expire: an offer that searched fine can be gone when you price it, so search again.
amadeus_aqc_dz_1Routes that touch AlgeriaSupports hold and same-day void. Some airlines or routes reject at the booking step even though they were in the results: try another route (for example ALG → ORN) or another offer. The cheapest holds fail more often than the others.

To test an ACD booking, see ACD documents: CDG → ALG on amadeus_aqc_dz_1 returns offers with ACD pricing.

Set send_email to false on bookings while you test, so no message goes to the address you typed.

Hotels

In the sandbox you can search and price any hotel, but you can only book the supplier's test hotels. Booking a random hotel does not work: pre_book answers 409 hotel_not_bookable_in_sandbox and lists the test hotels (before 2026-11-01 it answered 200 with an empty booking form, and book_hotel then failed with order_not_found). Use test_hotel_do_not_book (works with every residency) or test_hotel (works only with residency dz, ru or us), and cancel every booking you make: sandbox hotel bookings are real orders on a supplier test contract.

See Hotel sandbox testing for the ids, a copy-paste script that books and cancels a test hotel, the date rules and the known quirks.

eSIMs

  • A sandbox order really provisions an eSIM on the supplier's sandbox, with a dummy LPA string and a QR code image hosted by the sandbox.
  • Order and top-up answers carry three flags that make the "no money moved" rule visible: balanceDebited, transactionCreated and payoutCreated (twins balance_debited, transaction_created, payout_created), all false.
  • Usage is static: a sandbox eSIM reports ACTIVE with its full allowance and the figures do not move.
  • A sandbox top-up works end to end and shows a balance of 0.0.
  • Sandbox bookings appear in your history and booking detail like any other.

Testing checklist

Before you switch to live keys, verify in the sandbox:

  1. Search: your request is accepted and returns offers. Try one bad input on purpose (a wrong airport code) and check that you handle the error.
  2. Price: re-pricing an offer works and the pricing fields are what you expect.
  3. Book (issue): the instant booking completes and returns a PNR and an e-ticket.
  4. Book (hold): a hold on amadeus_aqc_dz_1 creates a reservation with status: awaiting_payment.
  5. Pay: pay_order with the order_id of the hold succeeds.
  6. Get booking: get_booking returns the booking, and bucket_link (the PDF) once it exists.
  7. Cancel a hold: cancel_order releases an unpaid held PNR. Voiding or refunding an issued ticket, exchanges and re-issues stay manual support operations (Duffel orders can use the self-service cancel quote).
  8. Hotels: run the whole flow on test_hotel_do_not_book and cancel it.
  9. eSIMs: order a package, read its instructions and usage, top it up.
  10. Failure paths: a read-only key on a write endpoint (403), an unknown id (404), a missing field (400), and a retry after a 429.
PreviousEnvironments and PostmanNext Conventions and naming

On this page

  • What the sandbox does
  • Flights
  • Hotels
  • eSIMs
  • Testing checklist

© 2026 FX-Port

TermsPrivacy[email protected]