⚡ Developer API · Beta

Automate your AVIF, WebP, JPEG and PNG compression workflow

Hook up your server to optimize all your images on the fly. Join the developers using the TrueSmush API — enter your name and email to retrieve your key and get started right now.

🎁 500 free compressions each month · No payment method required

Client libraries:🟩 Node.js🐍 Python🐘 PHP🔗 cURL

See API pricing & credit bundles →

How it works

1

Get an API key

Sign up, then create a key. The key is sent as an Authorization: Bearer header — the browser proxy forwards it for you.

2

Upload your image

POST multipart with the file plus an optional format + quality. You get a jobId back immediately.

3

Poll & download

Poll GET /api/jobs/:id until status is done, then download the result. One-shot, deleted after delivery.

Quickstart

Base URL: https://tinypixel-api.crunchpress.com

cURL — compress one image

bash
curl -X POST https://tinypixel-api.crunchpress.com/api/upload \
  -H "Authorization: Bearer $TINYPIXEL_KEY" \
  -F "[email protected]" \
  -F "format=webp"

cURL — convert to multiple formats & zip

bash
# 1) upload as AVIF
curl -X POST https://tinypixel-api.crunchpress.com/api/upload \
  -H "Authorization: Bearer $TINYPIXEL_KEY" \
  -F "[email protected]" -F "format=avif"

# 2) grab the returned jobId, then bundle results:
curl -X POST https://tinypixel-api.crunchpress.com/api/zip \
  -H "Authorization: Bearer $TINYPIXEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jobs":["<jobId>"]}'

# 3) download the zip (one-shot)
curl -OJ https://tinypixel-api.crunchpress.com/api/zip/<zipId>/download \
  -H "Authorization: Bearer $TINYPIXEL_KEY"

Node.js

javascript
const form = new FormData();
form.append('file', new Blob([buf], { type: 'image/png' }), 'hero.png');
form.append('format', 'webp');

const res = await fetch('https://tinypixel-api.crunchpress.com/api/upload', {
  method: 'POST',
  headers: { Authorization: 'Bearer ' + process.env.TINYPIXEL_KEY },
  body: form, // fetch sets the boundary for you — never set Content-Type
});
const { job } = await res.json();
// poll GET /api/jobs/:id until status === 'done', then download.

Python

python
import requests

r = requests.post(
    "https://tinypixel-api.crunchpress.com/api/upload",
    headers={"Authorization": f"Bearer {KEY}"},
    files={"file": open("hero.png", "rb")},
    data={"format": "webp"},
)
job = r.json()["job"]  # poll GET /api/jobs/<id> until done

PHP (WordPress style)

php
$curl = curl_init('https://tinypixel-api.crunchpress.com/api/upload');
curl_setopt_array($curl, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $KEY],
  CURLOPT_POSTFIELDS => [
    'file' => new CURLFile('/path/to/hero.png'),
    'format' => 'webp',
  ],
]);
$res = json_decode(curl_exec($curl), true);

API reference

All endpoints live under /api/* on the same base URL. Responses are JSON.

MethodEndpointDescription
POST/api/uploadUpload an image and compress/convert it. Multipart form field `file` (max 5 MB), optional `format` (webp | avif | jxl | png | jpeg | same) and `quality` (0–100).
GET/api/jobs/:idGet job status + result metadata (input/output sizes, savings, format).
GET/api/jobs/:id/downloadOne-shot download of the compressed output. The file is deleted after delivery.
GET/api/jobs?mine=1List your job history (requires X-Session-Token). Supports `limit` + `offset`.
POST/api/zipBundle multiple results: body `{ "jobs": ["<jobId>", ...] }`. Returns a batch zip id.
GET/api/zip/:id/downloadOne-shot download of the batch zip. Deleted after delivery; stale zips cleaned hourly.
POST/api/auth/signupCreate an account: `{ "email", "password" }`. Returns a session token.
POST/api/auth/loginLog in: `{ "email", "password" }`. 5 failed attempts → 15-minute lockout.
POST/api/auth/magicMagic-link login: `{ "email" }`. Emails a one-time link (15 min expiry). Always returns ok.
GET/api/auth/meCurrent user info. Pass session via `X-Session-Token` header.
GET/healthLiveness probe — returns `{ "ok": true }` when the worker is healthy.

Rate limits

Fair-use limits per API key (or per session token). 429 responses include a Retry-After header.

Uploads600 POST /minper API key / session
Reads1,800 GET /minjob status, downloads, history
Auth30 /minlogin, signup, magic-link
Login attempts5 per emailthen 15-min lockout

Errors

Standard HTTP codes. Error bodies look like { "error": "..." }.

400Bad request — missing file, unknown format, invalid JSON.
401Missing or invalid API key / session token.
404Job, zip or endpoint not found (or output expired — TTL is 48h).
409Output already downloaded / expired (one-shot download).
413File too large (max 5 MB per image, 20 per batch).
429Rate limited. Check Retry-After header.
500Engine failure — retry, or open an issue on GitHub.