Public API Files — File Upload Guide

How to upload a file to the Retraced platform and reference it from other resources (documents, attachments, product images, certificates, etc.).

Uploading is a two-step flow:

  1. POST /api/v2/files — register the file metadata. The server returns a pre-signed URL to the object storage bucket.
  2. PUT the raw bytes directly to that pre-signed URL. There is no separate finalize / confirm call.

Once the file exists, pass the returned id to whichever resource needs the file. The platform will automatically copy the bytes into the appropriate destination when you attach the file to a resource.

Setup

# Base URL
BASE_URL="https://publicapi.retraced.com/api/v2"

# Authentication — use your company API key
API_KEY="your-company-api-key"

All examples use curl. The API key is passed via the companyapikey header.


1. Register the file and get an upload URL

curl -X POST "$BASE_URL/files" \
  -H "companyapikey: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "spec.pdf",
    "fileSize": 204800,
    "fileType": "application/pdf"
  }'

Request body fields:

Field Type Required Notes
filename string yes Must include a supported extension (see the allowed types table below).
fileSize number yes Size in bytes. Must be between 1 and 1073741824 (1 GB).
fileType string yes MIME type. Must match filename's extension and be one of the supported content types.

Response (200):

{
  "metadata": { "success": true },
  "data": {
    "id": "A1B2c3D4e5F6g7H8",
    "name": "spec.pdf",
    "bucketName": "incoming",
    "url": "https://objectstorage.example.com/incoming/A1B2c3D4e5F6g7H8.pdf?X-...signature...",
    "originalUrl": "A1B2c3D4e5F6g7H8.pdf",
    "fileType": "DOCUMENT",
    "contentType": "application/pdf",
    "fileSize": 204800,
    "fileHash": "a9f…",
    "createdAt": "2026-04-23T10:30:00.000Z",
    "createdByCompanyId": "cmp_…",
    "createdByApiKeyId": "key_…"
  }
}

Important fields in the response:

2. Upload the bytes

PUT the raw file contents to the pre-signed URL. Both headers below are required and must match the fileType you sent in step 1 — otherwise the storage service will reject the upload with 403.

UPLOAD_URL="<paste value of data.url from step 1>"

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  -H "X-Upload-Content-Type: application/pdf" \
  --data-binary @spec.pdf

A successful upload returns 200 with an empty body. That is all — no finalize call is needed.

If the pre-signed URL has expired (older than ~1 hour), call POST /api/v2/files again to get a new one.


Allowed file types

Both filename extension and fileType MIME must be on this list. They must agree with each other.

Category Extensions MIME types
Image .jpg, .jpeg, .bmp, .png, .heic, .gif, .webp, .tiff image/jpeg, image/bmp, image/png, image/heic, image/gif, image/webp, image/tiff
Video .mp4, .webm video/mp4, video/webm
Document .doc, .docx, .pdf, .xls, .csv, .xlsx, .ppt, .pptx, .rtf application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf, application/vnd.ms-excel, text/csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, text/rtf

Maximum file size: 1 GB. Minimum: 1 byte.


Using the file afterwards

Once step 2 succeeds, the file is uploaded. To make it visible to the rest of the platform, reference its id from a resource that accepts file attachments (for example, creating a document, a certificate attachment, or a product image).

When that attaching resource is created, the platform automatically copies the file from the bucket into the correct destination and updates the database record. No additional call from your side is needed.

Files that are uploaded but never referenced from any resource stay in the bucket and are cleaned up periodically.


Common errors

Status When How to fix
400 filename has an unsupported extension, fileType is not on the allowed list, filename and fileType disagree, or fileSize is 0 / over 1 GB. Send a filename + MIME combination from the allowed-types table.
401 Missing or invalid companyapikey header. Check the header name (all lowercase) and the key value.
403 on the pre-signed PUT Upload URL has expired (> 1 hour), or the Content-Type / X-Upload-Content-Type sent in step 2 does not match the fileType from step 1. Request a fresh URL; make sure both headers equal the original fileType.