What it does

Uploading is how files enter fileAI for processing. You ask for a presigned storage URL, PUT the file to it, and processing starts as soon as the file lands.

When to use it

  • You receive invoices, statements or forms and want fileAI to classify them and extract values into your project.
  • You need to send many files at once (up to 100 per request), or files too large for one request (multipart, typically over 100 MB).
  • You have a folder of documents and want to send it as one .zip that fileAI unpacks and processes file by file.
Need values from one document without storing it? POST /v1/extract takes the file directly as multipart/form-data (up to 50 MB) and returns a job. See Extract, split and classify.

How it works

You never send file bytes to the API itself. You track the upload with GET /v1/uploads/{uploadId} or a callback; Async jobs compares the two.

Try it

Request an upload URL, then PUT the file to it. The URL is valid for 300 seconds (5 minutes) and can be used more than once within that time. Send the same Content-Type you gave as fileType (the file’s MIME type). The cURL examples assume FILEAI_BASE_URL is set as in Authentication.

Understand the result

The upload request returns 201:
Response (201)
Once the file lands, poll the upload, or wait for the request to your callbackURL:
Response (200)
The fraud_detection step is an internal processing step, not fileForensics. To check a file with fileForensics, see Choose products.

Next steps

Processing callbacks

Get notified instead of polling.

Supported file types

Every type fileAI accepts.

Files and folders

Organize uploads into folders.

Idempotency

Retry uploads safely.

Reference

Upload routes

Batch registration

POST /v1/files/upload/batch registers up to 100 files in one call and returns a presigned URL for each. Put shared options in defaults; any field on a file overrides the default.
Response (207)
  • results[i] always maps to files[i]. One bad file never rejects the others.
  • batchId is a 21-character lowercase id with no prefix. It is also the apiRequestId unless you set one in defaults.
  • The status is 201 when every file is accepted and 207 when the result is mixed.
  • An empty or missing files array returns 422 INVALID_BATCH; more than 100 files returns 422 BATCH_TOO_LARGE. Nothing is registered in either case.
  • A file over the page limit (when you send pageCount) is rejected on its own.
  • Send an Idempotency-Key (1–255 characters) to make the call safe to retry. A replay returns the same batchId, uploadIds and verdicts, with freshly signed URLs. See Idempotency.
  • isEphemeral and apiRequestId apply to the whole batch on this route, so they are only accepted in defaults.
Each URL is valid for 300 seconds. PUT each file to its own URL as in the single upload.

Multipart uploads for large files

Multipart uploads split one file into parts that you upload in parallel and then stitch together. Use them for large files (typically over 100 MB).
1

Initiate

Send the file size in MB. partSizeLimit (MB) is optional; parts are at least 5 MB, and the file is cut into at most 10,000 parts.
Response (201)
Keep id and key to complete the upload. uploadId is the id you track with GET /v1/uploads/{uploadId}.
2

Upload each part

PUT bytes startByte–endByte to each part’s presignedUrl, and save the ETag header from every response. Part URLs are valid for 900 seconds (15 minutes).
3

Complete

The response includes success: true, and processing starts.

Many large files

  • Initiate: POST /v1/files/upload/multipart/batch takes up to 25 files, with at most 2,500 part URLs across the batch. Over that, the request returns 422 BATCH_PARTS_TOO_LARGE and nothing is created; split the batch or raise partSizeLimit. Each file is accepted or rejected on its own, and the response is 201 even if every file is rejected, so check accepted, rejected and each result’s status.
  • Field names differ here: in batch results, uploadId is the storage multipart id (send it as id to complete or refresh) and fileId is the fileAI id you track with GET /v1/uploads/{uploadId}. Accepted results also include key and s3Path.
  • Per-file options: unlike /files/upload/batch, this route accepts isEphemeral on each file as well as in defaults.
  • Complete: POST /v1/files/upload/multipart/complete/batch with uploads (each id, key and full parts list) and an optional batchId. Each upload completes on its own: 201 when all succeed, 207 when some fail. Retry only the failed ones. A bad part list fails with INVALID_PARTS.
  • Refresh URLs: a long transfer can outlive its part URLs. POST /v1/files/upload/multipart/urls/refresh with id, key and the partNumbers still outstanding returns new URLs valid for another 900 seconds. Parts already uploaded stay uploaded. An unknown id/key returns 404.
Idempotency-Key is ignored on /multipart/batch and /multipart/urls/refresh: a retry starts a fresh set of uploads or signs fresh URLs. /multipart/complete/batch is idempotent for 24 hours. Abandoned multipart uploads expire on their own.

ZIP uploads

Upload a .zip through any route above. fileAI validates the archive, extracts it, and processes each supported file inside as its own upload. Set retainOriginalZipFileName: true to keep the archive’s name on the extracted files as zipArchiveName. Files from one ZIP share an apiRequestId (the ZIP’s id unless you supply one). GET /v1/uploads/{uploadId} for a ZIP returns one entry per extracted file in files, each with its own uploadId, statuses and files (documents). Files that could not be processed carry a processing_failed step with status error and an errorReason such as Unsupported file type. When some files succeed and some fail, the response is 207 instead of 200. If the archive itself fails validation, you get a zip_validation step with status error and an empty files array.

Upload options

These body fields are accepted on POST /v1/files/upload, and on the batch and multipart routes unless noted. Validation errors return 422, for example Invalid fileName., Invalid directoryId. or an ocrModel that is retired or unknown.

Choose products

enabledProducts on POST /v1/files/upload picks which products run on the file and are metered. It is accepted on single uploads only, and only in workspaces enabled for these products; otherwise the request returns 422. A storage-only upload without enabledProducts can later be sent to POST /v1/forensics.

Size limits

The maximum size for presigned and multipart uploads is set per instance. A file over it is marked as exceeding the maximum file size and is not processed. POST /v1/extract, /split and /classify accept files up to 50 MB.