Skip to main content

Unlayer API (3.0.0)

Download OpenAPI specification:Download

Unlayer API

Authentication

Most endpoints require a Bearer token. Pass it in the Authorization header:

Authorization: Bearer <your-token>

Two token types are supported:

Token Prefix Scope Use case
API Key unlayer_sk_ Project Server-to-server integration. The project ID is embedded in the key — no projectId parameter needed.
Personal Access Token unlayer_pat_ User Admin operations. Required for workspace endpoints. Must provide projectId via query param or X-Project-Id header for project endpoints.

Most integrations should use an API Key. Use a PAT only for workspace management or admin tasks.

The design schema reference at GET /v3/templates/schema is public and does not require authentication.

⚠️ Server-side use only. This API does not send CORS headers and cannot be called from a browser. API keys (unlayer_sk_*) must never be shipped to client-side code — treat them as secrets.

me

Current user and token context.

Get current plan and features.

Get the current plan, feature availability, and limits for a project. Used to answer "can I do X" / "what plan do I need" questions with ground-truth data instead of guessing.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

projects

Project details and configuration.

Get project.

Get project details by ID.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Configure Inbox Previews.

Configure the default email clients and data region used for Inbox Previews.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Request Body schema: application/json
required
required
object non-empty
clients
Array of strings or null [ 1 .. 20 ] items unique [ items [ 1 .. 200 ] characters ^[a-zA-Z0-9_.-]+$ ]
dataRegion
string or null
Enum: "us" "eu" null

Responses

Request samples

Content type
application/json
{
  • "inboxPreviews": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

templates

Template management — list, retrieve, generate, import, export, and convert designs.

List templates

List templates with cursor-based pagination. Returns templates in descending order by update time.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID to list templates for

limit
integer [ 1 .. 100 ]
Default: 20

Number of templates to return (1-100)

cursor
string

Pagination cursor from previous response

displayMode
string
Enum: "email" "web" "document"

Filter by template type

name
string

Filter by name (case-insensitive search)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string",
  • "has_more": true
}

Get template by ID.

Get template by ID.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Convert Full to Simple schema.

Convert design json from Full to Simple schema.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
required
object
displayMode
string
Default: "email"
Enum: "email" "web" "popup" "document"

Display mode of the design (email, web, document, popup). Defaults to "email", matching /v3/templates/validate. Mode-specific repairs apply during conversion (email caps contentWidth at 900px, for example), so pass the design's actual mode — a web design converted under the email default can be altered.

includeDefaultValues
boolean
Default: false
includeConversion
boolean
Default: false

When true, includes _conversion metadata in the response. This metadata can be passed to simple-to-full to restore original values without data loss.

Responses

Request samples

