# Upload ACD passport documents

> Add or replace the passport copies of a booking that needs ACD: one file for each traveler, sent as multipart/form-data (not JSON).

Endpoint: `POST /flights/upload_acd_documents`

Source: https://fx-port.com/docs/api/upload-acd-documents

`POST /api/v1/flights/upload_acd_documents`

Requires an API key with **Read+Write** permission: a Read key is refused with `read_write_permission_required`.

**The form.** `booking_id` is the PNR, the supplier order id or the FX-Port UUID of a booking of your agency (any other booking, also one of another agency, answers `404 BOOKING_NOT_FOUND`, like an unknown id). `traveler_ids` and `documents` are matched **by order**: the first id goes with the first file. Send `traveler_ids` once for each file, or as one comma-separated value (`1,2`), or as a JSON array as text (`["1","2"]`); the `documents` field is repeated, one file each. `replace=true` overwrites a traveler who already has a passport; without it that traveler is refused (`DOCUMENT_ALREADY_UPLOADED`) and nothing changes. The older names `bookingId`, `orderId`, `travelerIds`, `files`, `file` and `document` are still read.

**The files.** A PDF or an image (JPEG, PNG, WebP, HEIC/HEIF, AVIF, TIFF, BMP, GIF, JPEG 2000, JPEG XL), recognised **by content** (the extension and the `Content-Type` you send are not trusted). At most 10 MiB per file and 25 MiB per request, and no more files than travelers. Several files with problems are all reported in `results[]`: a request with any bad file stores nothing.

**Reading the answer.** `200` means every file was saved, `207` means only some were (`status: partial_success`; read `results[]`), `4xx` means nothing changed. A `5xx` after the files were stored cannot be told from the outside: call `get_acd_documents` before you retry. A retry without `replace` is safe; with `replace=true` it replaces the file again.

`notification` says whether the ACD team was told: in the sandbox it is never sent (`skipped: true`, `reason: sandbox_environment`). A hold accepts uploads (`reason: hold_booking`). The `download_url` links are public: treat them as sensitive. In the sandbox, a booking of `CDG` to `ALG` on `amadeus_aqc_dz_1` is an ACD booking: use fake files (a PDF or PNG a few bytes long), never a real document.

## Request

### Body

Required, multipart/form-data.

- `booking_id` (string, required): The PNR, the supplier order id or the FX-Port booking UUID. `order_id` and `pnr` are accepted as other names. When the form holds several spellings with different values, the first of `booking_id`, `bookingId`, `order_id`, `orderId`, `pnr` wins and an `ignored_field` warning names each dropped one.
- `traveler_ids` (array of string, required): The travelers the files belong to, **in the same order as `documents`**. Send the field once for each file, or one comma-separated value (`1,2`), or a JSON array as text (`["1","2"]`). A traveler may appear once per request.
- `documents` (array of string, required): One passport file for each traveler: PDF or an image, 10 MiB at most each, 25 MiB for all together. The field name must be `documents`.
- `replace` (string, optional): `true` to overwrite travelers that already have a passport (`1`, `yes`, `on` and `0`, `no`, `off` are read too). Default `false`. One of `true`, `false`.
- `agency_id` (string, optional): Not 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.
- `bookingId` (string, deprecated, optional): Legacy name: use `booking_id`. The older spelling of `booking_id`.
- `orderId` (string, deprecated, optional): Legacy name: use `booking_id`. The older spelling of `booking_id`.
- `agencyId` (string, deprecated, optional): Legacy name: use `agency_id`. The older spelling of `agency_id`.
- `travelerIds` (string, deprecated, optional): Legacy name: use `traveler_ids`. The older spelling of `traveler_ids`.
- `travelerId` (string, deprecated, optional): Legacy name: use `traveler_ids`. The older spelling of `traveler_ids`.
- `traveler_id` (string, deprecated, optional): Legacy name: use `traveler_ids`. The older spelling of `traveler_ids`.
- `files` (string, deprecated, optional): Legacy name: use `documents`. The older spelling of `documents`.
- `file` (string, deprecated, optional): Legacy name: use `documents`. The older spelling of `documents`.
- `document` (string, deprecated, optional): Legacy name: use `documents`. The older spelling of `documents`.

### Example request

```bash
curl https://api.fx-port.com/api/v1/flights/upload_acd_documents \
  -H "Authorization: Bearer fxp_test_YOUR_KEY" \
  -F 'booking_id=Y7HWMD' \
  -F 'traveler_ids=1' \
  -F 'documents=@passport.pdf;type=application/pdf'
```

