Skip to content

Examples

End-to-end examples that walk through presign → upload → finalize → convert → poll → download. All of them assume $KEY=ff_live_… is set in your environment.

curl

bash
#!/usr/bin/env bash
set -euo pipefail
KEY=${KEY:?set KEY=ff_live_...}
BASE=https://fileforge-api.aldrickb.app/v1

# 1. Presign
PRESIGN=$(curl -sS -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"filename":"photo.png","size":'"$(stat -c%s photo.png)"',"mime":"image/png"}' \
  "$BASE/files/presign-upload")
FILE_ID=$(jq -r .file_id <<<"$PRESIGN")
KEY_PATH=$(jq -r .storage_key <<<"$PRESIGN")
URL=$(jq -r .upload_url <<<"$PRESIGN")

# 2. Upload to MinIO
curl -fsS --upload-file photo.png -H "Content-Type: image/png" "$URL"

# 3. Finalize
curl -sS -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d "{\"storage_key\":\"$KEY_PATH\",\"original_name\":\"photo.png\",\"declared_mime\":\"image/png\"}" \
  "$BASE/files/$FILE_ID/finalize" >/dev/null

# 4. Convert
CONVERSION=$(curl -sS -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d "{\"input_file_id\":\"$FILE_ID\",\"target_format\":\"jpg\",\"preset\":{\"id\":\"web\"}}" \
  "$BASE/conversions")
CID=$(jq -r .id <<<"$CONVERSION")

# 5. Poll
while :; do
  STATUS=$(curl -sS -H "Authorization: Bearer $KEY" "$BASE/conversions/$CID" | jq -r .status)
  echo "status: $STATUS"
  case "$STATUS" in
    completed) break ;;
    failed|cancelled) echo "conversion ended in $STATUS" >&2; exit 1 ;;
  esac
  sleep 2
done

# 6. Download
curl -L -fsS -H "Authorization: Bearer $KEY" -o photo.jpeg "$BASE/conversions/$CID/output"
echo "wrote photo.jpeg"

Node (built-ins, no SDK)

ts
import { readFile, stat, writeFile } from 'node:fs/promises';

const KEY = process.env.KEY;
if (!KEY) throw new Error('set KEY=ff_live_...');
const BASE = 'https://fileforge-api.aldrickb.app/v1';
const auth = { Authorization: `Bearer ${KEY}` } as const;

async function api(path: string, init: RequestInit = {}) {
  const r = await fetch(BASE + path, {
    ...init,
    headers: { ...auth, ...(init.headers ?? {}), 'Content-Type': 'application/json' },
  });
  if (!r.ok) throw new Error(`${r.status} ${await r.text()}`);
  return r.json();
}

const path = 'photo.png';
const bytes = await readFile(path);
const size = (await stat(path)).size;

const presign = await api('/files/presign-upload', {
  method: 'POST',
  body: JSON.stringify({ filename: 'photo.png', size, mime: 'image/png' }),
});

const putRes = await fetch(presign.upload_url, {
  method: 'PUT',
  headers: { 'Content-Type': 'image/png' },
  body: bytes,
});
if (!putRes.ok) throw new Error(`upload failed: ${putRes.status}`);

await api(`/files/${presign.file_id}/finalize`, {
  method: 'POST',
  body: JSON.stringify({
    storage_key: presign.storage_key,
    original_name: 'photo.png',
    declared_mime: 'image/png',
  }),
});

const job = await api('/conversions', {
  method: 'POST',
  body: JSON.stringify({
    input_file_id: presign.file_id,
    target_format: 'jpg',
    preset: { id: 'web' },
  }),
});

while (true) {
  const status = await api(`/conversions/${job.id}`, { method: 'GET' });
  console.log('status:', status.status);
  if (status.status === 'completed') {
    const out = await fetch(`${BASE}/conversions/${job.id}/output`, { headers: auth, redirect: 'follow' });
    if (!out.ok) throw new Error(`download failed: ${out.status}`);
    await writeFile('photo.jpeg', Buffer.from(await out.arrayBuffer()));
    console.log('wrote photo.jpeg');
    break;
  }
  if (status.status === 'failed' || status.status === 'cancelled') {
    throw new Error(`conversion ended ${status.status}: ${status.error_message ?? 'no detail'}`);
  }
  await new Promise((r) => setTimeout(r, 2000));
}

Python (requests)

python
import os, time, requests

KEY = os.environ['KEY']  # ff_live_...
BASE = 'https://fileforge-api.aldrickb.app/v1'
HEADERS = {'Authorization': f'Bearer {KEY}'}

with open('photo.png', 'rb') as f:
    data = f.read()

presign = requests.post(
    f'{BASE}/files/presign-upload',
    headers={**HEADERS, 'Content-Type': 'application/json'},
    json={'filename': 'photo.png', 'size': len(data), 'mime': 'image/png'},
).json()

requests.put(
    presign['upload_url'],
    data=data,
    headers={'Content-Type': 'image/png'},
).raise_for_status()

requests.post(
    f"{BASE}/files/{presign['file_id']}/finalize",
    headers={**HEADERS, 'Content-Type': 'application/json'},
    json={
        'storage_key': presign['storage_key'],
        'original_name': 'photo.png',
        'declared_mime': 'image/png',
    },
).raise_for_status()

job = requests.post(
    f'{BASE}/conversions',
    headers={**HEADERS, 'Content-Type': 'application/json'},
    json={
        'input_file_id': presign['file_id'],
        'target_format': 'jpg',
        'preset': {'id': 'web'},
    },
).json()

while True:
    s = requests.get(f"{BASE}/conversions/{job['id']}", headers=HEADERS).json()
    print('status:', s['status'])
    if s['status'] == 'completed':
        break
    if s['status'] in ('failed', 'cancelled'):
        raise SystemExit(f"conversion {s['status']}: {s.get('error_message')}")
    time.sleep(2)

out = requests.get(
    f"{BASE}/conversions/{job['id']}/output",
    headers=HEADERS,
    allow_redirects=True,
)
out.raise_for_status()
with open('photo.jpeg', 'wb') as f:
    f.write(out.content)
print('wrote photo.jpeg')

Built solo on dedicated metal.