Transformations API
Resize, crop and convert an uploaded image or a remote source enabled for your account. Choose effects, output format and storage mode.
On this page
Example outputs
Original · 1000 × 750 PNG
Thumbnail · 600 × 600 WebPThe source and thumbnail illustrate a product image workflow. Explore the detailed examples for product thumbnailsor responsive variants.
Endpoints and authentication
| Method | Path | Response |
|---|---|---|
POST | /v1/projects/{projectId}/transforms | 200 · image bytes |
GET | /v1/projects/{projectId}/transforms | 200 · paginated metadata |
GET | /v1/projects/{projectId}/transforms/{id} | 200 · metadata |
GET | /v1/projects/{projectId}/transforms/{id}/content | 200 · image bytes, or authenticated 304 |
DELETE | /v1/projects/{projectId}/transforms/{id} | 200 · JSON message; idempotent deletion |
Request body
| Field | Requirement | Behavior |
|---|---|---|
imageId OR url | Exactly one | An owned, ready original UUID, or a permitted remote HTTP(S) URL. |
mode | Optional | CACHE (default), PERSIST or EPHEMERAL. |
maxOutputBytes | Optional positive integer | Lowers the configured output byte ceiling. Cannot exceed that ceiling; reserves capacity before work. |
transform | Optional object | Options below. Omit for normalized defaults; unknown properties are rejected. |
curl --fail-with-body --silent --show-error \
--request POST "$IMAZEO_API_ORIGIN/v1/projects/$IMAZEO_PROJECT_ID/transforms" \
--header "X-API-Key: $IMAZEO_API_KEY" \
--header 'Content-Type: application/json' \
--data "{\"imageId\":\"$IMAZEO_IMAGE_ID\",\"mode\":\"CACHE\",\"transform\":{\"width\":600,\"height\":600,\"fit\":\"cover\",\"format\":\"webp\",\"quality\":80}}" \
--dump-header response-headers.txt \
--output "$IMAZEO_OUTPUT"Use the environment setup in Quickstart. The Node.js example uploads and transforms, so it is an alternative workflow rather than an extra step.
Transformation parameters
| Property | Accepted value | Default / behavior |
|---|---|---|
width, height | Positive integers ≤ configured MAX_OUTPUT_DIMENSION (hard ceiling 10000). | Omitted dimensions preserve the oriented/cropped size; one dimension preserves proportions. |
fit | cover | contain | inside | fill | Both dimensions: cover. Otherwise: inside. All except inside require both dimensions. |
crop | {left, top, width, height} | Integer coordinates in oriented, trimmed source pixels. Must fit the source; width/height positive. |
rotate | Integer multiples of 90, −360…360 | 0; normalized to 0, 90, 180 or 270. |
flip, flop | boolean | false; vertical and horizontal reflection respectively. |
format | jpeg | png | webp | avif | gif | webp; SVG is input only. |
quality | Integer 1…100 | 80; encoder quality for JPEG/WebP/AVIF, palette quantization for PNG, palette colors for GIF. |
optimize | boolean | true; bounded encoder effort, not a file-size guarantee. |
stripMetadata | true only | Always true. false is rejected. EXIF/GPS/ICC omitted from derivatives. |
grayscale, negate | boolean | false. Negate inverts color channels, preserving alpha. |
blur | Number 0.3…10 | Omitted: skipped; sigma rounded to two decimals. |
sharpen | Number 0.5…5 | Omitted: skipped; sigma rounded to two decimals. |
brightness, saturation | Number 0…3 | Omitted: skipped; 1 leaves the factor unchanged. Rounded to three decimals. |
hue | Integer −180…180 | Omitted: skipped; degrees of hue rotation. |
trim | true or {threshold: integer 1…100} | Omitted: skipped; true uses threshold 10. Runs before crop. |
extend | {top, right, bottom, left} | All four integer sides required, each ≥0; at least one >0. Each side and opposite-side sum ≤ configured max dimension. |
background | #RGB or #RRGGBB | #ffffff; contain padding, extend padding and JPEG transparency flattening. |
position | center | entropy | attention | center; crop focal strategy, mainly for cover. attention requires more processing. |
Processing order and animation
EXIF orientation → trim → crop → flip/flop → right-angle rotation → resize → brightness/saturation/hue → grayscale → negate → blur → sharpen → extend → encode. Crops refer to the oriented and trimmed source. Final dimensions include padding and remain subject to pixel and dimension limits.
cover fills and crops; contain preserves proportions and pads with background; inside preserves proportions within bounds; fill stretches. Both dimensions default to cover; one or neither defaults to inside.
Animation is preserved only for supported GIF/WebP output and resizing. Animated crop, rotation, flip/flop, contain, grayscale, negate, blur, sharpen, modulation, trim, extend and non-center positioning are rejected. Frame and aggregate pixel limits also apply. Background removal and watermark/composite are not supported.
Remote URL input
Replace imageId with url; do not send both. Your account must have remoteUrlEnabled. A URL must be publicly routable HTTP(S) on ports 80/443, without user information or a fragment. Private, loopback, metadata and other blocked destinations are rejected; redirects are revalidated. Only submit URLs you have permission to process.
{
"url": "https://example.com/replace-with-your-image.jpg",
"mode": "CACHE",
"transform": {
"width": 600,
"format": "webp"
}
}# Save a JSON file named remote-request.json with the body shown below.
curl --fail-with-body --silent --show-error \
--request POST "$IMAZEO_API_ORIGIN/v1/projects/$IMAZEO_PROJECT_ID/transforms" \
--header "X-API-Key: $IMAZEO_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @remote-request.json \
--output remote-output.webpRemote source bytes are fetched and validated on every request, even before a cache hit. They are not added to your original library; stored derivative metadata has imageId: null. The source URL is not retained or logged by this flow. A remote hit still consumes a remote-fetch credit and output bandwidth.
Storage modes and caching
| Mode | Behavior | Accounting |
|---|---|---|
| PERSIST | Store until explicit or original-image deletion. | Processing, stored bytes and transfer usage apply. |
CACHE | Reuse matching source bytes and normalized settings within the configured lifetime. | Hit uses output bandwidth; expired stored bytes count until cleanup. |
EPHEMERAL | Always computes, bypasses derivative cache, saves no output media file. | Processing and bandwidth apply; operation records remain. |
Binary response and later retrieval
POST returns HTTP 200 image bytes, not a JSON data field. Headers include X-Transformation-ID, X-Cache (HIT or MISS), ETag, Content-Type, Content-Length, X-Image-Width, X-Image-Height, X-Image-Format and X-Request-ID. POST uses Cache-Control: private, no-store. EPHEMERAL IDs do not identify a downloadable stored file.
GET content uses private, no-cache and Vary: Authorization, X-API-Key. Send If-None-Match with the prior ETag for revalidation. A matching validator returns an empty 304 only after authorization, with no bandwidth charge. This conditional behavior applies to derivative content, not original content.
# Set IMAZEO_TRANSFORMATION_ID from X-Transformation-ID and IMAZEO_ETAG
# to the exact quoted ETag received earlier. Stored modes only.
curl --silent --show-error --fail-with-body \
"$IMAZEO_API_ORIGIN/v1/projects/$IMAZEO_PROJECT_ID/transforms/$IMAZEO_TRANSFORMATION_ID/content" \
--header "X-API-Key: $IMAZEO_API_KEY" \
--header "If-None-Match: $IMAZEO_ETAG" \
--dump-header revalidation-headers.txt --output derivative-response.binMetadata GET returns data with _id, projectId, nullable imageId, sourceHash, transformHash, normalized spec, mode, bytes, processingMs, status, sha256, metadata, nullable expiresAt and createdAt. The list uses page/limit pagination and includes expired or pending-deletion records for cleanup. A single metadata GET requires a ready, unexpired result.
DELETE is idempotent and refunds stored bytes only. It returns a JSON message envelope. Deletion, expiration and cache cleanup do not refund earlier processing or transfers.
Errors and recovery
Failures use a JSON error envelope even when the successful response is binary. Check status before treating the body as an image. Request IDs are illustrative below.
{
"success": false,
"error": {
"code": "TRANSFORM_INVALID",
"message": "Transformation parameters are invalid or unsupported.",
"details": {}
},
"meta": {
"requestId": "example-request-id"
}
}Fix TRANSFORM_INVALID before retrying. REMOTE_URL_INVALID/BLOCKED are 400, REMOTE_FETCH_FAILED is 502 and disabled remote entitlement is PLAN_LIMIT_EXCEEDED (403). Concurrent transformations may return TRANSFORM_CONFLICT (409); capacity can return IMAGE_BUSY (503).
Documentation reviewed 2026-10-03 against development backend e298ec7. Verify your deployment’s API origin and limits before integrating.
