Quickstart¶
From signup to a processed image in under five minutes.
curl -X POST https://api.purlo.dev/v1/image \
-H "Authorization: Bearer purlo_YOUR_KEY" \
-F 'operations={"resize":{"w":800},"format":"webp","quality":80,"strip":true}' \
-F "image=@photo.jpg" \
-o out.webp
That resizes photo.jpg to 800px wide, converts it to WebP, compresses it at
quality 80, and strips EXIF/GPS metadata — in one call. out.webp is the result.
Swap in your own key and file and you're done.
1. Get an API key¶
See Authentication for the full flow. Short version:
- Free tier (no card):
POST /v1/signupwith your email, click the verification link, and your key is issued — about a minute. - Paid tiers:
POST /v1/billing/checkoutwith atier, complete Stripe Checkout, and your key is issued on the success page.
Every key looks like purlo_xxxxxxxxxxxxxxxxxxxxxxxx. It's shown once at
creation — store it somewhere safe.
2. Make the call¶
Send your image as multipart/form-data (field image) along with an
operations JSON object describing what to do to it:
curl -X POST https://api.purlo.dev/v1/image \
-H "Authorization: Bearer purlo_YOUR_KEY" \
-F 'operations={"resize":{"w":800},"format":"webp","quality":80,"strip":true}' \
-F "image=@photo.jpg" \
-o out.webp
You can also point Purlo at a URL instead of uploading a file — see
Reference for the url form.
3. Check the response¶
A successful call returns the processed image bytes directly, with these headers:
X-Purlo-Output-Format: webp
X-Purlo-Output-Bytes: 42110
X-Purlo-Operations: resize,format=webp,quality=80,strip
X-Purlo-Quota-Limit: 1000
X-Purlo-Quota-Remaining: 999
An error comes back as JSON instead, e.g.:
{ "error": { "code": "invalid_operations", "message": "resize.fit must be one of: inside, outside, cover, contain, fill." } }
Full list in Errors & limits.
Next¶
- Endpoint reference — every operation and parameter.
- Examples — the same call in JavaScript, PHP, and Python.
Running against a local dev server¶
If you're running Purlo yourself (npm start), the API listens on
http://localhost:3000 instead of https://api.purlo.dev, and a seeded dev
key (dev_local_key, free tier) works out of the box: