Conversions
Conversions are async — every POST /v1/conversions returns immediately with status: 'queued', and you poll GET /v1/conversions/{id} until status is completed, failed, or cancelled. Required scope: convert:write.
GET /v1/formats
Returns the tier-filtered preset matrix. Same data the web UI consumes; useful for building a form or validating presets client-side.
curl -H "Authorization: Bearer ff_live_…" \
https://fileforge-api.aldrickb.app/v1/formatsShape (abbreviated):
{
"formats": {
"image/png": {
"jpg": {
"worker": "image",
"freeAllowed": true,
"presets": [
{ "id": "web", "label": "Web (q=82)", "params": { "quality": 82 } },
{ "id": "high", "label": "High quality (q=92)", "params": { "quality": 92 } },
{ "id": "lossless", "label": "Lossless / max", "params": { "quality": 100 } }
]
}
}
}
}POST /v1/conversions
Enqueues a single conversion. The input_file_id must point at a file you already finalized.
curl -X POST \
-H "Authorization: Bearer ff_live_…" \
-H "Content-Type: application/json" \
-d '{
"input_file_id": "9f6c...8e",
"target_format": "pdf",
"preset": { "id": "standard" }
}' \
https://fileforge-api.aldrickb.app/v1/conversionsResponse (202 Accepted):
{
"id": "5b3e...11",
"status": "queued",
"worker_type": "document",
"target_format": "pdf",
"preset": { "id": "standard", "params": {} }
}Valid (target_format, preset.id) pairs are listed under each entry of GET /v1/formats. There is no universal "default" preset — every worker exposes a small named set (e.g. web / high / lossless for images, standard / linearize for PDF, low / web / high / very-high for lossy audio). Always read the matrix before constructing the request.
preserve_metadata: true is allowed for Pro/Enterprise only; free returns 403. target_format must be allowed for the source MIME at your tier (see errors).
POST /v1/conversions/bulk
Submit up to tier.bulk_max conversions at once (Pro: 20; Enterprise: 100). Every item burns one conversion-rate token, so a 20-item batch from a fresh window will be accepted but follow-up calls in the same minute will rate-limit.
curl -X POST \
-H "Authorization: Bearer ff_live_…" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "input_file_id": "...a", "target_format": "pdf", "preset": { "id": "standard" } },
{ "input_file_id": "...b", "target_format": "pdf", "preset": { "id": "standard" } }
]
}' \
https://fileforge-api.aldrickb.app/v1/conversions/bulkResponse:
{
"bulk_id": "f1a0...77",
"total": 2,
"items": [
{ "conversion_id": "...", "input_file_id": "...a", "target_format": "pdf" },
{ "conversion_id": "...", "input_file_id": "...b", "target_format": "pdf" }
]
}There's no aggregate GET /v1/conversions/bulk/:id on the public API in the v1.0.0 beta — poll each conversion_id independently. The aggregate endpoint exists on the App API for the web UI's bulk-grid view; if you need it on the public API, open an issue.
GET /v1/conversions/{id}
Status snapshot + a fresh presigned download URL when complete.
{
"id": "5b3e...11",
"status": "completed", // queued | scanning | processing | completed | failed | cancelled
"progress_pct": 100,
"worker_type": "document",
"source_format": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"target_format": "pdf",
"attempt_count": 1,
"error_code": null,
"error_message": null,
"queued_at": "2026-05-07T12:34:56Z",
"started_at": "2026-05-07T12:34:58Z",
"completed_at": "2026-05-07T12:35:04Z",
"duration_ms": 6112,
"output": {
"file_id": "...",
"download_url": "https://minio.lan/...?X-Amz-Signature=...",
"expires_in": 300
}
}Poll every 1–2 seconds while status is non-terminal. The download_url in the response is regenerated on every call and lives for 5 minutes.
GET /v1/conversions/{id}/output
Convenience: 302-redirects to a fresh presigned download URL. Lets you curl -L straight to the bytes without parsing JSON.
curl -L -H "Authorization: Bearer ff_live_…" \
-o budget.pdf \
https://fileforge-api.aldrickb.app/v1/conversions/5b3e...11/outputReturns 400 not_ready if the conversion isn't completed yet. Returns 404 if the conversion doesn't belong to your account.
