Download OpenAPI specification:Download
Welcome to the Unlayer REST API documentation. Our API enables you to programmatically access and manipulate email templates, designs, and other Unlayer resources.
The Unlayer API uses Basic Authentication. All requests require you to authenticate using a Unlayer Project API Key as the username with an empty string as the password:
curl -u YOUR_API_KEY: -X GET https://api.unlayer.com/v2/templates
All API calls must use HTTPS. Any calls made using HTTP will return an appropriate error code.
Follow these steps to get your API key:
Authorization: Basic BASE64-ENCODED-API-KEY
If you need to, you may construct and send basic auth headers yourself. To do this you need to perform the following steps:
APIKey:Password where Password will always be empty. For example, if your API Key is XAyAztva4, you will just add a : at the end. XAyAztva4:Authorization header with content Basic followed by the encoded string. For example, the string XAyAztva4: encodes to WEF5QXp0dmE0Og== in base64. Here's how the request would look: curl -D- \
-X GET \
-H "Authorization: Basic WEF5QXp0dmE0Og==" \
"https://api.unlayer.com/v2/templates"
All API requests will receive a standard HTTP response code.
GET https://api.unlayer.com/v2/templates
Get a list of available templates
| page | integer >= 1 Default: 1 Current page |
| perPage | integer >= 1 Default: 20 Number of templates to fetch per page |
| includeDesign | integer Default: 1 Enum: 0 1 Should the result include design json or not. This is not recommended as it could result in long response. To disable, pass 0. |
{- "success": true,
- "data": [
- {
- "id": "string",
- "name": "string",
- "design": { },
- "displayMode": "string",
- "updatedAt": "string",
- "createdAt": "string"
}
]
}GET https://api.unlayer.com/v2/templates/{id}
Get a specific template by ID
| id required | string ID of the template to retrieve |
{- "success": true,
- "data": {
- "id": "string",
- "name": "string",
- "design": { },
- "displayMode": "string",
- "updatedAt": "string",
- "createdAt": "string"
}
}Check a design JSON against the Unlayer schema — in CI, in import pipelines, or before saving. A schema problem caught here is a clear error message instead of a broken render. Older designs are upgraded to the current schema first, and custom tool blocks can be deep-checked by passing your tool declarations.
See Design Schema → Design object for the design shape this endpoint expects.
This endpoint lives on the v3 base URL:
https://api.unlayer.com/v3. Authenticate with a Bearer token (API key with theunlayer_sk_prefix).
GET https://api.unlayer.com/v3/templates/schema
Download the canonical design schema as a standard JSON Schema document — the exact schema /templates/validate checks against. Plug it into any JSON Schema validator, IDE, or codegen tooling.
Serves the Full schema by default; pass simple=true for the compact Simple schema. No authentication required.
| simple | boolean Default: false When |
| displayMode | string Default: "email" Enum: "email" "web" "document" "popup" Display mode whose rules the schema describes. Defaults to |
{ }POST https://api.unlayer.com/v3/templates/validate
Check a design JSON against the Unlayer schema. Every checked design gets HTTP 200 — read data.valid, not the status code; only malformed requests (missing design, unknown displayMode) return 400 with error: VALIDATION_ERROR. Invalid designs come back with data.errors: the dotted path, message, and code of every issue. Built-in content blocks are validated against their exact per-type schemas, not just the content envelope.
Designs saved by an older editor version are upgraded to the current schema before checking, the same way the editor and the convert endpoints treat stored designs. Pass migrate: false to check strict conformance with the current schema version instead.
Using custom tools? Pass their declarations in customTools and each matching block's values is checked against the tool's declared options, with wrong types reported at their exact path. Blocks of undeclared tools are only checked for the { type, values } envelope.
Known limitation: body.headers and body.footers are not yet part of the body schema — their content blocks are deep-checked, but header/footer structure itself is not validated.
required | object The design JSON to validate. |
| schema | string Default: "full" Enum: "full" "simple" Which form of the schema to validate against. |
| displayMode | string Default: "email" Enum: "email" "web" "document" "popup" Display mode for the design. Some validation rules differ per mode. Defaults to |
| migrate | boolean Default: true Upgrade designs with an older |
Array of objects <= 100 items Custom tool declarations, in the same shape passed to |
{- "displayMode": "email",
- "design": {
- "counters": {
- "u_row": 1,
- "u_column": 1,
- "u_content_button": 1
}, - "body": {
- "id": "body-1",
- "rows": [
- {
- "id": "row-1",
- "cells": [
- 1
], - "columns": [
- {
- "id": "col-1",
- "contents": [
- {
- "id": "btn-1",
- "type": "button",
- "values": {
- "text": "Shop now"
}
}
], - "values": { }
}
], - "values": { }
}
], - "values": { }
}, - "schemaVersion": 25
}
}{- "success": true,
- "data": {
- "valid": true
}
}GET https://api.unlayer.com/v2/template-folders/{id}/templates
Get a list of templates in a specific folder
| id required | string ID of the folder to retrieve templates from |
| page | integer >= 1 Default: 1 Current page |
| perPage | integer >= 1 Default: 20 Number of templates to fetch per page |
| includeDesign | integer Default: 1 Enum: 0 1 Should the result include design json or not. This is not recommended as it could result in long response. To disable, pass 0. |
{- "success": true,
- "data": [
- {
- "id": "string",
- "name": "string",
- "design": { },
- "displayMode": "string",
- "updatedAt": "string",
- "createdAt": "string"
}
]
}Convert a design JSON between Unlayer's two schema forms:
Round-trip safely by passing includeConversion: true on the way out — the embedded _conversion metadata restores original values without data loss.
See Design Schema → Design object for the shape these endpoints accept and return.
These endpoints live on the v3 base URL:
https://api.unlayer.com/v3. Authenticate with a Bearer token (API key with theunlayer_sk_prefix).
POST https://api.unlayer.com/v3/templates/convert/full-to-simple
Convert a design from the Full schema to the Simple schema. Use this when you have an in-editor design and need to send it somewhere that expects the Simple shape — your own backend storage, a webhook payload, the /templates/validate endpoint when validating against the simple form, and so on.
required | object The Full-schema design JSON. |
| displayMode | string Default: "email" Enum: "email" "web" "document" "popup" Display mode of the design. Defaults to |
| includeDefaultValues | boolean Default: false When |
| includeConversion | boolean Default: false When |
{- "displayMode": "email",
- "includeConversion": true,
- "design": {
- "counters": {
- "u_row": 1,
- "u_column": 1,
- "u_content_button": 1
}, - "body": {
- "id": "body-1",
- "rows": [
- {
- "id": "row-1",
- "cells": [
- 1
], - "columns": [
- {
- "id": "col-1",
- "contents": [
- {
- "id": "btn-1",
- "type": "button",
- "values": {
- "text": "Shop now",
}
}
], - "values": { }
}
], - "values": { }
}
], - "values": { }
}, - "schemaVersion": 25
}
}{- "success": true,
- "data": {
- "design": {
- "body": {
- "id": "body-1",
- "rows": [
- {
- "id": "row-1",
- "cells": [
- 1
], - "columns": [
- {
- "id": "col-1",
- "contents": [
], - "values": { }
}
], - "values": { }
}
], - "values": { }
}, - "schemaVersion": 25,
- "_conversion": {
- "data": "JTdCJTIycmVtb3ZlZEZyb21GdWxsRGF0YSUyMiUzQSU1QiU1RC4uLg==",
- "version": 1
}
}
}
}POST https://api.unlayer.com/v3/templates/convert/simple-to-full
Convert a design from the Simple schema to the Full schema. If the input was produced by /templates/convert/full-to-simple with includeConversion: true, the embedded _conversion metadata is used to restore original values without data loss.
required | object The Simple-schema design JSON. May include a |
| displayMode | string Default: "email" Enum: "email" "web" "document" "popup" Display mode of the design. Defaults to |
| includeDefaultValues | boolean Default: false When |
{- "displayMode": "email",
- "design": {
- "body": {
- "id": "body-1",
- "rows": [
- {
- "id": "row-1",
- "cells": [
- 1
], - "columns": [
- {
- "id": "col-1",
- "contents": [
], - "values": { }
}
], - "values": { }
}
], - "values": { }
}, - "schemaVersion": 25,
- "_conversion": {
- "data": "JTdCJTIycmVtb3ZlZEZyb21GdWxsRGF0YSUyMiUzQSU1QiU1RC4uLg==",
- "version": 1
}
}
}{- "success": true,
- "data": {
- "design": {
- "counters": {
- "u_row": 1,
- "u_column": 1,
- "u_content_button": 1
}, - "body": {
- "id": "body-1",
- "rows": [
- {
- "id": "row-1",
- "cells": [
- 1
], - "columns": [
- {
- "id": "col-1",
- "contents": [
- {
- "id": "btn-1",
- "type": "button",
- "values": {
- "text": "Shop now",
}
}
], - "values": { }
}
], - "values": { }
}
], - "values": { }
}, - "schemaVersion": 25
}
}
}You can use Unlayer's Cloud API to generate HTML, Image, PDF or ZIP file of your templates or designs.
The Cloud API helps you take care these common use-cases:
POST https://api.unlayer.com/v2/export/html
Export a design to HTML format with various options
| design required | object The design JSON to export |
| displayMode required | string Enum: "email" "web" "popup" The display mode of the design |
| mergeTags | object Values to replace merge tags in the design |
| customJS | Array of strings URLs to your custom JS to support custom tools |
| editorVersion | string Optional editor version to use when exporting the design. If omitted, the API uses the X-Unlayer-Editor-Version header when present. Versions earlier than 1.438.0 use 1.438.0. |
{- "design": { },
- "displayMode": "email",
- "mergeTags": { },
- "customJS": [
- "string"
], - "editorVersion": "string"
}{- "success": true,
- "data": {
- "html": "string",
- "chunks": {
- "body": "string",
- "css": "string",
- "js": "string",
- "fonts": [
- "string"
]
}
}
}POST https://api.unlayer.com/v2/export/image
Export a design to image format (PNG)
| design required | object The design JSON to export |
| displayMode required | string Enum: "email" "web" "popup" The display mode of the design |
| mergeTags | object Values to replace merge tags in the design |
| customJS | Array of strings URLs to your custom JS to support custom tools |
| editorVersion | string Optional editor version to use when exporting the design. If omitted, the API uses the X-Unlayer-Editor-Version header when present. Versions earlier than 1.438.0 use 1.438.0. |
| fullPage | boolean Default: true Generate image of the full page. |
{- "design": { },
- "displayMode": "email",
- "mergeTags": { },
- "customJS": [
- "string"
], - "editorVersion": "string",
- "fullPage": true
}{- "success": true,
- "data": {
- "url": "string"
}
}POST https://api.unlayer.com/v2/export/pdf
Export a design to PDF format
| design required | object The design JSON to export |
| displayMode required | string Enum: "email" "web" "popup" The display mode of the design |
| mergeTags | object Values to replace merge tags in the design |
| customJS | Array of strings URLs to your custom JS to support custom tools |
| editorVersion | string Optional editor version to use when exporting the design. If omitted, the API uses the X-Unlayer-Editor-Version header when present. Versions earlier than 1.438.0 use 1.438.0. |
{- "design": { },
- "displayMode": "email",
- "mergeTags": { },
- "customJS": [
- "string"
], - "editorVersion": "string"
}{- "success": true,
- "data": {
- "url": "string"
}
}POST https://api.unlayer.com/v2/export/zip
Export a design as a ZIP archive containing all assets
| design required | object The design JSON to export |
| displayMode required | string Enum: "email" "web" "popup" The display mode of the design |
| mergeTags | object Values to replace merge tags in the design |
| customJS | Array of strings URLs to your custom JS to support custom tools |
| editorVersion | string Optional editor version to use when exporting the design. If omitted, the API uses the X-Unlayer-Editor-Version header when present. Versions earlier than 1.438.0 use 1.438.0. |
{- "design": { },
- "displayMode": "email",
- "mergeTags": { },
- "customJS": [
- "string"
], - "editorVersion": "string"
}{- "success": true,
- "data": {
- "url": "string"
}
}