Skip to content

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.

bash
curl -H "Authorization: Bearer ff_live_…" \
     https://fileforge-api.aldrickb.app/v1/formats

Shape (abbreviated):

jsonc
{
  "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.

bash
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/conversions

Response (202 Accepted):

json
{
  "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.

bash
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/bulk

Response:

json
{
  "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.

jsonc
{
  "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.

bash
curl -L -H "Authorization: Bearer ff_live_…" \
     -o budget.pdf \
     https://fileforge-api.aldrickb.app/v1/conversions/5b3e...11/output

Returns 400 not_ready if the conversion isn't completed yet. Returns 404 if the conversion doesn't belong to your account.

Built solo on dedicated metal.