## Response

### 200: Every file was saved.

- `environment` (string): The 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_id` (string): The id of the request, also in the `X-Request-Id` header.
- `warnings` (array of object): Problems that did not stop the upload.
- `success` (boolean): `true` for `200` and for `207`.
- `status` (string): `success`: every file stored. `partial_success`: some stored, some failed (HTTP `207`). One of `success`, `partial_success`.
- `requestId` (string, deprecated): Legacy name: use `request_id`. The id of this request, 8 characters, for support.
- `booking_id` (string, deprecated): Legacy name: use `pnr`. The PNR.
- `pnr` (string): The PNR. The snake_case twin of `booking_id`, with the same value: use this name.
- `message` (string): A sentence: `2 documents saved.`
- `summary` (object): The counts of this request.
  - `received` (integer): Files in the request.
  - `uploaded` (integer): New passports.
  - `replaced` (integer): Replaced passports.
  - `failed` (integer): Files that failed.
- `results` (array of object): One entry for each file, in the order you sent them.
  - `index` (integer): The position of the file in your request, from 0.
  - `traveler_id` (string): The traveler of this file.
  - `traveler_name` (string, nullable): The name on the booking, `null` when the id is not on the booking.
  - `filename` (string): The file name you sent (`document-<n>` when the part had none).
  - `status` (string): `uploaded`: a new passport. `replaced`: a passport that existed was replaced. `failed`: this file has a problem (see `error`). `skipped`: this file is valid, but another file of the request failed, so it was not processed. One of `uploaded`, `replaced`, `failed`, `skipped`.
  - `content_type` (string): Only for `uploaded` and `replaced`: the detected type.
  - `size_bytes` (integer): Only for `uploaded` and `replaced`: the size of the stored file.
  - `download_url` (string): Only for `uploaded` and `replaced`: the public address of the stored file.
  - `error` (object): Only for `failed`: what is wrong with this file.
    - `code` (string): The code of the problem.
    - `message` (string): A sentence about it.
    - `expected_traveler_ids` (array of string): `UNKNOWN_TRAVELER_ID`: the ids of the booking.
    - `accepted_extensions` (array of string): `UNSUPPORTED_FILE_TYPE`: the accepted extensions.
    - `max_file_size_bytes` (integer): `FILE_TOO_LARGE`: the limit.
    - `reason` (string): `STORAGE_UPLOAD_FAILED`: always the fixed text `storage_error`. The message of the storage system is never returned.
- `acd` (object): The ACD state of a booking: what is needed, what was uploaded, and whether you can upload.
  - `booking_id` (string, deprecated): Legacy name: use `pnr`. The PNR of the booking.
  - `pnr` (string): The PNR of the booking. The snake_case twin of `booking_id`, with the same value: use this name.
  - `acd_required` (boolean): `true` when the booking needs ACD passports and FX-Port did not waive them.
  - `acd_waived` (boolean): `true` when FX-Port marked ACD as not required for this booking. No upload is accepted then. You cannot set it.
  - `acd_submitted` (boolean): `true` once every traveler has a passport. Never `null`. Also `true` for a hold that has a complete set.
  - `acd_paid` (boolean): `true` once FX-Port's team has marked the ACD amount of the booking as paid. You cannot set it.
  - `complete` (boolean): Every required passport is uploaded. Always `false` when ACD is not required.
  - `can_upload` (boolean): Whether `upload_acd_documents` accepts files for this booking right now.
  - `blocked_reason` (string, nullable): Why `can_upload` is `false`. `null` otherwise. One of `ACD_NOT_REQUIRED`, `ACD_WAIVED`, `BOOKING_NOT_ELIGIBLE`, `TRAVELERS_NOT_AVAILABLE`.
  - `required_documents` (integer): The number of passports needed: one for each traveler of the booking. `0` when ACD is not required.
  - `uploaded_documents` (integer): How many of the required passports are uploaded.
  - `missing_documents` (integer): How many are still missing.
  - `missing_traveler_ids` (array of string): The travelers who still need a passport. Use these values in `traveler_ids`.
  - `travelers` (array of object): Every traveler of the booking.
    - `traveler_id` (string): The id to send in `traveler_ids`: the id of the passenger on the booking (`"1"`, `"2"` for Amadeus Algeria, `pas_...` for Duffel).
    - `traveler_name` (string): The name on the booking.
    - `traveler_type` (string): The passenger type, for example `ADULT`.
    - `ticket_number` (string, nullable): The e-ticket number. `null` until the airline returns one: always for a hold, and for an instant booking whose number has not arrived.
    - `status` (string): Whether this traveler has a passport. One of `uploaded`, `missing`.
    - `document` (object, nullable): The current passport file of a traveler.
      - `filename` (string, nullable): The file name you sent.
      - `content_type` (string): The type FX-Port detected from the content (for example `application/pdf`, `image/jpeg`), not the one you sent.
      - `size_bytes` (integer): The size of the stored file.
      - `download_url` (string): A **public** address of the file: anyone who has it can download the passport. Treat it as sensitive.
      - `uploaded_at` (string): ISO 8601 UTC time of the upload, with `+00:00`.
      - `replaced_count` (integer): How many times the passport was replaced.
  - `unassigned_documents` (array of object): Files that do not count as a traveler's passport.
    - `download_url` (string): A public address of the file.
  - `revision` (integer): Increases by one with each upload that stored a file. `0` for a booking without any.
  - `limits` (object): The upload limits. Read them instead of hardcoding them.
    - `accepted_formats` (array of string): The 11 accepted formats.
    - `accepted_extensions` (array of string): The 20 extensions of those formats.
    - `max_file_size_bytes` (integer): The largest accepted file: 10485760 (10 MiB).
    - `max_request_size_bytes` (integer): The largest total size of the files of one request: 26214400 (25 MiB).
    - `max_documents_per_request` (integer): The number of travelers of the booking: the most files one request can carry.
- `notification` (object): Whether the ACD team was notified. The e-mail goes to FX-Port, not to you or the traveler.
  - `sent` (boolean): Whether FX-Port's ACD team was e-mailed.
  - `type` (string): `submitted` when the set became complete, `updated` after a replacement on a complete set. Absent when nothing was due. One of `submitted`, `updated`.
  - `skipped` (boolean): `true` when no e-mail was due or sent: see `reason`.
  - `reason` (string): Why no e-mail was sent: `awaiting_remaining_documents`, `hold_booking` or `sandbox_environment`; with `error` it is the fixed text `email_error` (the message of the mail system is never returned).
  - `error` (string): `EMAIL_SEND_FAILED` when the e-mail failed. The files are saved.

```json
{
  "environment": "sandbox",
  "success": true,
  "status": "success",
  "requestId": "58bfcf4a",
  "booking_id": "Y7IA34",
  "message": "2 documents saved.",
  "summary": {
    "received": 2,
    "uploaded": 2,
    "replaced": 0,
    "failed": 0
  },
  "results": [
    {
      "index": 0,
      "traveler_id": "1",
      "traveler_name": "JANE DOE",
      "filename": "passport-1.png",
      "status": "uploaded",
      "content_type": "image/png",
      "size_bytes": 69,
      "download_url": "https://s3.example.com/fx-port/acd_passports/Y7IA34/1/20261101142620_28e115c8.png"
    },
    {
      "index": 1,
      "traveler_id": "3",
      "traveler_name": "JAMES DOE",
      "filename": "passport-3.pdf",
      "status": "uploaded",
      "content_type": "application/pdf",
      "size_bytes": 191,
      "download_url": "https://s3.example.com/fx-port/acd_passports/Y7IA34/3/20261101142620_4194315e.pdf"
    }
  ],
  "acd": {
    "booking_id": "Y7IA34",
    "acd_required": true,
    "acd_waived": false,
    "acd_submitted": true,
    "acd_paid": false,
    "complete": true,
    "can_upload": true,
    "blocked_reason": null,
    "required_documents": 3,
    "uploaded_documents": 3,
    "missing_documents": 0,
    "missing_traveler_ids": [],
    "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": 2,
    "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
    }
  },
  "notification": {
    "sent": false,
    "type": "submitted",
    "skipped": true,
    "reason": "sandbox_environment"
  },
  "warnings": []
}
```

### 207: Some files were saved and others failed. `results[]` says which, with a code for each; send the failed travelers again.

- `environment` (string): The 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_id` (string): The id of the request, also in the `X-Request-Id` header.
- `warnings` (array of object): Problems that did not stop the upload.
- `success` (boolean): `true` for `200` and for `207`.
- `status` (string): `success`: every file stored. `partial_success`: some stored, some failed (HTTP `207`). One of `success`, `partial_success`.
- `requestId` (string, deprecated): Legacy name: use `request_id`. The id of this request, 8 characters, for support.
- `booking_id` (string, deprecated): Legacy name: use `pnr`. The PNR.
- `pnr` (string): The PNR. The snake_case twin of `booking_id`, with the same value: use this name.
- `message` (string): A sentence: `2 documents saved.`
- `summary` (object): The counts of this request.
  - `received` (integer): Files in the request.
  - `uploaded` (integer): New passports.
  - `replaced` (integer): Replaced passports.
  - `failed` (integer): Files that failed.
