Documentation
Uploads and Jobs
Upload images, create async jobs, and structure resize, optimize, tile, grid_render, or tile_patch requests.
Last updated: May 11, 2026
Uploads and processing are intentionally split into two steps.
1. Upload the source asset
POST /v1/assets
- Requires an API key.
- Accepts still-image
jpeg,png,webp,gif,avif,heif, andjxluploads when the current runtime can decode them. - GIF and animated GIF inputs are handled as still images. Outputs are flattened to one frame.
- Animated WebP is not part of the default upload path.
- Validates MIME type and upload size.
- Applies an account rate limit of
30uploads per minute. - Stores the source image for later processing jobs.
Example:
curl -X POST \
-H "Authorization: Bearer igk_..." \
-F "file=@/path/to/source.png" \
https://api.imagegrid.dev/v1/assets
2. Create an async job
POST /v1/jobs
- Applies an account rate limit of
60job-creation requests per minute. - Accepted jobs may stay queued longer when the service is busy.
- Queue pressure does not introduce a separate busy rejection for ordinary backlog.
- A synchronous
429withcode: "worker_capacity_exceeded"is only used when one job exceeds current processing limits.
Supported operations:
resizeoptimizetilegrid_rendertile_patch
Resize example:
{
"asset_id": "6ea91098-6c8c-46ec-869a-a3ef2d4f4d2c",
"operation": "resize",
"options": {
"width": 1600,
"height": 900,
"fit": "inside",
"format": "webp"
}
}
Optimize example:
{
"asset_id": "6ea91098-6c8c-46ec-869a-a3ef2d4f4d2c",
"operation": "optimize",
"options": {
"format": "jpeg",
"quality": 82
}
}
Tile example:
{
"asset_id": "6ea91098-6c8c-46ec-869a-a3ef2d4f4d2c",
"operation": "tile",
"options": {
"tile_size": 128,
"format": "png",
"strategy": "deepzoom"
}
}
Grid render example:
{
"operation": "grid_render",
"options": {
"width": 640,
"height": 320,
"block_width": 32,
"block_height": 32,
"format": "png"
}
}
Tile patch example:
{
"operation": "tile_patch",
"options": {
"tileset_id": "6ea91098-6c8c-46ec-869a-a3ef2d4f4d2c",
"patches": [
{
"type": "color",
"color": "#ff0000",
"x": 0,
"y": 0,
"width": 32,
"height": 32
}
]
}
}
3. Poll the job
GET /v1/jobs/{id}
The response includes status plus any generated artifacts.
Polling is rate limited to 240 requests per minute per account. If you receive 429, honor Retry-After and back off with jitter instead of retrying immediately.
Typical statuses:
queuedprocessingsucceededfailed
Operational notes
- Quotas may deny uploads or jobs before processing starts.
- Optional AV scanning can fail closed when the scanner is unavailable.
- Artifact bytes are not returned inline from the job endpoint. Use artifact metadata and signed download URLs instead.
grid_renderandtile_patchdo not takeasset_id.resize,optimize, andtiledo.- If your workflow needs animation preserved, read Animated Image Support before relying on the default still-image path.
- See Operations for the complete option schemas and defaults.
Error-handling guidance
- Treat
429-style quota or policy failures as actionable, not retry-forever failures. - Retry transient
5xxresponses with backoff. - Record the asset ID and job ID in your logs so support can trace the run later.
- Read Errors for signed download failures, validation details, and async job failure fields.