Synchronous images

Transform an image synchronously

Runs ONE deterministic op — or ONE saved preset with no AI step — on ONE image and answers with the result bytes. Nothing is stored: no job, no asset, no public URL.

The image is the request body; the op and its parameters are query parameters: ?op=resize&width=1200. An op takes only what its catalogue entry declares, so resizing AND re-encoding is two steps, and two steps are a preset: ?preset=<slug> (or <slug>@<version>) runs all of its steps in this one call, and takes no parameters beside it. Which ops may be used here is GET /api/v1/ops → syncEndpoint; do not hard-code a list.

THREE WAYS TO SEND THE IMAGE: the raw bytes with their own Content-Type (the format is read from that header, so application/octet-stream on a camera RAW is unsupported_format); multipart/form-data with a file part; or application/json with a reference instead of bytes — {assetId} (one of your assets) or {url} (fetched by this service: http(s) only, no private addresses, no redirects) — and then op / preset / parameters may ride in the body too; the query string wins where both say something.

Which presets may be used here follows from their steps: only deterministic steps, however many, run here. A preset with an AI step, or with a step that reads a stored layer (composite, overlay) — or any other step that names one of your assets as its second image (boolean, joinChannel) — is 400 invalid_param on preset: it is still a valid preset, and the same reference runs as a job.

LIMITS: a body of at most 25 MB, an input of at most 50 megapixels (a bigger one is 400 unsupported_format: it is refused on the size its header declares, before it is decoded), 10 s of wall clock (503, deadline_exceeded). At most 4 calls in flight per account: one more is 429 rate_limited with details.reason = "account_concurrency" and Retry-After: 1. A success counts one against the plan's processing allowance, however many steps a preset holds; past it, a success is paid from your balance at the plan's overageCredits (GET /api/v1/ops), and a call the balance cannot cover is 402 insufficient_credit before anything runs. A failure counts and costs nothing. No Idempotency-Key: nothing is created, so send it again.

USE THIS WHEN:

  • You are holding an image and only want the result back
  • You do not want the input or the output stored

DO NOT USE WHEN:

  • The op or a preset step is an AI op, or you have more than one image → POST /api/v1/jobs
  • You want an asset id or a permanent URL → POST /api/v1/jobs
post/api/v1/images/transform

Request

  • Base URL: https://api.imagestep.dev
  • URL: https://api.imagestep.dev/api/v1/images/transform
  • Auth: API key in header Authorization

Query parameters

opstring

Op name; must be one whose GET /api/v1/ops entry has a syncEndpoint. Mutually exclusive with preset.

presetstring

A deterministic preset to run as one call: its slug or id, or slug@version to pin one version. Mutually exclusive with op.

response'url'

url to get JSON with a signed link to the result (valid 5 minutes) instead of the bytes; anything else, or nothing, answers the bytes. The one part of this endpoint that writes storage: a temporary object, gone within a day.

Request body

opstring

Transform only: the op, as ?op=

presetstring

Transform only: the preset, as ?preset=

assetIdstring

One of your assets, read by this service (its browser-readable rendition when it has one)

urlstring

An image on the internet, fetched by this service: http(s) only, never a private or loopback address, redirects not followed. Its format is the type it was served as, else the one its extension names

parametersobject

Transform with op only: the op's parameters. A key also in the query string takes the query's value.

Response

The transformed image, Content-Type the produced format, with X-ImageStep-Width / X-ImageStep-Height and X-ImageStep-Duration-Ms. With ?response=url, JSON instead: data is a signed link to the result, valid for 5 minutes.

successboolean required

Indicates if the request was successful

messagestring

Human-readable message about the response

timestampstring date-time

Timestamp when the response was generated

Example response

{
  "success": true,
  "message": "Operation completed successfully",
  "timestamp": "2024-01-15T10:30:45.123Z",
  "error": {
    "code": "invalid_param",
    "message": "format must be one of: jpeg, png, webp",
    "param": "format",
    "requestId": "9f0c1c2e-6f2a-4f6b-9d3e-0a1b2c3d4e5f"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.