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')