API docs
Everything the website does, your scripts can do: upload a file, ask for a format, wait, download. Five requests, plain JSON over HTTPS.
1. Get a key
Create one on the API keys page. It starts with bck_, is shown once, and acts as your account with your plan's limits. Send it on every request:
Authorization: Bearer bck_…
Keep it secret, like a password. Revoke it on the same page and it stops working at once.
2. Create the file
Say what you are about to upload. kind is image or video, and size_bytes is the file's exact size. The answer holds the file's id and an upload_url, valid for an hour.
export BISACOMPRESS_KEY=bck_…
FILE=$(curl -s https://bisacompress-api.manabisa.com/api/v1/files \
-H "Authorization: Bearer $BISACOMPRESS_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"photo.jpg","kind":"image","size_bytes":'"$(wc -c < photo.jpg)"'}')
# {"file":{"id":"0192…","status":"uploading",…},"upload_url":"https://…"}
FILE_ID=$(echo "$FILE" | jq -r .file.id)
UPLOAD_URL=$(echo "$FILE" | jq -r .upload_url)3. Upload the bytes
PUT the file to upload_url as it is. This goes straight to storage, so it needs no Authorization header.
curl -s -X PUT --upload-file photo.jpg "$UPLOAD_URL"
4. Start a job
Choose the output format and a preset: small, balanced (the default), or high.
| Kind | Formats |
|---|---|
| image | webp, jpeg, avif |
| video | mp4 (H.264), webm (VP9) |
JOB_ID=$(curl -s https://bisacompress-api.manabisa.com/api/v1/jobs \
-H "Authorization: Bearer $BISACOMPRESS_KEY" \
-H "Content-Type: application/json" \
-d '{"file_id":"'"$FILE_ID"'","format":"webp","preset":"balanced"}' | jq -r .id)
# the job: {"id":"0192…","status":"queued","progress":0,…}5. Wait, then download
Ask for the job every second or two. status goes queued → processing (with progress 0–100) → done or failed. When it is done the answer carries a download_url, valid for an hour.
while :; do
JOB=$(curl -s https://bisacompress-api.manabisa.com/api/v1/jobs/$JOB_ID -H "Authorization: Bearer $BISACOMPRESS_KEY")
STATUS=$(echo "$JOB" | jq -r .job.status)
[ "$STATUS" = done ] && break
[ "$STATUS" = failed ] && { echo "$JOB" | jq -r .job.error; exit 1; }
sleep 2
done
curl -s -o photo.webp "$(echo "$JOB" | jq -r .download_url)"Everything else
GET /usage: your plan, storage, and how many jobs you have left today.GET /filesandGET /jobs: your 100 newest, newest first.DELETE /files/{id}: deletes a file and its result, and gives back the storage. Results are kept until you do.GET /plans: every plan's limits and prices; no key needed.
Limits
| Plan | Per file | Storage | Jobs at a time | Jobs per 24 h |
|---|---|---|---|---|
| Free | 50 MB | 2 GB | 3 | 25 |
| Pro | 2 GB | 100 GB | 50 | 2,000 |
| Max | 5 GB | 1 TB | 100,000 | 10,000 |
Every key and session also shares a limit of 120 requests a minute. GET /usage always has your current numbers.
Errors
Every error is JSON, {"error":"…"}, with one of these statuses:
| 400 | Something in the request is wrong: a missing field, an unknown format, or a format for the other kind. |
| 401 | The key is missing, revoked, or expired. |
| 402 | Your plan does not include cloud compression. |
| 403 | Your storage is full, the file is not yours, or the route needs a signed-in session (API keys cannot manage keys). |
| 404 | No such file or job on your account. |
| 409 | The file still has a job in progress, so it cannot be deleted yet. |
| 413 | The file is larger than your plan allows. |
| 429 | Too many jobs in progress, the daily job limit, or too many requests. Wait and retry. |
Questions: support@manabisa.com.