Reference

Job polling

GET /v1/jobs/{job_id} — poll an async optimize, smartcrop, or multi-format job until it's done.

Any call made with ?async=true — to /v1/optimize, /v1/optimize/multi, or /v1/smartcrop — returns a job_id. Poll it here until status stops being "processing".

GET /v1/jobs/{job_id}
Terminal
curl https://api.helloimg.io/v1/jobs/job_5f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c \
  -H "Authorization: Bearer <your API key>"

Unauthorized (401) — like every other /v1/* route, a missing or malformed Authorization header answers:

{ "error": "invalid api key" }

Single-format job

Processing:

{
  "job_id": "job_5f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c",
  "status": "processing"
}

Completed:

{
  "job_id": "job_5f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c",
  "status": "completed",
  "progress": 100,
  "result": {
    "image_url": "https://cdn.helloimg.io/helloimg-optimized/opt_job_5f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c.webp",
    "original_size": 855000,
    "new_size": 111000,
    "percent": 87.03,
    "processing_time_ms": 26
  }
}

Failed:

{
  "job_id": "job_5f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c",
  "status": "failed",
  "error": "..."
}

Not found (404) — the job ID doesn't exist, or it's more than an hour old:

{
  "error": "Job not found",
  "message": "Job may have expired (TTL: 1 hour) or invalid job_id"
}

Multi-format job

A job ID from /v1/optimize/multi aggregates every requested format into one response. status is "processing" while any format is still running, "completed" once at least one format finished and none are pending, or "failed" if every format failed:

{
  "job_id": "multi_5f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c",
  "status": "completed",
  "progress": 100,
  "results": [
    {
      "format": "jpeg",
      "status": "completed",
      "result": {
        "image_url": "https://cdn.helloimg.io/helloimg-optimized/opt_multi_..._jpeg.jpg",
        "original_size": 855000,
        "new_size": 214000,
        "percent": 74.97
      },
      "error": null
    },
    {
      "format": "webp",
      "status": "completed",
      "result": {
        "image_url": "https://cdn.helloimg.io/helloimg-optimized/opt_multi_..._webp.webp",
        "original_size": 855000,
        "new_size": 111000,
        "percent": 87.03
      },
      "error": null
    }
  ]
}

progress is the percentage of formats completed while any are still processing, and 100 once the job is terminal — even if some formats failed, so a client watching progress isn't left at a frozen value.

Notes

  • Job results expire after 1 hour — fetch and store the image_url before then.
  • A completed result can also come back immediately, with 200 instead of 202, straight from the original optimize/smartcrop call — that happens when the exact same image and options were already optimized recently. There's nothing to poll in that case.