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 illustration of a forest-green field notebook and pencil on a pale deskOriginal · 1000 × 750 PNG
Square cover-cropped WebP thumbnail of the same field notebookThumbnail · 600 × 600 WebP
Original Imazeo sample artwork. The thumbnail is precomputed locally with a cover resize and WebP quality 80; viewing this page makes no API request. Download the original PNG.

The source and thumbnail illustrate a product image workflow. Explore the detailed examples for product thumbnailsor responsive variants.

Endpoints and authentication

MethodPathResponse
POST/v1/projects/{projectId}/transforms200 · image bytes
GET/v1/projects/{projectId}/transforms200 · paginated metadata
GET/v1/projects/{projectId}/transforms/{id}200 · metadata
GET/v1/projects/{projectId}/transforms/{id}/content200 · image bytes, or authenticated 304
DELETE/v1/projects/{projectId}/transforms/{id}200 · JSON message; idempotent deletion

Request body

FieldRequirementBehavior
imageId OR urlExactly oneAn owned, ready original UUID, or a permitted remote HTTP(S) URL.
modeOptionalCACHE (default), PERSIST or EPHEMERAL.
maxOutputBytesOptional positive integerLowers the configured output byte ceiling. Cannot exceed that ceiling; reserves capacity before work.
transformOptional objectOptions below. Omit for normalized defaults; unknown properties are rejected.
cURL example
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

PropertyAccepted valueDefault / behavior
width, heightPositive integers ≤ configured MAX_OUTPUT_DIMENSION (hard ceiling 10000).Omitted dimensions preserve the oriented/cropped size; one dimension preserves proportions.
fitcover | contain | inside | fillBoth 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.
rotateInteger multiples of 90, −360…3600; normalized to 0, 90, 180 or 270.
flip, flopbooleanfalse; vertical and horizontal reflection respectively.
formatjpeg | png | webp | avif | gifwebp; SVG is input only.
qualityInteger 1…10080; encoder quality for JPEG/WebP/AVIF, palette quantization for PNG, palette colors for GIF.
optimizebooleantrue; bounded encoder effort, not a file-size guarantee.
stripMetadatatrue onlyAlways true. false is rejected. EXIF/GPS/ICC omitted from derivatives.
grayscale, negatebooleanfalse. Negate inverts color channels, preserving alpha.
blurNumber 0.3…10Omitted: skipped; sigma rounded to two decimals.
sharpenNumber 0.5…5Omitted: skipped; sigma rounded to two decimals.
brightness, saturationNumber 0…3Omitted: skipped; 1 leaves the factor unchanged. Rounded to three decimals.
hueInteger −180…180Omitted: skipped; degrees of hue rotation.
trimtrue 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.
positioncenter | entropy | attentioncenter; 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.

remote-request.json — replace the illustrative source URL
{
  "url": "https://example.com/replace-with-your-image.jpg",
  "mode": "CACHE",
  "transform": {
    "width": 600,
    "format": "webp"
  }
}
Remote transformation
# 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.webp

Remote 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

ModeBehaviorAccounting
PERSISTStore until explicit or original-image deletion.Processing, stored bytes and transfer usage apply.
CACHEReuse matching source bytes and normalized settings within the configured lifetime.Hit uses output bandwidth; expired stored bytes count until cleanup.
EPHEMERALAlways 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.

Revalidate stored derivative
# 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.bin

Metadata 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.

400 error response
{
  "success": false,
  "error": {
    "code": "TRANSFORM_INVALID",
    "message": "Transformation parameters are invalid or unsupported.",
    "details": {}
  },
  "meta": {
    "requestId": "example-request-id"
  }
}
Error codes and recovery →

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.