- `results` (array of object): One entry for each file, in the order you sent them.
  - `index` (integer): The position of the file in your request, from 0.
  - `traveler_id` (string): The traveler of this file.
  - `traveler_name` (string, nullable): The name on the booking, `null` when the id is not on the booking.
  - `filename` (string): The file name you sent (`document-<n>` when the part had none).
  - `status` (string): `uploaded`: a new passport. `replaced`: a passport that existed was replaced. `failed`: this file has a problem (see `error`). `skipped`: this file is valid, but another file of the request failed, so it was not processed. One of `uploaded`, `replaced`, `failed`, `skipped`.
  - `content_type` (string): Only for `uploaded` and `replaced`: the detected type.
  - `size_bytes` (integer): Only for `uploaded` and `replaced`: the size of the stored file.
  - `download_url` (string): Only for `uploaded` and `replaced`: the public address of the stored file.
  - `error` (object): Only for `failed`: what is wrong with this file.
    - `code` (string): The code of the problem.
    - `message` (string): A sentence about it.
    - `expected_traveler_ids` (array of string): `UNKNOWN_TRAVELER_ID`: the ids of the booking.
    - `accepted_extensions` (array of string): `UNSUPPORTED_FILE_TYPE`: the accepted extensions.
    - `max_file_size_bytes` (integer): `FILE_TOO_LARGE`: the limit.
    - `reason` (string): `STORAGE_UPLOAD_FAILED`: always the fixed text `storage_error`. The message of the storage system is never returned.
