Image Generation via URL
This is the dynamic image id, not the design id
{dynamicImageId} is the id returned by POST /designs/{designId}/dynamic-image-url — not the design ID. The dynamic_image_url returned by that endpoint already includes the format segment; append your query string to it directly, or construct URLs manually from the {dynamicImageId}.
The URL of a dynamic image variant is:
https://img.abyssale.com/{dynamicImageId}[/{formatNameOrUid}]?{overrides}The URL is public — no API key, no signature. Anyone holding it can render variants; see the security model.
The query-string grammar
Every query parameter is an element override — key=value, where the key names a layer of the design and the value is what you want changed. All available properties are listed under Element Properties.
Long form — layer_name.property_name=value:
?text_title.color=%23FF0000&text_title.font_size=64&company_logo.hidden=trueShort form — layer_name=value, the property being inferred from the layer's type:
| Layer type | layer_name=value sets |
|---|---|
text, button, qrcode (and any other text-carrying type) | payload |
image, logo | image_url |
rating | rating_score |
The exact rules:
- URL-encode every value — colors'
#becomes%23, URLs and spaces must be escaped. An empty value is a hard400with a reminder to URL-encode. - A key must contain exactly one dot for the long form; keys with more dots are silently ignored.
- A short-form key must name a layer that exists on the rendered format — otherwise the parameter is silently dropped. Long-form property errors are caught at render and answer
400 Invalid Property: [layer.property] …. - If a key is repeated, only the first value is used.
- A literal
\nin a text value becomes a real line break. hiddenacceptstrue/false/1/0(case-insensitive).
Example — a design with a text_title layer and a company_logo layer:
https://img.abyssale.com/a12b3c4d-5e6f-7890-abcd-ef1234567890?text_title=Welcome&text_title.color=%23FFFFFF&text_title.background_color=%23FF0000&company_logo=https%3A%2F%2Fcdn.example.com%2Flogo.pngHow to select a format
The optional path segment after the id picks the format — by name or by uid (recommended: it survives renames). Omitted, the design's first format is rendered.
https://img.abyssale.com/{dynamicImageId}/instagram-story
https://img.abyssale.com/{dynamicImageId}/74c5ee10-c9e8-4433-90e3-3320bab8dff0Format names and uids come from the creation response or Design Details. An unknown format answers 404.
Using text variables
As explained in the Text Layer documentation, text variables are replaced dynamically:
?vars.{variableName}={variableValue}If a text layer contains {username} Smith, then ?vars.username=Alice renders Alice Smith. URL-encode the value like any other.
Output, caching and credits
- The response is the rendered file itself, with the matching
Content-Type. There is no output-type, quality or size parameter — the design and the rendered background decide. See Output file type. - Every unique query string is a distinct variant: rendered once (1 credit), then served from cache (
Cache-Control: public, max-age=31104000— 360 days). A variant is immutable — to re-render after editing the design, change the query string (any difference creates a new variant, and consumes a new credit). - Responses allow any origin (
Access-Control-Allow-Origin: *). - Finite dataset? Pre-generate every variant once upfront to warm the CDN cache — end users are then served from cache only, with no render latency.
Output file type
You cannot ask for a file type — there is no output-type parameter, and an unrecognised query key is ignored rather than rejected. The renderer picks one per variant, in this order:
Content-Type | When |
|---|---|
application/pdf | The format is one of the predefined print formats — A3, A4, A5, A6, business card, postcard, square postcard, US Letter — picked in the design editor. Checked first, before any background test. |
image/png | The rendered background is not fully opaque — an alpha channel below 1, or a gradient containing transparency. |
image/jpeg | Everything else. This is the common case. |
Because the transparency test runs against the background actually rendered, an override can change the file type of a single variant: adding ?root.background_color=%2300000000 to an otherwise opaque design serves that one variant as PNG while every other variant stays JPEG. If the background is left alone, the design's own background decides and every variant agrees.
A dynamic image can only be minted from a static design in the first place — see Overview — so picking A4 does not make the design a print design, and its PDF is not a print file. A format created through the JSON design import never carries the print-format flag at all, so an API-imported design always serves PNG or JPEG.
A PDF variant is a web PDF, and will not render in an <img> tag
The PDF is 72 DPI, RGB — no CMYK conversion, no ICC profile, no bleed, no crop marks. Do not send it to a print supplier. Print-ready PDF/X-4 with CMYK and bleed comes from a printer design through multi-format PDFs for printing — a different endpoint and a different rendering pipeline.
Nothing on the URL signals the PDF case and no error is raised, so if you embed dynamic images in HTML or email, read the response Content-Type rather than assuming an image.
Errors
Errors are returned as plain-text responses (no JSON envelope, no fallback image):
| Status | When |
|---|---|
400 | Empty parameter value, invalid property value (Invalid Property: …), or the dynamic image was deactivated. |
401 | Your plan does not include Dynamic Images. |
404 | Malformed or unknown dynamicImageId, unknown format, or the design no longer exists. |
429 | Per-visitor limit (5 requests/24 h when enable_rate_limit is on), the 10 req/s per-image limit (test mode), or your credit balance is exhausted. |
503 | Maintenance in progress. |
Related
- Create a Dynamic Image by API — mint the base URL first
- Element Properties — all available layer properties and their names
- Overview — Dynamic Images — modes, security, credits and caching
