FOLIO REST API
Upload. Read. Serve.
Create a workspace and an API key in the dashboard. Call this API from your server with Authorization: Bearer $FOLIO_KEY. Send your customer ID in X-Folio-Tenant; omitting it uses the default tenant.
An API key grants access to every tenant in its workspace. Authorize your end user in your app before choosing their tenant. Give browsers signed links instead of secret keys.
curl "https://folio.atef.dev/api/v1/files" \
-H "Authorization: Bearer $FOLIO_KEY" \
-H "X-Folio-Tenant: customer_123" \
-F "[email protected]" \
-F "purpose=invoice" \
-F 'metadata={"orderId":"order_456"}'The response contains file.id, status, and derivatives. Read the file until the rendition you need says ready. Originals are available immediately; preview failures leave the original intact.
curl "https://folio.atef.dev/api/v1/files/$FILE_ID/links" \
-H "Authorization: Bearer $FOLIO_KEY" \
-H "X-Folio-Tenant: customer_123" \
-H "Content-Type: application/json" \
-d '{"variant":"preview"}'Resolve the returned relative url against https://folio.atef.dev, then use it in your app. A link grants access to one file rendition and expires after five minutes. Choose content, thumbnail, preview, or optimized.
Endpoints
| Method | Path | What it does |
|---|---|---|
| POST | /files | Upload multipart field file. Optional purpose, profile, and metadata (JSON object). |
| GET | /files | List tenant files with limit=1–100 and cursor; response includes nextCursor. |
| GET | /files/:id | Read metadata, processing status, and available renditions. |
| GET | /files/:id/content | Download the original. |
| GET | /files/:id/thumbnail | Get an image thumbnail or PDF first-page preview. |
| GET | /files/:id/preview | Get a visual preview. |
| GET | /files/:id/optimized | Get the compressed WebP image rendition. |
| POST | /files/:id/links | Create a five-minute signed link for one rendition. |
| POST | /files/:id/retry | Retry failed preview processing. |
| DELETE | /files/:id | Delete the logical file and release its allowance. |
| GET | /usage | Read workspace and tenant storage usage and limits. |
| GET | /tenants | List tenants in your workspace. |
| PUT | /tenants/:id | Set a limit with {"limitBytes":100000000}; null removes the limit. |
Limits and errors
Free storage is 3,000,000,000 bytes of originals. Automatic renditions are included. Uploads are limited to 25 MiB. Tenant limits apply inside the workspace allowance, including concurrent uploads.
Errors use {"error":{"code":"…","message":"…","requestId":"…"}}. Invalid keys return 401; unknown or other-tenant files return 404; pending previews return 409; unsupported renditions return 415; upload size or storage quotas return 413 with a specific error code. Respect Retry-After on 429, and include the request ID when asking for support.
This release uses one-file HTTP uploads and polling. Uploads do not yet support idempotency keys; avoid blindly retrying a request whose result is unknown. Resumable uploads, browser upload tokens, webhooks, AI jobs, and paid storage are later work.