Skip to main content

URL Generation

Imagor Studio exposes two GraphQL mutations for generating signed imagor URLs. These are the core bridge between the image editor and the imagor processing engine.

Both mutations require a valid token with write scope — see Authentication.


generateImagorUrl

The low-level mutation. Takes an image path and explicit imagor parameters, returns a signed URL.

mutation GenerateImagorUrl($imagePath: String!, $params: ImagorParamsInput!) {
generateImagorUrl(imagePath: $imagePath, params: $params)
}

Parameters

FieldTypeDescription
imagePathString!Path to the image in storage (e.g. gallery/photo.jpg)
paramsImagorParamsInput!Imagor transformation parameters

ImagorParamsInput fields

FieldTypeDescription
widthIntOutput width in pixels
heightIntOutput height in pixels
fitInBooleanFit image within dimensions (letterbox)
stretchBooleanStretch to fill dimensions exactly
smartBooleanSmart crop (content-aware)
hAlignStringHorizontal alignment: "left", "right"
vAlignStringVertical alignment: "top", "bottom"
hFlipBooleanFlip horizontally
vFlipBooleanFlip vertically
cropLeftFloatCrop left coordinate (original image pixels)
cropTopFloatCrop top coordinate
cropRightFloatCrop right coordinate
cropBottomFloatCrop bottom coordinate
paddingLeftIntLeft padding in pixels
paddingTopIntTop padding in pixels
paddingRightIntRight padding in pixels
paddingBottomIntBottom padding in pixels
trimBooleanTrim whitespace/borders
trimByStringTrim reference: "top-left", "bottom-right"
trimToleranceIntTrim color tolerance
filters[ImagorFilterInput!]Additional imagor filters

ImagorFilterInput

input ImagorFilterInput {
name: String! # e.g. "quality", "format", "brightness"
args: String! # e.g. "80", "webp", "10"
}

Example

mutation {
generateImagorUrl(
imagePath: "gallery/photo.jpg"
params: {
width: 800
height: 600
fitIn: true
filters: [
{ name: "format", args: "webp" }
{ name: "quality", args: "85" }
]
}
)
}

Returns a URL like:

/imagor/unsafe/fit-in/800x600/filters:format(webp):quality(85)/gallery/photo.jpg

(or a signed URL if a secret is configured)


generateImagorUrlFromTemplate

The high-level mutation used by the image editor. Takes a template JSON (the full editor state) and converts it to a signed imagor URL, handling all the complexity of layer composition, preview scaling, and image path overrides.

mutation GenerateImagorUrlFromTemplate(
$templateJson: String!
$imagePath: String
$contextPath: [String!]
$forPreview: Boolean
$previewMaxDimensions: DimensionsInput
$skipLayerId: String
$appendFilters: [ImagorFilterInput!]
) {
generateImagorUrlFromTemplate(
templateJson: $templateJson
imagePath: $imagePath
contextPath: $contextPath
forPreview: $forPreview
previewMaxDimensions: $previewMaxDimensions
skipLayerId: $skipLayerId
appendFilters: $appendFilters
)
}

Parameters

FieldTypeDescription
templateJsonString!JSON-encoded template envelope (see below)
imagePathStringOptional image path override — triggers applyTemplateState logic
contextPath[String!]Layer ID path for nested layer editing (empty = root)
forPreviewBooleanPreview mode: adds preview()/format(webp) filters, scales blur/sharpen/padding
previewMaxDimensionsDimensionsInputConstrain preview output to fit within these dimensions
skipLayerIdStringExclude a specific layer from rendering (used during text editing)
appendFilters[ImagorFilterInput!]Extra filters appended after conversion (e.g. attachment for download)

The Template JSON Format

The templateJson parameter is a JSON-encoded object matching the .imagor.json template file format:

{
"version": "1.0",
"dimensionMode": "adaptive",
"predefinedDimensions": { "width": 1920, "height": 1080 },
"sourceImagePath": "gallery/photo.jpg",
"transformations": {
"imagePath": "gallery/photo.jpg",
"originalDimensions": { "width": 1920, "height": 1080 },
"width": 1920,
"height": 1080,
"brightness": 10,
"contrast": -5,
"format": "webp",
"quality": 85,
"layers": [...]
}
}

Top-level fields

FieldDescription
versionAlways "1.0"
dimensionMode"adaptive" or "predefined" — controls how dimensions are applied when overriding the image
predefinedDimensionsThe source image's original dimensions — used for crop validation when overriding the image
sourceImagePathThe original source image path
transformationsThe full editor state (see below)

