Skip to content

Fileverity API docs

Files

Upload images and documents to Fileverity: multipart for files up to 4 MB, pre-signed upload for files up to 50 MB. File object, limits and retention.

View as MarkdownUpdated 2026-11-04

Images and documents are checked in two steps. First you upload the file with POST /files and receive a file ID. Then you create an analysis that references that ID. Text does not need a file; use Text detections.

Supported files

Images (fvimg-2)Documents (fvdoc-3)
Formatsjpeg, png, webppdf, docx, doc, rtf, odt, pptx, txt
Maximum size10 MB50 MB
Other limits40 megapixels100 pages

Two ways to upload

MethodRequestSizeFile status in the response
Multipartmultipart/form-data with the field fileUp to 4 MBuploaded
Pre-signed URLJSON with filename, content_type and bytes, then a PUT of the bytesUp to 50 MBpending until the bytes arrive

Images are limited to the image size above whichever method you use.

Multipart upload

Send files up to 4 MB as multipart/form-data in the field file. The format is detected from the file contents, not from its name or declared type.

curl https://api.fileverity.com/v1/files \  -H "Authorization: Bearer $FILEVERITY_API_KEY" \  -F file=@claim-photo.jpg
{  "id": "file_8Hk2pQ4vN9sL1xR7cW3mY6zB",  "object": "file",  "filename": "claim-photo.jpg",  "bytes": 2481920,  "content_type": "image/jpeg",  "status": "uploaded",  "livemode": true,  "created": 1793700000,  "expires_at": 1793786400}

Pre-signed upload

For files larger than 4 MB, up to 50 MB, ask for an upload URL, then send the bytes straight to storage.

  1. POST /files with a JSON body: filename (optional), content_type and the exact size in bytes. The response has status: pending and an upload object.
  2. PUT the file bytes to upload.url with the headers in upload.headers, before upload.expires_at. No Authorization header is needed for this request.
  3. Optionally poll GET /files/{id} until status is uploaded.
  4. Create the analysis with the file ID.
FILE=$(curl -s https://api.fileverity.com/v1/files \  -H "Authorization: Bearer $FILEVERITY_API_KEY" \  -H "Content-Type: application/json" \  -d '{"filename": "contract.pdf", "content_type": "application/pdf", "bytes": 18874368}') UPLOAD_URL=$(echo "$FILE" | jq -r .upload.url)FILE_ID=$(echo "$FILE" | jq -r .id) curl -X PUT "$UPLOAD_URL" \  -H "content-type: application/pdf" \  --data-binary @contract.pdf
{  "id": "file_Pw3mY6zB8Hk2pQ4vN9sL1xR7",  "object": "file",  "filename": "contract.pdf",  "bytes": 18874368,  "content_type": "application/pdf",  "status": "pending",  "livemode": true,  "created": 1793700000,  "expires_at": 1793786400,  "upload": {    "url": "https://example.private.blob.vercel-storage.com/f/0d6f1c2e-7b1a-4c53-9a0e-5e8a41b3c7d2?signature=...",    "method": "PUT",    "headers": {      "content-type": "application/pdf"    },    "expires_at": 1793703600  }}

The URL shown is shortened. Use the one in your response as it is. Send the content-type header exactly as returned in upload.headers.

Accepted content types

KindContent types
Imagesimage/jpeg, image/png, image/webp
Documentsapplication/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/msword, application/rtf, application/vnd.oasis.opendocument.text, application/vnd.openxmlformats-officedocument.presentationml.presentation, text/plain

The file object

FieldTypeDescription
idstringFile ID, prefixed file_.
objectstringAlways file.
filenamestring or nullSanitized file name.
bytesinteger or nullSize in bytes.
content_typestringDetected or declared content type.
statusstringpending until uploaded bytes have arrived, then uploaded.
livemodebooleanfalse for files created with a test key. Files are separated by mode.
createdintegerUnix timestamp.
expires_atintegerUnix timestamp after which the file is deleted.
uploadobjectOnly on the response to a JSON upload request: url, method (PUT), headers and expires_at.

Retention

  • A file is kept for at most 24 hours (see expires_at) and then deleted.
  • A file is deleted as soon as an analysis starts from it. Each uploaded file is used by one analysis; upload it again to check it again.
  • DELETE /files/{id} removes a file and its stored bytes earlier.
  • A workspace can hold up to 50 unexpired files and 200 MB per mode at once. Beyond that, uploads fail with pending_files_limit (HTTP 429, no retry-after) until files are used, deleted or expire.
  • A file ID that is unknown, expired or already used returns file_not_found when you create an analysis, and not_found when you retrieve or delete it. file_not_found is also returned when the upload to upload.url has not finished yet, so wait until GET /files/{id} shows uploaded.

Errors

CodeStatusCause
missing_parameter400No file field in the multipart body.
unsupported_media_type415The body is neither multipart/form-data nor JSON.
unsupported_file415The format is not supported.
invalid_file422The file is empty, damaged or cannot be read.
file_too_large413A multipart file larger than 4 MB, or bytes above 50 MB.
invalid_parameter400A JSON field is missing, mistyped or unknown.
invalid_json400The JSON body is not an object.
pending_files_limit429Too many unexpired uploads in the workspace. Not sent with a retry-after header.
idempotency_mismatch, idempotency_in_progress409The Idempotency-Key was used with a different request, or its first request is still running.

Test keys validate uploads but do not store the bytes. A JSON upload request with a test key returns a test upload object (upload.test is true, the file is already uploaded): there is nothing to PUT.