- `acd` (object): The ACD state of a booking: what is needed, what was uploaded, and whether you can upload.
  - `booking_id` (string, deprecated): Legacy name: use `pnr`. The PNR of the booking.
  - `pnr` (string): The PNR of the booking. The snake_case twin of `booking_id`, with the same value: use this name.
  - `acd_required` (boolean): `true` when the booking needs ACD passports and FX-Port did not waive them.
  - `acd_waived` (boolean): `true` when FX-Port marked ACD as not required for this booking. No upload is accepted then. You cannot set it.
  - `acd_submitted` (boolean): `true` once every traveler has a passport. Never `null`. Also `true` for a hold that has a complete set.
  - `acd_paid` (boolean): `true` once FX-Port's team has marked the ACD amount of the booking as paid. You cannot set it.
  - `complete` (boolean): Every required passport is uploaded. Always `false` when ACD is not required.
  - `can_upload` (boolean): Whether `upload_acd_documents` accepts files for this booking right now.
  - `blocked_reason` (string, nullable): Why `can_upload` is `false`. `null` otherwise. One of `ACD_NOT_REQUIRED`, `ACD_WAIVED`, `BOOKING_NOT_ELIGIBLE`, `TRAVELERS_NOT_AVAILABLE`.
  - `required_documents` (integer): The number of passports needed: one for each traveler of the booking. `0` when ACD is not required.
  - `uploaded_documents` (integer): How many of the required passports are uploaded.
  - `missing_documents` (integer): How many are still missing.
  - `missing_traveler_ids` (array of string): The travelers who still need a passport. Use these values in `traveler_ids`.
  - `travelers` (array of object): Every traveler of the booking.
    - `traveler_id` (string): The id to send in `traveler_ids`: the id of the passenger on the booking (`"1"`, `"2"` for Amadeus Algeria, `pas_...` for Duffel).
    - `traveler_name` (string): The name on the booking.
    - `traveler_type` (string): The passenger type, for example `ADULT`.
    - `ticket_number` (string, nullable): The e-ticket number. `null` until the airline returns one: always for a hold, and for an instant booking whose number has not arrived.
    - `status` (string): Whether this traveler has a passport. One of `uploaded`, `missing`.
    - `document` (object, nullable): The current passport file of a traveler.
      - `filename` (string, nullable): The file name you sent.
      - `content_type` (string): The type FX-Port detected from the content (for example `application/pdf`, `image/jpeg`), not the one you sent.
      - `size_bytes` (integer): The size of the stored file.
      - `download_url` (string): A **public** address of the file: anyone who has it can download the passport. Treat it as sensitive.
      - `uploaded_at` (string): ISO 8601 UTC time of the upload, with `+00:00`.
      - `replaced_count` (integer): How many times the passport was replaced.
  - `unassigned_documents` (array of object): Files that do not count as a traveler's passport.
    - `download_url` (string): A public address of the file.
  - `revision` (integer): Increases by one with each upload that stored a file. `0` for a booking without any.
  - `limits` (object): The upload limits. Read them instead of hardcoding them.
    - `accepted_formats` (array of string): The 11 accepted formats.
    - `accepted_extensions` (array of string): The 20 extensions of those formats.
    - `max_file_size_bytes` (integer): The largest accepted file: 10485760 (10 MiB).
    - `max_request_size_bytes` (integer): The largest total size of the files of one request: 26214400 (25 MiB).
    - `max_documents_per_request` (integer): The number of travelers of the booking: the most files one request can carry.