Content type
application/json
{
  • "design": {
    },
  • "displayMode": "email",
  • "includeDefaultValues": false,
  • "includeConversion": false
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Convert Simple to Full schema.

Convert design json from Simple to Full schema.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
required
object
displayMode
string
Default: "email"
Enum: "email" "web" "popup" "document"

Display mode of the design (email, web, document, popup). Defaults to "email", matching /v3/templates/validate. Mode-specific repairs apply during conversion (email caps contentWidth at 900px, for example), so pass the design's actual mode — a web design converted under the email default can be altered.

includeDefaultValues
boolean
Default: false

Responses

Request samples

Content type
application/json
{
  • "design": {
    },
  • "displayMode": "email",
  • "includeDefaultValues": false
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

AI design generation

Generate or modify an Unlayer design using AI. Send the conversation as messages (today only the last user message is consumed; earlier turns are accepted as chat history) and describe the target with output.kind + output.displayMode. Pass the current canvas state in context (full design JSON + selection pointer) to modify an existing design. Only anthropic and openai models are supported. To import existing HTML or an image instead, use POST /v3/templates/import.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
model
string

Preferred AI model in "provider/id" form, e.g. "anthropic/claude-opus-5". Optional — server resolves a default per output kind.

boolean or Array of strings

Transient-outage fallback controls. Omit to use Unlayer defaults only when no model is pinned; true always uses Unlayer defaults; false disables the outage tail; an ordered array replaces the default provider/model strings.

required
Array of objects [ 1 .. 10 ] items

Conversation messages in chronological order, capped at 10 messages. The last user message is the prompt for this turn; the newest earlier user/assistant turns are forwarded within a 12,000-character aggregate history budget. A user message may carry a predefined prompt action via metadata.action.id (e.g. SPELLING, REPHRASE).

required
object
object
locale
string <= 100 characters ^[A-Za-z0-9]{1,8}(?:-[A-Za-z0-9]{1,8})*$

BCP-47 fallback locale for AI status messages.

conversationId
string

Reserved for future server-side conversation memory.

Responses

Request samples

Content type
application/json
{
  • "model": "string",
  • "fallbackModels": true,
  • "messages": [
    ],
  • "output": {
    },
  • "context": {
    },
  • "locale": "string",
  • "conversationId": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "output": {
    },
  • "model": {
    },
  • "usage": {
    }
}

Import a template from HTML or an image

Import an existing template from HTML or an image (URL or base64) and return the resulting Unlayer design JSON. No template DB entry is created.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
model
string <= 200 characters

Preferred AI model. Accepts a provider/model string (e.g. "anthropic/claude-opus-5", "openai/gpt-5.6-luna"), a bare provider ("anthropic", "openai") which uses that provider's default model, or a bare model id ("claude-opus-5", "gpt-5.6-luna") with the provider inferred from the name. Optional — defaults to anthropic/claude-opus-5.

boolean or Array of strings

Transient-outage fallback controls. Omit to use Unlayer defaults only when no model is pinned; true always uses Unlayer defaults; false disables the outage tail; an ordered array replaces the default provider/model strings.

displayMode
required
string
Enum: "email" "web" "popup" "document"

Display mode for the imported design

required
Array of objects [ 1 .. 10 ] items

Array of input parts. Must contain exactly one "html" or "image" part; may also contain one or more "text" parts with optional instructions.

Responses

Request samples

Content type
application/json
{
  • "model": "string",
  • "fallbackModels": true,
  • "displayMode": "email",
  • "input": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "output": {
    },
  • "model": "string",
  • "provider": "string",
  • "usage": {
    }
}

Get the design JSON Schema.

Returns the canonical design schema as a standard JSON Schema document — the exact schema POST /v3/templates/validate checks against, ready to plug into any JSON Schema validator or editor tooling. Serves the Full schema by default; pass simple=true for the compact Simple schema. No authentication required. Responses carry a strong ETag and long-lived cache headers; send If-None-Match to revalidate for free.

query Parameters
simple
boolean
Default: false

When true, returns the Simple schema instead of the Full schema.

displayMode
string
Default: "email"
Enum: "email" "web" "popup" "document"

Display mode whose rules the schema describes (email, web, document, popup). Defaults to "email".

Responses

Validate a design against the Unlayer schema.

Validate a design JSON against the Unlayer design schema. Returns { success: true, data: { valid: true } } when the payload conforms; otherwise data is { valid: false, errors: [...] } with descriptive issues. Every checked design gets HTTP 200 — data.valid is the source of truth, not the status code. Only malformed requests (e.g. a missing design field or an unknown displayMode) fail request validation with 400 VALIDATION_ERROR.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
required
object

The design JSON to validate.

schema
string
Default: "full"
Enum: "full" "simple"

Which form of the schema to validate against. Defaults to "full".

displayMode
string
Default: "email"
Enum: "email" "web" "popup" "document"

Display mode for the design (email, web, document, popup). Some validation rules differ per mode. Defaults to "email" — without a default, options from every mode would apply at once, the strictest possible check, and real editor-saved designs could be reported invalid.

migrate
boolean
Default: true

When true (default), a full-form design with an older schemaVersion is upgraded to the current schema before validating — matching how the editor and the convert endpoints treat stored designs. Designs without a schemaVersion predate versioning and are fully migrated the same way. Set to false to check strict conformance with the current schema version. Designs with a newer schemaVersion than this API knows are validated as-if-current.

Array of objects <= 100 items

Custom tool declarations, in the same shape passed to unlayer.registerTool. When provided, blocks matching a declared tool have their values checked against the tool's declared options (wrong types are reported at their exact path). Blocks of undeclared tools keep envelope-only validation.

Responses

Request samples

Content type
application/json
{
  • "design": { },
  • "schema": "full",
  • "displayMode": "email",
  • "migrate": true,
  • "customTools": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

workspaces

Workspace access and management.

List accessible workspaces.

Get all workspaces accessible by the current token. Requires a Personal Access Token (PAT).

Authorizations:
personalAccessTokenAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Get workspace by ID.

Get a specific workspace by ID with its projects. Requires a Personal Access Token (PAT).

Authorizations:
personalAccessTokenAuth
path Parameters
workspaceId
required
string

The workspace ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

blocks

Reusable design blocks — list shared project blocks and end-user saved blocks for backup, migration, and usage reporting.

List blocks

List blocks with cursor-based pagination. Returns both shared project blocks and blocks saved by end-users; each user-saved block carries the userId it was saved under (null for shared blocks), so usage can be aggregated per end-user without enumerating user IDs. Returns blocks in descending order by creation.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID to list blocks for

limit
integer [ 1 .. 100 ]
Default: 20

Number of blocks to return (1-100)

cursor
string

Pagination cursor from previous response

displayMode
string
Enum: "email" "web" "popup" "document"

Filter by display mode

userId
string

Only blocks saved by this end-user (exact match on the user id your app passes to the editor)

scope
string
Default: "all"
Enum: "all" "shared" "user"

Filter by block ownership: shared project blocks, end-user saved blocks, or both

category
string

Filter by category (case-insensitive search)

includeData
boolean
Default: true

Include the block design JSON in each item. Pass false for lightweight sweeps (e.g. usage reports).

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string",
  • "has_more": true
}

ai-credits

AI credit balance, usage breakdown, and webhook/alert settings. Credits are pooled per workspace; settings are per project.

Get AI credit balance.

Returns the current AI credit balance for the project. Credits are pooled per workspace — every project in a workspace shares one balance. Only credit counts are returned; token counts, model names, and costs are never exposed.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Responses

Response samples

Content type
application/json
{
  • "is_capped": true,
  • "credits_total": 0,
  • "credits_used": 0,
  • "credits_remaining": 0,
  • "reset_date": null
}

Get AI credit settings.

Returns a project's AI credit exhaustion behavior, alert thresholds, and webhook endpoint. The signing secret is never returned — only whether one exists (has_signing_secret).

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Responses

Response samples

Content type
application/json
{
  • "exhaustion_behavior": "disable",
  • "threshold_alerts": [
    ],
  • "webhook_url": null,
  • "has_signing_secret": true
}

Update AI credit settings.

Configures AI credit exhaustion behavior, usage alert thresholds, and the webhook endpoint for a project. The HMAC signing secret is generated the first time a webhook URL is set and returned exactly once in the response — store it securely; it is never shown again.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Request Body schema: application/json
required
exhaustion_behavior
string
Enum: "disable" "show_error"

What the editor does when the credit balance is exhausted.

threshold_alerts
Array of integers[ items [ 1 .. 100 ] ]

Usage percentages (1-100) at which a threshold_reached webhook fires, once per crossing per period.

webhook_url
string or null <uri> ^https://

HTTPS endpoint that receives AI credit webhooks.

Responses

Request samples

Content type
application/json
{
  • "exhaustion_behavior": "disable",
  • "threshold_alerts": [
    ],
  • "webhook_url": "http://example.com"
}

Response samples

Content type
application/json
{
  • "exhaustion_behavior": "disable",
  • "threshold_alerts": [
    ],
  • "webhook_url": null,
  • "has_signing_secret": true,
  • "signing_secret": "string"
}

Rotate the AI credit webhook signing secret.

Generates a new HMAC signing secret for the project and returns it exactly once. The previous secret stops working immediately, so update your webhook verification before rotating. Requires a webhook URL to be configured first.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Responses

Response samples

Content type
application/json
{
  • "signing_secret": "string"
}

Get AI credit usage breakdown.

Returns AI credit consumption for the project, broken down by end user and feature type. Filterable by date range, end user, and feature type. Usage is updated near real time and grouped by the UTC date when the AI activity occurred. Recent activity may take a short time to appear. Defaults to the current billing period. Only credit counts are returned; token counts, model names, and costs are never exposed. Per-end-user attribution requires the partner to pass endUserId on editor initialization.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

query Parameters
start
string^\d{4}-\d{2}-\d{2}$

Start date (inclusive), YYYY-MM-DD.

end
string^\d{4}-\d{2}-\d{2}$

End date (inclusive), YYYY-MM-DD.

end_user_id
string

Filter to a single end user id.

feature_type
string
Enum: "full_template_gen" "block_edit" "html_import" "image_import" "image_generation"

Filter to a single feature type.

limit
integer [ 1 .. 1000 ]
Default: 100

Max breakdown rows to return (1-1000).

offset
integer >= 0
Default: 0

Number of breakdown rows to skip (pagination).

sort
string
Default: "credits"
Enum: "credits" "end_user_id" "feature_type"

Field the breakdown is ordered by. Defaults to credits.

order
string
Default: "desc"
Enum: "asc" "desc"

Sort direction. Defaults to desc (highest credits first).

Responses

Response samples

Content type
application/json
{
  • "total_credits_used": 0,
  • "total": 0,
  • "breakdown": [
    ]
}

List AI credit webhook deliveries.

Returns the webhook delivery history for the project, newest first — the event, delivery status, attempt count, and last response code for each. Use it to spot failed deliveries and drive the retry endpoint. Payloads expose credits only.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

query Parameters
status
string
Enum: "pending" "delivered" "failed"

Filter to a single delivery status.

event
string
Enum: "ai.credits.usage_recorded" "ai.credits.threshold_reached" "ai.credits.exhausted"

Filter to a single event type.

limit
integer [ 1 .. 100 ]
Default: 50

Max deliveries to return (1-100).

offset
integer >= 0
Default: 0

Number of deliveries to skip (pagination).

Responses

Response samples

Content type
application/json
{
  • "deliveries": [
    ],
  • "total": 0
}

List a webhook delivery’s attempts.

Returns the per-attempt history for a single delivery, newest attempt first — the response code, error, and time of each POST (including automatic retries). Returns 404 if the delivery is not found for this project.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The project ID

deliveryId
required
string

The webhook delivery ID

query Parameters
limit
integer [ 1 .. 100 ]
Default: 50

Max attempts to return (1-100).

offset
integer >= 0
Default: 0

Number of attempts to skip (pagination).

Responses

Response samples

Content type
application/json
{
  • "attempts": [
    ],
  • "total": 0
}

Retry a webhook delivery.

Re-queues a single previously-failed (or pending) webhook delivery for another attempt. Returns 404 if the delivery is not found for this project, and 409 if it was already delivered.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The project ID

deliveryId
required
string

The webhook delivery ID

Responses

Response samples

Content type
application/json
{
  • "status": "requeued"
}

inbox-previews

Inbox Previews usage reporting for projects and their end users.

Get Inbox Previews usage.

Returns project credit totals, a daily trend, and an end-user breakdown. The current billing model uses one credit per selected client; previous-model generations use one credit per accepted LIVE run and none for TEST runs.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

query Parameters
start
string^\d{4}-\d{2}-\d{2}$

Start date (inclusive), YYYY-MM-DD.

end
string^\d{4}-\d{2}-\d{2}$

End date (inclusive), YYYY-MM-DD.

end_user_id
string [ 1 .. 10000 ] characters

Only include usage attributed to this end user ID. It is normalized exactly as it was when the usage was recorded.

limit
integer [ 1 .. 100 ]
Default: 100

Maximum rows to return.

offset
integer [ 0 .. 100000 ]
Default: 0

Number of rows to skip.

Responses

Response samples

Content type
application/json
{
  • "summary": {
    },
  • "daily": [
    ],
  • "email_clients": [
    ],
  • "end_users": {
    }
}

Remove Inbox Previews end-user attribution.

Permanently removes one end user ID from this project’s Inbox Previews usage history while preserving generation and credit totals.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

Request Body schema: application/json
required
end_user_id
required
string [ 1 .. 10000 ] characters

The original end user ID supplied to the editor. It is normalized exactly as it was when usage was recorded.

Responses

Request samples

Content type
application/json
{
  • "end_user_id": "string"
}

Response samples

Content type
application/json
{
  • "error": "string",
  • "message": "string"
}

Get Inbox Previews usage runs.

Returns recent project generations and their credit usage. Per-device rows include the selected clients and their view status; per-generation rows list the clients the provider reported, without view, end-user, template, or region details.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

The resource ID

query Parameters
start
string^\d{4}-\d{2}-\d{2}$

Start date (inclusive), YYYY-MM-DD.

end
string^\d{4}-\d{2}-\d{2}$

End date (inclusive), YYYY-MM-DD.

end_user_id
string [ 1 .. 10000 ] characters

Only include usage attributed to this end user ID. It is normalized exactly as it was when the usage was recorded.

limit
integer [ 1 .. 100 ]
Default: 25

Maximum rows to return.

offset
integer [ 0 .. 100000 ]
Default: 0

Number of rows to skip.

Responses

Response samples

Content type
application/json
{
  • "total": 0,
  • "limit": 0,
  • "offset": 0,
  • "data": [
    ]
}

editor-sessions

Ephemeral editor session creation and access.

Create editor session

Create an ephemeral, no-DB editor session for a design and return a hosted editor URL the user can open to edit it in the real Unlayer editor.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
required
object

Design JSON to load into the editor.

displayMode
string
Enum: "email" "web" "popup" "document"

Editor display mode. Defaults to email.

Responses

Request samples

Content type
application/json
{
  • "design": { },
  • "displayMode": "email"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

export

Render designs as HTML, images, PDFs, or ZIP files.

Export HTML

Export a design as rendered HTML.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
design
required
object

Unlayer design JSON

displayMode
string
Enum: "email" "web" "popup" "document"
customJS
Array of strings or string
editorVersion
string
mergeTags
object
mergeTagsSchema
object
designTags
object
designTagsConfig
object
safeHtml
boolean
language
string
languages
Array of strings

Responses

Request samples

Content type
application/json
{
  • "design": { },
  • "displayMode": "email",
  • "customJS": "string",
  • "editorVersion": "string",
  • "mergeTags": { },
  • "mergeTagsSchema": { },
  • "designTags": { },
  • "designTagsConfig": { },
  • "safeHtml": true,
  • "language": "string",
  • "languages": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Export image

Export a design as a PNG image.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
design
required
object

Unlayer design JSON

displayMode
string
Enum: "email" "web" "popup" "document"
customJS
Array of strings or string
editorVersion
string
mergeTags
object
mergeTagsSchema
object
designTags
object
designTagsConfig
object
safeHtml
boolean
language
string
languages
Array of strings
width
number
height
number
fullPage
boolean
deviceScaleFactor
number

Responses

Request samples

Content type
application/json
{
  • "design": { },
  • "displayMode": "email",
  • "customJS": "string",
  • "editorVersion": "string",
  • "mergeTags": { },
  • "mergeTagsSchema": { },
  • "designTags": { },
  • "designTagsConfig": { },
  • "safeHtml": true,
  • "language": "string",
  • "languages": [
    ],
  • "width": 0,
  • "height": 0,
  • "fullPage": true,
  • "deviceScaleFactor": 0
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Export PDF

Export a design as a PDF document.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
design
required
object

Unlayer design JSON

displayMode
string
Enum: "email" "web" "popup" "document"
customJS
Array of strings or string
editorVersion
string
mergeTags
object
mergeTagsSchema
object
designTags
object
designTagsConfig
object
safeHtml
boolean
language
string
languages
Array of strings
pageSize
string
Enum: "Letter" "Legal" "Tabloid" "Ledger" "A0" "A1" "A2" "A3" "A4" "A5" "A6"
number or string

Responses

Request samples

Content type
application/json
{
  • "design": { },
  • "displayMode": "email",
  • "customJS": "string",
  • "editorVersion": "string",
  • "mergeTags": { },
  • "mergeTagsSchema": { },
  • "designTags": { },
  • "designTagsConfig": { },
  • "safeHtml": true,
  • "language": "string",
  • "languages": [
    ],
  • "pageSize": "Letter",
  • "contentWidth": 0
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Export ZIP

Export a design as a ZIP archive containing HTML and assets.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

The project ID (required for PAT auth, auto-resolved for API key auth)

Request Body schema: application/json
required
design
required
object

Unlayer design JSON

displayMode
string
Enum: "email" "web" "popup" "document"
customJS
Array of strings or string
editorVersion
string
mergeTags
object
mergeTagsSchema
object
designTags
object
designTagsConfig
object
safeHtml
boolean
language
string
languages
Array of strings

Responses

Request samples

Content type
application/json
{
  • "design": { },
  • "displayMode": "email",
  • "customJS": "string",
  • "editorVersion": "string",
  • "mergeTags": { },
  • "mergeTagsSchema": { },
  • "designTags": { },
  • "designTagsConfig": { },
  • "safeHtml": true,
  • "language": "string",
  • "languages": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

emails

Send and manage transactional email.

List sent emails

List emails sent from this project within the rolling 90-day history window. Without a status filter, results and date bounds use acceptance time. With a status filter, results and date bounds use the time each email entered that status.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

Project ID (auto-resolved for API key auth)

status
string
Enum: "queued" "sending" "sent" "delivered" "bounced" "complained" "failed"

Filter by email delivery status

search
string

Search recipient addresses and subjects by case-sensitive substring

tag
string

Filter by tag in "key=value" format (e.g. "campaign=welcome")

from
string <date>

Start date (ISO date). Bounds acceptance time normally, or status transition time when status is supplied.

to
string <date>

End date (ISO date). Bounds acceptance time normally, or status transition time when status is supplied.

limit
integer [ 1 .. 100 ]
Default: 20

Number of emails to return (1-100)

cursor
string

Pagination cursor from previous response

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string",
  • "has_more": true
}

Send an email

Send a transactional email with raw HTML content. The sender domain must be verified in the project workspace; verified sender domains are shared by every Developer Email API project in that workspace.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
header Parameters
idempotency-key
string <= 255 characters

Unique key for idempotent sends (max 255 characters). If provided, duplicate requests within 24 hours return the cached response.

Request Body schema: application/json
required
from
required
string

Sender email address or "Name " format. Domain must be verified.

to
required
Array of strings <email> = 1 items [ items <email > ]

Exactly one recipient. Each request creates one independently tracked delivery.

cc
Array of arrays <= 0 items

CC is not supported by this endpoint.

bcc
Array of arrays <= 0 items

BCC is not supported by this endpoint.

subject
required
string <= 998 characters

Email subject line

html
required
string

HTML content of the email

text
string

Plain text version of the email. If provided, a multipart/alternative message is sent.

replyTo
string <email>

Reply-To email address

object <= 10 properties

Key-value tags for categorizing the email (e.g. {"campaign": "welcome"}). Max 10 tags. Keys (1-64 chars) and values (up to 256 chars) may only contain letters, numbers, underscores, and hyphens (the Amazon SES message-tag character set).

object <= 9 properties

Custom email headers. Up to 9 printable-ASCII X-* headers are allowed (e.g. {"X-Entity-Ref-ID": "abc123"}). Header names may contain up to 126 characters and each name plus value may contain up to 996 characters.

Array of objects <= 10 items

File attachments. Max 10 files per email, max 5 MB total payload size (including headers and base64 overhead).

Responses

Request samples

Content type
application/json
{
  • "from": "string",
  • "to": [
    ],
  • "cc": [ ],
  • "bcc": [ ],
  • "subject": "string",
  • "html": "string",
  • "text": "string",
  • "replyTo": "user@example.com",
  • "tags": {
    },
  • "headers": {
    },
  • "attachments": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get email details

Retrieve details of a sent email, including its current delivery status, during the rolling 90-day history window. Expired emails return 404.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

Email ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get email event timeline

Retrieve the operational event timeline for a sent email, showing send, delivery, bounce, and complaint events in chronological order during the rolling 90-day history window. Expired emails return 404.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

Email ID

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Render an email template

Render a saved email template with optional merge variables. Returns the final HTML without sending. Useful for previewing emails before sending.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
templateId
required
string^[1-9][0-9]*$

Template ID to render

object <= 100 properties

Merge variables to substitute. Use {{key}} syntax in your template.

Responses

Request samples

Content type
application/json
{
  • "templateId": "string",
  • "variables": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get email settings

Get the email sender settings for this project.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update email settings

Update the email sending configuration for this project. Only include the fields you want to change.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
defaultFromName
string <= 255 characters

Default sender display name

Responses

Request samples

Content type
application/json
{
  • "defaultFromName": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get email statistics

Get aggregated email delivery statistics for a project. Returns totals or daily breakdown for the specified period. Statistics are asynchronous and may lag by about one hour.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

Project ID (auto-resolved for API key auth)

period
string
Default: "30d"
Enum: "7d" "30d" "90d"

Time period for stats

groupBy
string
Value: "day"

Group results by day for chart data

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List suppressed email addresses

List all email addresses suppressed for this project due to bounces, complaints, or manual suppression. Cursor-paginated.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

Project ID (auto-resolved for API key auth)

limit
integer [ 1 .. 200 ]
Default: 100

Max number of results (1-200)

cursor
string

Pagination cursor from a previous response. Omit to start from the beginning.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true,
  • "next_cursor": null
}

Suppress an email address

Manually add an email address to the suppression list. Future sends to this address will be blocked.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
email
required
string <email>

Email address to suppress

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove email from suppression list

Remove an email address from the suppression list so it can receive emails again.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

Project ID (auto-resolved for API key auth)

email
required
string

Email address to unsuppress

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Check if an email is suppressed

Look up a specific email address to see if it is currently on the suppression list.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
query Parameters
projectId
string

Project ID (auto-resolved for API key auth)

email
required
string

Email address to check

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Send an email using a template

Send a transactional email by rendering a saved template with optional merge variables. The template must have rendered HTML (saved at least once in the editor). The sender domain must be verified in the project workspace; verified sender domains are shared by every Developer Email API project in that workspace.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
header Parameters
idempotency-key
string <= 255 characters

Unique key for idempotent sends (max 255 characters). Duplicate requests within 24 hours return the cached response.

Request Body schema: application/json
required
from
required
string

Sender email address or "Name " format. Domain must be verified.

to
required
Array of strings <email> = 1 items [ items <email > ]

Exactly one recipient. Each request creates one independently tracked delivery.

cc
Array of arrays <= 0 items

CC is not supported by this endpoint.

bcc
Array of arrays <= 0 items

BCC is not supported by this endpoint.

templateId
required
string^[1-9][0-9]*$

Template ID to use for the email body

subject
string <= 998 characters

Email subject line. Supports {{variable}} merge syntax. Defaults to template name if omitted.

object <= 100 properties

Merge variables to substitute in the template and subject. Use {{key}} syntax in your template.

text
string

Plain text version of the email. Supports {{variable}} merge syntax.

replyTo
string <email>

Reply-To email address

object <= 10 properties

Key-value tags for categorizing the email (e.g. {"campaign": "welcome"}). Max 10 tags. Keys (1-64 chars) and values (up to 256 chars) may only contain letters, numbers, underscores, and hyphens (the Amazon SES message-tag character set).

object <= 9 properties

Custom email headers. Up to 9 printable-ASCII X-* headers are allowed. Header names may contain up to 126 characters and each name plus value may contain up to 996 characters.

Array of objects <= 10 items

File attachments. Max 10 files per email, max 5 MB total payload size.

Responses

Request samples

Content type
application/json
{
  • "from": "string",
  • "to": [
    ],
  • "cc": [ ],
  • "bcc": [ ],
  • "templateId": "string",
  • "subject": "string",
  • "variables": {
    },
  • "text": "string",
  • "replyTo": "user@example.com",
  • "tags": {
    },
  • "headers": {
    },
  • "attachments": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

domains

Manage verified sender domains.

List sender domains

List sender domains shared by every Developer Email API project in the workspace. Requires a personal access token belonging to a workspace owner or admin; project API keys cannot manage domains.

Authorizations:
personalAccessTokenAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Add a sender domain

Register a sender domain shared by every Developer Email API project in the workspace. Requires a personal access token belonging to a workspace owner or admin. Verification requires the workspace-specific TXT record and the returned SES DKIM records.

Authorizations:
personalAccessTokenAuth
Request Body schema: application/json
required
domain
required
string

Domain name to register, such as example.com.

Responses

Request samples

Content type
application/json
{
  • "domain": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get domain details

Get the ownership TXT challenge and SES DKIM records for a sender domain shared by every Developer Email API project in the workspace. Requires a personal access token belonging to a workspace owner or admin.

Authorizations:
personalAccessTokenAuth
path Parameters
id
required
string

Domain ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a sender domain

Delete a sender domain shared by every Developer Email API project in the workspace. Requires a personal access token belonging to a workspace owner or admin. The SES identity remains so a later reconciler can clean it up safely.

Authorizations:
personalAccessTokenAuth
path Parameters
id
required
string

Domain ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Verify domain status

Verify the ownership TXT challenge and SES DKIM identity for a sender domain shared by every Developer Email API project in the workspace. Requires a personal access token belonging to a workspace owner or admin.

Authorizations:
personalAccessTokenAuth
path Parameters
id
required
string

Domain ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

webhooks

Manage Developer Email API webhooks.

List webhooks

List all webhook endpoints configured for a project.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Create a webhook

Create a new webhook endpoint. A signing secret is auto-generated and returned once. Use it to verify webhook signatures.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
Request Body schema: application/json
required
url
required
string <uri>

The HTTPS URL to receive webhook events

events
Array of strings
Items Enum: "email.sent" "email.delivered" "email.bounced" "email.complained"

Event types to subscribe to. If omitted or empty, all events are sent.

active
boolean
Default: true

Whether the webhook is active

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get webhook details

Get details of a specific webhook endpoint.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

Webhook ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a webhook

Update a webhook endpoint URL, events, or active status.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

Webhook ID

Request Body schema: application/json
required
url
string <uri>

The HTTPS URL to receive webhook events

events
Array of strings
Items Enum: "email.sent" "email.delivered" "email.bounced" "email.complained"

Event types to subscribe to. If omitted or empty, all events are sent.

active
boolean

Whether the webhook is actively receiving events

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a webhook

Delete a webhook endpoint. It will no longer receive events.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

Webhook ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Rotate webhook signing secret

Generate a new signing secret for a webhook. The new secret is returned once — store it securely. The old secret is invalidated immediately.

Authorizations:
apiKeyAuthpersonalAccessTokenAuth
path Parameters
id
required
string

Webhook ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}