Skip to main content
Developer API · Early access

Convert & compress files from your code.

One REST endpoint, one header. Send a file or a URL, poll for a signed download link. The same engines that power filewhirl.com — no JWT, no SDK required. The API is in early access — join the waitlist and we'll get you set up with a key.

x-api-key auth

No JWT, no Authorization header — call it from any backend.

Private by default

Files deleted within an hour; signed URLs only.

Usage-metered

Planned: a $29/mo plan + pay-as-you-go credits. Free during early access.

Authentication

The API is in early access. Request a key and you'll send it on every request like this:

header
x-api-key: ff_live_your_key_here

Keys start with ff_live_ and are shown only once. Keep them server-side — anyone with a key can spend your quota.

Create a job

POST https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api — upload a file as multipart, or send a public URL as JSON. The to field is the target format; pass the same format as the input to compress it. Returns 202 with an id, token and status_url.

cURL — upload a file
curl -X POST https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api \
  -H "x-api-key: ff_live_your_key_here" \
  -F "file=@photo.png" \
  -F "to=jpg"
cURL — convert from a URL
curl -X POST https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api \
  -H "x-api-key: ff_live_your_key_here" \
  -H "content-type: application/json" \
  -d '{ "to": "mp3", "url": "https://example.com/clip.mp4" }'

Poll for the result

GET https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api?id=…&token=… every ~1.5s until status is done or error. On success you get a signed output_url valid for one hour.

cURL — poll status
curl "https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api?id=JOB_ID&token=JOB_TOKEN" \
  -H "x-api-key: ff_live_your_key_here"

Full examples

Node.js
const API = "https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api";
const KEY = process.env.FILEWHIRL_API_KEY;

// 1. Create a job (upload a file)
const form = new FormData();
form.append("file", fileBlob, "photo.png");
form.append("to", "jpg");

const res = await fetch(API, { method: "POST", headers: { "x-api-key": KEY }, body: form });
const { id, token, status_url } = await res.json();

// 2. Poll until done (every ~1.5s; outputs are ready within seconds-minutes)
let job;
do {
  await new Promise((r) => setTimeout(r, 1500));
  job = await (await fetch(status_url, { headers: { "x-api-key": KEY } })).json();
} while (job.status === "queued" || job.status === "processing");

if (job.status === "done") console.log("Download:", job.output_url);
else throw new Error(job.error);
Python
import os, time, requests

API = "https://fkgvpgpdkktikfzspnib.supabase.co/functions/v1/convert-api"
KEY = os.environ["FILEWHIRL_API_KEY"]
H = {"x-api-key": KEY}

# 1. Create a job (or pass JSON {"to": "...", "url": "..."} instead of a file)
with open("photo.png", "rb") as f:
    r = requests.post(API, headers=H, files={"file": f}, data={"to": "jpg"})
job = r.json()
sid, token = job["id"], job["token"]

# 2. Poll until done
while True:
    time.sleep(1.5)
    s = requests.get(API, headers=H, params={"id": sid, "token": token}).json()
    if s["status"] in ("done", "error"):
        break

print(s.get("output_url") or s["error"])

Responses & status codes

CodeMeaning
202Job created — returns { id, token, status, billing, status_url }.
200Poll result — { status, output_url?, output_size?, engine?, error? }.
400Bad request — missing `to`, or no file/url provided.
401Invalid or missing x-api-key.
402Quota exceeded — subscribe or buy credits ({ error, reason, hint }).
404Unknown job id/token on a poll.
500Server error (upload/metering/internal) — safe to retry.
  • Up to 2 GB per file.
  • Output URLs are signed and expire after 1 hour.
  • One usage unit per job; failed-to-queue jobs are auto-refunded.
  • No JWT or Supabase header needed — just x-api-key.

Common questions

How do I get an API key?+

The API is in early access. Email hello@filewhirl.com to request a key — keys look like ff_live_… and are shown once, so store it securely. Self-serve signup and billing go live soon.

Do I need a Supabase or Authorization header?+

No. The endpoint is authenticated solely by the x-api-key header — no JWT, no Authorization, no apikey header. That's why it's safe to call from any backend.

What can I convert or compress?+

Anything the website supports — images, video, audio, documents and archives, plus same-format compression (e.g. to=jpg on a jpg re-encodes it smaller). The full format matrix is the same one powering filewhirl.com.

How is usage billed?+

One unit per job. The API plan includes a monthly allowance; once it's used up, jobs draw from pay-as-you-go credits. If neither has room the API returns 402 with a reason — you're never charged for a job that fails to queue (units are refunded on insert failure). During early access there's no charge.

How big can files be and how long are outputs available?+

Up to 2 GB per file. Output download URLs are signed and valid for 1 hour; both the upload and the result are deleted after that window.

Is there a rate limit?+

There's no hard HTTP rate limit today — throughput is governed by your plan's concurrency and monthly quota. Be a good citizen: poll a job's status every ~1.5s rather than in a tight loop.

Ready? Join the API waitlist · see pricing · browse the tools · OpenAPI spec · Postman collection.