- `notification` (object): Whether the ACD team was notified. The e-mail goes to FX-Port, not to you or the traveler.
  - `sent` (boolean): Whether FX-Port's ACD team was e-mailed.
  - `type` (string): `submitted` when the set became complete, `updated` after a replacement on a complete set. Absent when nothing was due. One of `submitted`, `updated`.
  - `skipped` (boolean): `true` when no e-mail was due or sent: see `reason`.
  - `reason` (string): Why no e-mail was sent: `awaiting_remaining_documents`, `hold_booking` or `sandbox_environment`; with `error` it is the fixed text `email_error` (the message of the mail system is never returned).
  - `error` (string): `EMAIL_SEND_FAILED` when the e-mail failed. The files are saved.

```json
{
  "environment": "sandbox",
  "success": true,
  "status": "partial_success",
  "requestId": "3d7a91c0",
  "booking_id": "Y7IA34",
  "message": "1 of 2 documents saved; 1 failed — retry the failed travelers.",
  "summary": {
    "received": 2,
    "uploaded": 1,
    "replaced": 0,
    "failed": 1
  },
  "results": [
    {
      "index": 0,
      "traveler_id": "1",
      "traveler_name": "JANE DOE",
      "filename": "passport-1.png",
      "status": "uploaded",
      "content_type": "image/png",
      "size_bytes": 69,
      "download_url": "https://s3.example.com/fx-port/acd_passports/Y7IA34/1/20261101142620_28e115c8.png"
    },
    {
      "index": 1,
      "traveler_id": "3",
      "traveler_name": "JAMES DOE",
      "filename": "passport-3.pdf",
      "status": "failed",
      "error": {
        "code": "STORAGE_UPLOAD_FAILED",
        "message": "The document could not be stored. Retry this traveler.",
        "reason": "storage_error"
      }
    }
  ],
  "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": 2,
    "missing_documents": 1,
    "missing_traveler_ids": [
      "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": 2,
    "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
    }
  },
  "notification": {
    "sent": false,
    "skipped": true,
    "reason": "awaiting_remaining_documents"
  },
  "warnings": []
}
```

## Errors

| Status | Code | Example message |
| --- | --- | --- |
| 400 | `DOCUMENT_COUNT_MISMATCH` | traveler_ids and documents must have the same number of entries (they are matched by order). |
| 400 | `VALIDATION_FAILED` | 2 of 2 documents were rejected. Nothing was uploaded. |
| 400 | `MISSING_BOOKING_ID` | Missing required form field: booking_id |
| 403 | `read_write_permission_required` | This endpoint requires an API key with read_write permission. |
| 404 | `BOOKING_NOT_FOUND` | No flight booking found for 'ZZZZZZ'. |
| 409 | `DOCUMENT_ALREADY_UPLOADED` | A passport is already uploaded for traveler '2'. Send replace=true to replace it. |
| 409 | `ACD_NOT_REQUIRED` | This booking does not require ACD documents. |
| 413 | `FILE_TOO_LARGE` | Uploaded document 'big.pdf' exceeds the 10 MB limit. |
| 415 | `UNSUPPORTED_FILE_TYPE` | 'bad.pdf' is not a supported passport document. Upload a PDF or a JPEG, PNG, WebP, HEIC/HEIF, AVIF, TIFF, BMP, GIF, JPEG 2000 or JPEG XL image. |
| 415 | `UNSUPPORTED_MEDIA_TYPE` | Send multipart/form-data with the fields booking_id, traveler_ids and documents. |
| 502 | `STORAGE_UPLOAD_FAILED` | None of the documents could be stored. Nothing was changed. Please retry. |
| 503 | `STORAGE_UNAVAILABLE` | Document storage is temporarily unavailable. Please retry. |

See [Errors](https://fx-port.com/docs/errors.md) for every code and how to react.

## Related guides

- [Upload ACD documents](https://fx-port.com/docs/flights/acd-documents.md)
