Export a Design
Alpha
The contract may change without notice, and imports created with it are not guaranteed to remain compatible. Not covered by the deprecation policy.
The reverse of Create Import: it turns a design back into the JSON that would recreate it, so you can clone, version, diff or edit a design without ever hand-writing a payload.
curl "https://api.abyssale.com/designs/$DESIGN_UUID/as-import" \
-H "x-api-key: $API_KEY"You get back a { payload, warnings, version } envelope. All four design types export — static, printer, animated, printer_multipage — and every design that exists is importable: the exported payload is guaranteed to validate against POST /designs/import/json and recreate the design, blank text layers included. The one exception is not_round_trippable, for values that predate the import contract.
| You want to… | Do this |
|---|---|
| Clone a design into another project | Export it, add a target with the destination project_uuid, re-POST. |
| Version a design | Export it and commit the payload to your VCS. |
| Edit programmatically | Export, mutate the fields you care about, POST back. |
| Diff two designs | Compare their two exported payloads. |
| Learn the import format | Build a design in the editor, export it, read the payload. |
Clone a design into another project
Extract payload from the envelope and add a target block — the export knows the design's content, not where you want the copy to live, so payload never carries one:
curl "https://api.abyssale.com/designs/$DESIGN_UUID/as-import" \
-H "x-api-key: $API_KEY" \
| jq --arg project "$PROJECT_UUID" \
'.payload + { target: { kind: "design", project_uuid: $project } }' \
| curl -X POST "https://api.abyssale.com/designs/import/json" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d @-Two ways this goes wrong:
| Symptom | Cause |
|---|---|
unknown_field at payload, warnings, version and missing_required for name, type, formats, layers | You posted the whole envelope. Unwrap .payload first. |
missing_required at target.project_uuid | No target block. Without one the import creates a workspace template, not a design. |
The round trip carries content, not settings
Design settings and some generation settings are not part of the payload and will not follow the copy — to duplicate a design in full, use the duplicate action in the UI. And a design from another workspace references its custom fonts by name, so map each one to a font that exists in the target workspace (GET /fonts) before re-importing.
Exports are stable after one round trip
export → import → export returns byte-identical payloads, which is what makes snapshot-and-diff safe. Only the first round trip differs from a hand-authored input, because the stored design is your input plus the defaults the pipeline materialises — see What the export normalises.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
uuid | path | string (uuid) | Yes | Design UUID. Only designs that live under a project are addressable — workspace templates are not. |
There are no query parameters, and deliberately no version-selection parameter: one contract version is maintained at a time, and the response's version names it.
Response
200 OK with an envelope:
| Field | Type | Description |
|---|---|---|
payload | object | A POST /designs/import/json body — the schema documented on Create Import. Never contains a target; add one before re-POSTing. |
warnings | array<object> | {path?, code?, layer?, message} entries for values clipped or normalised on export. See below. |
version | string | The API version that produced payload — currently "v2026-08-17". One version is maintained at a time; see the changelog. |
payload's top-level fields are name, type, then either formats + layers (static / printer / animated, plus animation on animated) or the print setup + pages (printer_multipage).
warnings
Common codes are color_converted, property_not_representable and print_settings_not_recoverable.
- Group on
layer, not onpath.layeris the layer's name, present whenever the warning was raised while transforming one. The index insidepathis a position in the emitted array, not what you see in the editor — group layers move to the end, so positions shift. - Only branch on entries that carry a
code. An entry with nocodeis a human-readable note with no stable machine identity.
Asset URLs
All src values on image / logo layers come back as Abyssale-hosted https:// URLs, and those URLs are re-acceptable on POST /designs/import/json without re-upload — the API recognises them, skips the presigned-upload phase and fetches the bytes server-side. A full round trip therefore never moves binary payloads through your client.
The URL's extension may differ from what you uploaded
On static / animated designs, uploaded images are normalised for the render pipeline: an opaque image is stored as JPEG and an image with transparency as lossless WebP. So hero.png may come back as a .jpeg or .webp URL. Transparency is never lost — a transparent PNG takes the lossless branch. Don't key anything off the extension.
On printer / printer_multipage, src points at the untouched original instead — the exact bytes used at generation time, ICC profile and file format preserved.
What the export normalises
The export is generated from the stored design, not replayed from your original request, so a few things move. None is a loss and all are stable — which is why exports settle after one round trip. Read this section only if you are diffing an export against a hand-authored payload.
| What moves | How it comes back | Warning |
|---|---|---|
| Schema defaults | Omitted entirely — hidden: false, rotation: 0, radius: 0, shape.type: "rectangle", font_style: "normal", char_spacing: 0, alignment: "middle center". Re-importing produces the same design. | — |
| Defaults applied at import time | Always present, even if you never sent them — line_height: 130, font_weight: 400, the rating defaults (star_color, background_color, rating_score). | — |
image.radius | As mask_name: "rounded_corners" + mask_properties.radius. An equivalent shape; the rounding survives re-import. | — |
| Layer skew | Dropped, the rest of the mask unchanged. If skew was the only thing stored, the whole mask goes and the layer re-imports square. | property_not_representable |
A rounded_corners mask with no radius | Mask dropped; the layer re-imports square. | property_not_representable |
| A button's label highlight box | Dropped. Never folded into padding — that would shrink the text box and stop the design rendering. | property_not_representable |
The default merge sentinel | Never emitted; explicit per-format keys instead. | — |
| Layer order | Preserved, group layers at their original position, matching the editor's layer manager. | — |
font_size on text and button layers | The rendered, post-fit value, not your starting hint — with or without min_font_size. | none, by design |
| Print colors | Canonical CMYK tokens: whitespace stripped, 5-component tokens normalised to cmyka. | — |
| Print geometry | Exact to storage precision — ≤2 decimals on mm, ≤3 on in, what the editor shows. Compares byte-for-byte. | — |
Two things that look like normalisation but are exported verbatim:
- Empty image slots. An
imageorlogolayer whose slot was never filled comes back as a normal layer with nosrc, keeping its layout and every other property.srcis optional on import for exactly this reason, so it re-imports into the same empty slot. All four design types. - Blank text payloads. A
text,buttonorqrcodelayer holding an empty or whitespace-onlypayloadis exported exactly as stored, whitespace included — the import schema accepts blank payloads.
Why font_size is not warned about
Nothing is persisted to compare against, so the export cannot tell whether a resize actually happened — a warning would fire unconditionally on every text layer and say nothing. The exported value is faithful in the sense that matters: it recreates the design exactly as it renders. Expect it to differ only when diffing against your original hand-authored payload. See the text layer reference.
Printer designs
Printer designs export in the same physical-unit space the import contract is authored in — no DPI conversion is applied.
| What | How it exports |
|---|---|
| Geometry | type: "printer" plus each format's unit (mm | in); format dims, layouts and geometric properties as floats in that unit, font_size / min_font_size in pt. Rounded to 4 decimals, so compare with a tolerance rather than byte equality. |
| Colors | Canonical CMYK tokens — cmyk(...) / cmyka(...), whitespace stripped, 5-component tokens normalised to cmyka. |
bleed_size / safe_size | Read from the design's print settings and emitted on each format, but only when that zone is enabled. |
dpi | One dpi per format (formats[i].dpi). Re-importing reuses the value instead of recomputing it. |
src on image and logo layers | The untouched originals — the exact bytes used at generation time, ICC profile and file format preserved, never a display proxy. Shape strokes and qrcode centre icons are included as data URIs. |
| QR error-correction level | Never emitted; chosen automatically on import. |
| Star geometry | star_dimension / star_margin above the pixel-equivalence caps are clipped to the cap, one warning per path. The payload always re-validates. |
Two cases where a print colour is not simply carried across:
- An RGB (hex) solid colour is converted to CMYK on the way out, with a
color_convertedwarning at that path. The export succeeds and the payload re-imports. - A gradient fails the export with
not_round_trippable— it cannot be converted without collapsing to a flat fill.
If the print settings could not be read at all, a print_settings_not_recoverable warning appears once at path formats and re-import falls back to platform defaults: computed DPI, bleed and safe disabled.
See Print Imports for the printer authoring rules the exported payload conforms to.
Animated designs
Animated designs export as type: "animated" with px geometry and hex colors like static, plus the full animation model:
- The top-level
animation(duration, andscreenshot_at_swhen stored) and per-layeranimation(start_at_s/end_at_stiming plustweens) are included, along withvideo/audiolayers. - Tween
ids are regenerated on re-import, so they are not part of the exported payload; keyframes are emitted as-is. - When the design has no stored timeline length (older designs),
animation.durationis derived from element timing and ananimation_duration_derivedwarning is emitted atanimation.duration. Values are clipped into the valid[1, 60]range with a warning where needed. - A design whose formats fall outside the 1920 × 1200 bounding box (only possible on designs created before the current limits) cannot be re-imported, so the export fails with
not_round_trippable.
See Animated Imports for the authoring rules the exported payload conforms to.
Multi-page print designs
Multi-page print designs export as type: "printer_multipage" in the pages[] shape:
The print setup is emitted once at the top level —
unit,width,height, plusbleed_size/safe_sizewhen enabled anddpi— matching the multi-page import contract. Eachpages[i]entry carries onlybackground_colorandlayers.Page layers are emitted in the same physical-unit space as printer designs — mm/in geometry, pt font sizes, canonical CMYK colors.
Group layers appear in multi-page exports at their original position in their page's
layers[].Empty image/logo slots on a page are preserved like anywhere else — see What the export normalises.
Older designs with non-uniform pages cannot be expressed in the uniform top-level shape. Where the stored pages disagree, a
print_settings_not_recoverablewarning is emitted at the offending setting —width/height,bleed_size,safe_sizeordpi— and the first page's value is used.Pages that disagree on their
unitfail withnot_round_trippableat pathunit. Pages that differ only in size, in the same unit, degrade with the warning above instead.Why a mixed-unit document cannot be exported
Every page's geometry is already expressed in that page's own unit, so emitting one page's ruler for the whole document would reinterpret another page's numbers and change its size — a 4 × 6 in page would come back as 4 × 6 mm.
See Multi-Page Print Imports for the authoring rules the exported payload conforms to.
Errors
400 not_round_trippable
All four design types export, so type alone never blocks a round-trip. This error is returned only when a specific value in the design cannot be expressed as a valid import payload — typically older data that predates the import contract. The error envelope follows the standard shape; the path points at the offending value and expected describes the constraint it violates.
{
"errors": [
{
"path": "layers[3].properties.background_color",
"code": "not_round_trippable",
"message": "Printer imports do not support gradient colors, and this design surfaces 'linear-gradient(0% 0% 100% 0%,0% #1A47FF 1,100% #B65151 1)'. A gradient cannot be converted to cmyk without silently collapsing it to a flat fill — the design cannot be exported as an import payload."
}
]
}Common triggers:
- A printer (or multi-page print) design carries a gradient color. An RGB solid color is not a trigger — it is converted to CMYK with a
color_convertedwarning. - An animated design has no recoverable timeline length, or a format outside the 1920 × 1200 bounding box (designs created before the current limits).
- A layer or property has no import-schema equivalent. When a single property is affected it is dropped with a
property_not_representablewarning instead; this error is reserved for values that genuinely cannot be expressed. - Every layer had to be dropped, leaving no importable payload (
layersrequires at least one entry). - The generated payload fails its own schema check — the API never returns an invalid import body; if regeneration would produce one, the response is promoted to
not_round_trippable.
404 Not Found
Returned when the UUID does not exist or belongs to a different company.
Related
- Create Import — the endpoint that consumes this response shape
- Import Status — error envelope and warning code reference
- Design Details — fetch the runtime view of the same design
