Changelog
What changed in the FX-Port API and in these docs, newest first.
New entries are added at the top. A change that could break an integration ships under a new API version (the / prefix) and is announced here first; additive changes, such as a new field or a new accepted spelling, do not change the version. See Conventions and naming.
2026-11-01: new documentation, one naming convention, clearer errors, safer defaults
Nothing was removed. Every endpoint, request field and response key that worked yesterday works today. The changes below add names, add keys, tell you what to use, and refuse requests that could never have succeeded.
Documentation
- The documentation moved from
docs.fx-port.comto fx-port.com/docs. Every old address redirects permanently to its new one, so links, bookmarks and search results keep working. - A generated API reference with every endpoint, its parameters, its responses and examples in nine languages, an OpenAPI 3.1 file at /openapi.json, llms.txt and llms-full.txt for AI tools, every page as Markdown (add
.mdto its address), and search. - The Postman collections were regenerated from the same description of the API: see Environments and Postman.
- The navigation is grouped by product (Flights, Hotels, eSIMs, Account), each with its stages, in the guides and in the API reference. The hotel search around a point is called geo search everywhere.
- New guides: Quickstart, Conventions and naming, Legacy names and twins, Errors, Rate limits and fair use, Streaming search results, Mini and full hotel data and the guides of get_ticket_number, cancel_quote and confirm_cancel.
- The flights, hotels and eSIMs guides were rewritten against the live API: corrected claims, real responses, the sandbox test hotels, and the ACD passport uploads reference.
Naming: one convention, the old names still work
snake_caseis the canonical spelling of every request field. A request that uses an earlier spelling (searchId,offerId,bookingType,hotelId,checkinDate,partnerOrderId...) is still served. The response then carries awarningsentry and the headersDeprecation,LinkandX-FX-Deprecated-Fieldsthat name the spelling to use.- Every
camelCasekey of a response stays, and itssnake_casetwin is added next to it with the same value.?naming=snake(or the headerX-FX-Naming: snake) returns thesnake_casekeys only. GET /publishes the complete map (no key needed). The reference marks each earlier spelling as deprecated and says what replaces it.api/ v1/ conventions/ naming
Errors and request ids
- Every error body now has
errors[](code,type,title,message,field,details,documentation_url),meta.request_idandrequest_id, next to the keys it always had. A reply with HTTP200andsuccess: falsehas them too. The code is stable: writeifstatements againsterrors[0].code, not against the message. See Errors. - Every response carries
X-Request-Id. Quote it when you contact support. - A request that could never succeed is refused with
400and a stable code before any supplier is called: an unknown airport code, a date that is impossible or too far away, an absurd passenger count, an unknown value ofcabin_classorbooking_type, a hotel stay over 30 nights. These used to come back as503 all_suppliers_failed, as500or as a502that Cloudflare replaced by an HTML page. book_flightanswers a failure with JSON (409,422or503) instead of an HTML502.- Messages no longer carry the raw text of a supplier, of the database or of the code.
Flights
- Streaming is documented:
stream=truereturns the offers supplier by supplier as server-sent events,environmentcomes first, comment lines keep the connection alive, anddoneis always the last event. booking_typeandcabin_classare validated. An unknownbooking_typeused to create a paid instant order with Duffel.flexible_searchwith no supplier able to answer returns422 no_supplier_supports_flexible_searchinstead of503.failures[]of a search says why a supplier failed incause(supplier_timeout,supplier_api_error...).get_bookingaddsacd_required,requires_acd, a booleanacd_submitted,pdf_urlandpdf_url_no_price.- ACD uploads:
upload_acd_documentsreads the form after authentication, answers415to anything butmultipart/, and has the new codesform-data INVALID_MULTIPARTandINVALID_BOOKING_ID. The existing codes and the limits (10 MiB a file, 25 MiB a request) are unchanged.
Hotels
- Mini and full hotel data:
get_hotel_infoandhotels/acceptdetails detail_level(minimal,miniorfull, defaultfull) andimages_limit. A mini card is about eight times smaller than the full document: use it for search results and read the full document for the hotel page. - In the sandbox, only the supplier's test hotels can be booked (Sandbox testing).
pre_bookof any other hotel answers409 hotel_not_bookable_in_sandboxinstead of a success that could never be booked. pre_bookanswers the same request within 60 seconds with the same result, andbook_hotelrefuses a second booking of the samebooking_idwith409 duplicate_bookingand does not call the supplier again.search_advancedanswers at most 5,000 hotels and saystruncatedwhen it cut the list. An unknown hotel is404 hotel_not_found(it was a502). Supplier cost data and debug blocks are no longer in the answers to API keys.
eSIMs
- Usage, instructions, top-up packages and top-ups work for the eSIMs of your agency and environment only. Any other ICCID answers
404 iccid_not_foundbefore the supplier is called. setup-urlreturns the install link only. Thesearchof the eSIM list no longer fails on special characters, andusage/takes up to 50 ICCIDs and answers one entry per ICCID.bulk - An order or a top-up that the supplier refuses answers
supplier_errorwith a fixed message, and no balance is debited.
Security
- A booking, a search or an eSIM of another agency answers the same
404as one that does not exist, on every endpoint. Nothing tells a caller that an identifier exists. - A request body has a size limit: 64 KB for a search or a price, 256 KB for any other JSON, 26 MB for an ACD upload. A larger body answers
413 request_too_large. - A key that is not shaped like an FX-Port key (
fxp_live_orfxp_test_and 16 to 64 letters and digits) answers401 invalid_api_key_formatat once. A burst of requests with unknown keys from one address is slowed down, and never affects a valid key. See Rate limits and fair use. - Internal data (net fares, commissions, internal ids) is no longer returned by
get_booking,get_ticket_numberandinclude_bags.
Limits and headers
- Every response of an API key has
ratelimit-limit,ratelimit-remaining,ratelimit-resetandratelimit-policy, and every429and503hasRetry-After. New codes:concurrency_limit_exceeded,auth_rate_limited,service_overloaded,supplier_busy. - Search and hotel-content endpoints also limit how many calls of one key run at the same time. The ceilings are far above what an interactive application needs and run in observation mode first: nothing is refused because of them until we announce it here.
2026-10-25: ACD passport uploads
API
POST /tells you how many passports an ACD booking needs and which travelers already have one.api/ v1/ flights/ get_acd_documents POST /adds one passport, several or all of them, and replaces a passport that was already sent. See ACD passport uploads.api/ v1/ flights/ upload_acd_documents
2026-10-08: void window anchored to the payment day
API
booking.voidableUntilis now computed from the day the booking was paid, not from the day it was created. See Get a flight booking.
2026-08-27: security, eSIMs and hotels
Documentation
2026-08-17: first public documentation
API
- Flights: search, flexible-date search, price, book (issue or hold), quote, pay, cancel a held booking, get a booking, get the ticket PDF, airports.
- Suppliers and account: the list of suppliers, balances, the balance ledger, booking history and booking detail.
- Self-serve API keys with Read and Read+Write permissions, for the sandbox (
fxp_test_) and for live (fxp_live_), on one base URL.