Get the ACD document state of a booking
Read what a booking needs for ACD, which travelers already have a passport on file, and whether you can upload.
/api/v1/flights/get_acd_documentsCall it before every upload and use its traveler_id values and missing_traveler_ids: do not build traveler ids yourself.
A booking needs ACD passports when its fare has pricing.acd.applied: true (requiresACD: true on the offer and the booking): one passport copy for every traveler on the booking. acd_required of get_booking and acd.acd_required here say whether passports are still expected. The endpoint answers 200 for every booking of your agency, ACD or not: for a booking without ACD acd_required is false, can_upload is false and blocked_reason is ACD_NOT_REQUIRED. Travelers are listed either way. ticket_number of a traveler is null until the airline returns one (always for a hold).
booking_id takes the PNR, the supplier order id or the FX-Port UUID (order_id and pnr are other names of the same field). Only bookings of your agency in the environment of your key are found: a booking of another agency, a booking of the other environment and an id that does not exist all answer the same 404 BOOKING_NOT_FOUND, so an answer never tells whether a booking exists. The download_url of a document is a public address that needs no key: anybody who has it can open the passport, so treat it as sensitive.
curl https://api.fx-port.com/api/v1/flights/get_acd_documents \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"booking_id": "Y7IA34"
}'{
"environment": "sandbox",
"success": true,
"requestId": "8201f6f6",
"booking_id": "Y7IA34",
"acd": {
"booking_id": "Y7IA34",
"acd_required": true,
"acd_waived": false,
"acd_submitted": false,
"acd_paid": false,
"complete": false,
"can_upload": true,
"blocked_reason": null,
"required_documents": 3,
"uploaded_documents": 1,
"missing_documents": 2,
"missing_traveler_ids": [
"1",
"3"
],
"travelers": [
{
"traveler_id": "1",
"traveler_name": "JANE DOE",
"traveler_type": "ADULT",
"ticket_number": null,
"status": "missing",
"document": null
},
{
"traveler_id": "2",
"traveler_name": "JOHN DOE",
"traveler_type": "ADULT",
"ticket_number": null,
"status": "uploaded",
"document": {
"filename": "john-passport.pdf",
"content_type": "application/pdf",
"size_bytes": 482113,
"download_url": "https://s3.example.com/fx-port/acd_passports/Y7IA34/2/20261101142618_ec9632ab.pdf",
"uploaded_at": "2026-11-01T14:26:18.120000+00:00",
"replaced_count": 0
}
},
{
"traveler_id": "3",
"traveler_name": "JAMES DOE",
"traveler_type": "ADULT",
"ticket_number": null,
"status": "missing",
"document": null
}
],
"unassigned_documents": [],
"revision": 1,
"limits": {
"accepted_formats": [
"avif",
"bmp",
"gif",
"heif",
"jp2",
"jpeg",
"jxl",
"pdf",
"png",
"tiff",
"webp"
],
"accepted_extensions": [
"avif",
"bmp",
"dib",
"gif",
"heic",
"heif",
"j2k",
"jfif",
"jp2",
"jpeg",
"jpg",
"jpx",
"jxl",
"pdf",
"pjp",
"pjpeg",
"png",
"tif",
"tiff",
"webp"
],
"max_file_size_bytes": 10485760,
"max_request_size_bytes": 26214400,
"max_documents_per_request": 3
}
}
}{
"environment": "sandbox",
"success": true,
"requestId": "8b5b5c52",
"booking_id": "Y7HKJM",
"acd": {
"booking_id": "Y7HKJM",
"acd_required": false,
"acd_waived": false,
"acd_submitted": false,
"acd_paid": false,
"complete": false,
"can_upload": false,
"blocked_reason": "ACD_NOT_REQUIRED",
"required_documents": 0,
"uploaded_documents": 0,
"missing_documents": 0,
"missing_traveler_ids": [],
"travelers": [
{
"traveler_id": "1",
"traveler_name": "JOHN SMITH",
"traveler_type": "ADULT",
"ticket_number": "124-2446977395",
"status": "missing",
"document": null
}
],
"unassigned_documents": [],
"revision": 0,
"limits": {
"accepted_formats": [
"avif",
"bmp",
"gif",
"heif",
"jp2",
"jpeg",
"jxl",
"pdf",
"png",
"tiff",
"webp"
],
"accepted_extensions": [
"avif",
"bmp",
"dib",
"gif",
"heic",
"heif",
"j2k",
"jfif",
"jp2",
"jpeg",
"jpg",
"jpx",
"jxl",
"pdf",
"pjp",
"pjpeg",
"png",
"tif",
"tiff",
"webp"
],
"max_file_size_bytes": 10485760,
"max_request_size_bytes": 26214400,
"max_documents_per_request": 1
}
}
}Request
Body
Required, JSON.
booking_idstringrequiredThe PNR, the supplier order id or the FX-Port booking UUID. Letters, digits and - _ . : = ~, up to 128 characters. order_id and pnr are accepted as other names of the same field.
agency_idstringNot needed: the agency of a call is always the one of your API key. The field is accepted so that older clients keep working, and it is ignored.
bookingIdstringdeprecatedLegacy name, still accepted. Use booking_id instead.
The older spelling of booking_id.
orderIdstringdeprecatedLegacy name, still accepted. Use booking_id instead.
The older spelling of booking_id.
agencyIdstringdeprecatedLegacy name, still accepted. Use agency_id instead.
The older spelling of agency_id.
Response
200The ACD state of the booking.
environmentstringThe environment of the key that made the call: sandbox for fxp_test_ keys, live for fxp_live_ keys. Present in every JSON body.
One of sandbox, live.
request_idstringThe id of the request, also in the X-Request-Id header.
warningsarray of objectPresent only when the request used a previous spelling of a field or something the endpoint ignored.
ShowHide 5 attributes
codestringWhat the warning is about.
One of deprecated_field, ignored_field, coerced_value, deprecated_value, deprecated_endpoint.
fieldstringThe request field the warning is about.
replacementstringThe name to use instead, for deprecated_* warnings.
messagestringA sentence that says what happened and what to do.
documentation_urlstringWhere the naming rules are explained.
successbooleanAlways true here: a booking without ACD is a 200 too.
requestIdstringdeprecatedLegacy name, still accepted. Use request_id instead.
The id of this request, 8 characters, for support.
booking_idstringdeprecatedLegacy name, still accepted. Use pnr instead.
The PNR, whatever identifier you sent.
pnrstringThe PNR, whatever identifier you sent. The snake_case twin of booking_id, with the same value: use this name.
acdobjectThe ACD state of a booking: what is needed, what was uploaded, and whether you can upload.
ShowHide 17 attributes
booking_idstringdeprecatedLegacy name, still accepted. Use pnr instead.
The PNR of the booking.
pnrstringThe PNR of the booking. The snake_case twin of booking_id, with the same value: use this name.
acd_requiredbooleantrue when the booking needs ACD passports and FX-Port did not waive them.
acd_waivedbooleantrue when FX-Port marked ACD as not required for this booking. No upload is accepted then. You cannot set it.
acd_submittedbooleantrue once every traveler has a passport. Never null. Also true for a hold that has a complete set.
acd_paidbooleantrue once FX-Port's team has marked the ACD amount of the booking as paid. You cannot set it.
completebooleanEvery required passport is uploaded. Always false when ACD is not required.
can_uploadbooleanWhether upload_acd_documents accepts files for this booking right now.
blocked_reasonstringnullableWhy can_upload is false. null otherwise.
One of ACD_NOT_REQUIRED, ACD_WAIVED, BOOKING_NOT_ELIGIBLE, TRAVELERS_NOT_AVAILABLE.
required_documentsintegerThe number of passports needed: one for each traveler of the booking. 0 when ACD is not required.
uploaded_documentsintegerHow many of the required passports are uploaded.
missing_documentsintegerHow many are still missing.
missing_traveler_idsarray of stringThe travelers who still need a passport. Use these values in traveler_ids.
travelersarray of objectEvery traveler of the booking.
ShowHide 6 attributes
traveler_idstringThe id to send in traveler_ids: the id of the passenger on the booking ("1", "2" for Amadeus Algeria, pas_... for Duffel).
traveler_namestringThe name on the booking.
traveler_typestringThe passenger type, for example ADULT.
ticket_numberstringnullableThe e-ticket number. null until the airline returns one: always for a hold, and for an instant booking whose number has not arrived.
statusstringWhether this traveler has a passport.
One of uploaded, missing.
documentobjectnullableThe current passport file of a traveler.
ShowHide 6 attributes
filenamestringnullableThe file name you sent.
content_typestringThe type FX-Port detected from the content (for example application/, image/), not the one you sent.
size_bytesintegerThe size of the stored file.
download_urlstringA public address of the file: anyone who has it can download the passport. Treat it as sensitive.
uploaded_atstringISO 8601 UTC time of the upload, with +00:00.
replaced_countintegerHow many times the passport was replaced.
unassigned_documentsarray of objectFiles that do not count as a traveler's passport.
ShowHide 1 attribute
download_urlstringA public address of the file.
revisionintegerIncreases by one with each upload that stored a file. 0 for a booking without any.
limitsobjectThe upload limits. Read them instead of hardcoding them.
ShowHide 5 attributes
accepted_formatsarray of stringThe 11 accepted formats.
accepted_extensionsarray of stringThe 20 extensions of those formats.
max_file_size_bytesintegerThe largest accepted file: 10485760 (10 MiB).
max_request_size_bytesintegerThe largest total size of the files of one request: 26214400 (25 MiB).
max_documents_per_requestintegerThe number of travelers of the booking: the most files one request can carry.
Errors
| Status | Code | Example message |
|---|---|---|
| 400 | MISSING_BOOKING_ID | Missing required field: booking_id |
| 400 | INVALID_BOOKING_ID | `booking_id` is not a valid identifier (letters, digits and - _ . : = ~ only, up to 128 characters). |
| 404 | BOOKING_NOT_FOUND | No flight booking found for 'ZZZZZZ'. |
The shape of the error body depends on the endpoint. See Errors for every shape and code.