transformations fields

The transformations object mirrors the frontend ImageEditorState interface:

FieldTypeDescription
imagePathstringImage path (required)
originalDimensions{width, height}Source image dimensions (required)
width / heightnumberOutput dimensions
fitInbooleanFit-in mode
stretchbooleanStretch mode
smartbooleanSmart crop
hAlign / vAlignstringAlignment
hFlip / vFlipbooleanFlip axes
rotation0|90|180|270Rotation angle
cropLeft/Top/Width/HeightnumberCrop rectangle (original image coordinates)
brightness/contrast/saturation/huenumberColor adjustments
blur / sharpennumberBlur / sharpen amount
grayscalebooleanGrayscale filter
roundCornerRadiusnumberRound corner radius in pixels
fillColorstringFill/padding color (hex without #, or "none")
paddingTop/Right/Bottom/LeftnumberPadding in pixels
proportionnumberScale entire output (e.g. 50 = 50%)
formatstringOutput format: "webp", "jpeg", "png"
qualitynumberOutput quality (0–100)
maxBytesnumberMaximum output file size in bytes
stripIcc / stripExifbooleanStrip metadata
layersLayer[]Image and text overlay layers

The imagePath Override and applyTemplateState Logic

When imagePath is provided, the backend applies the same logic as the frontend's applyTemplateState function:

  1. Fetch dimensions — calls the imagor meta endpoint for the target image to get its actual width/height
  2. Crop validation — crop coordinates are only preserved if predefinedDimensions exactly matches the target image dimensions; otherwise crop is stripped (coordinates would be invalid for a different image)
  3. Dimension mode — applies the template's dimensionMode:
    • "predefined" → keeps the template's explicit width/height (the desired output size)
    • "adaptive" → replaces width/height with the target image's natural dimensions

This allows a single template to be applied to different images while respecting the template's intent.

# Apply a saved template to a different image
mutation {
generateImagorUrlFromTemplate(
templateJson: $savedTemplateJson
imagePath: "gallery/new-photo.jpg"
forPreview: false
)
}

contextPath — Layer Editing

When the editor is editing a nested layer (drilling into a layer's transforms), contextPath is the array of layer IDs from root to the currently-edited layer.

The backend uses this to:

  • Walk the layer tree to find the active layer's transforms
  • Compute the parent canvas dimensions for resolving f-token (fill) dimensions
# Generate URL for a specific layer's context
mutation {
generateImagorUrlFromTemplate(
templateJson: $templateJson
contextPath: ["layer-abc123"]
forPreview: true
previewMaxDimensions: { width: 1200, height: 900 }
)
}

For root-level editing, pass null or omit contextPath.


Preview Mode (forPreview)

When forPreview: true, the backend:

  • Appends filters:preview():format(webp) to the URL
  • Scales blur, sharpen, round corner, and padding values proportionally to the preview size
  • Suppresses crop, rotation, and layers when visualCropEnabled is set (so the user sees the uncropped image while dragging crop handles)
  • Scales layer positions and dimensions to match the preview resolution

Combined with previewMaxDimensions, this constrains the preview to fit within a bounding box while maintaining aspect ratio:

mutation {
generateImagorUrlFromTemplate(
templateJson: $templateJson
forPreview: true
previewMaxDimensions: { width: 1200, height: 900 }
)
}

appendFilters — Extra Filters

Append additional imagor filters after the template's own filters. The primary use case is generating a download URL with the attachment filter:

mutation {
generateImagorUrlFromTemplate(
templateJson: $templateJson
forPreview: false
appendFilters: [{ name: "attachment", args: "" }]
)
}

This produces a URL that triggers a browser download (Content-Disposition: attachment) when visited.


How the Editor Uses These Mutations

Use CaseMutationKey Parameters
Live previewgenerateImagorUrlFromTemplateforPreview: true, previewMaxDimensions
Copy URLgenerateImagorUrlFromTemplateforPreview: false
DownloadgenerateImagorUrlFromTemplateforPreview: false, appendFilters: [{name:"attachment",args:""}]
ThumbnailgenerateImagorUrlFromTemplateforPreview: true, previewMaxDimensions: {width:200,height:200}
Apply template to new imagegenerateImagorUrlFromTemplateimagePath: "new/image.jpg"
Layer context previewgenerateImagorUrlFromTemplatecontextPath: ["layer-id"], forPreview: true
Text editing (hide layer)generateImagorUrlFromTemplateskipLayerId: "text-layer-id"
Direct paramsgenerateImagorUrlparams: { width, height, filters }