{ "openapi": "3.1.0", "info": { "title": "Unlayer API", "version": "3.0.0", "description": "Unlayer API\n\n## Authentication\n\nMost endpoints require a Bearer token. Pass it in the `Authorization` header:\n\n```\nAuthorization: Bearer \n```\n\nTwo token types are supported:\n\n| Token | Prefix | Scope | Use case |\n|-------|--------|-------|----------|\n| **API Key** | `unlayer_sk_` | Project | Server-to-server integration. The project ID is embedded in the key — no `projectId` parameter needed. |\n| **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. |\n\nMost integrations should use an **API Key**. Use a PAT only for workspace management or admin tasks.\n\nThe design schema reference at `GET /v3/templates/schema` is public and does not require authentication.\n\n> ⚠️ **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." }, "components": { "securitySchemes": { "apiKeyAuth": { "type": "http", "scheme": "bearer", "description": "API Key (unlayer_sk_). Project-scoped — the project ID is embedded in the key, so no projectId parameter is needed. Recommended for most integrations." }, "personalAccessTokenAuth": { "type": "http", "scheme": "bearer", "description": "Personal Access Token (unlayer_pat_). User-scoped — required for workspace endpoints and admin operations. Must provide projectId for project endpoints." } }, "schemas": {} }, "paths": { "/v3/blocks": { "get": { "operationId": "listBlocks", "summary": "List blocks", "tags": [ "blocks" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID to list blocks for" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "in": "query", "name": "limit", "required": false, "description": "Number of blocks to return (1-100)" }, { "schema": { "type": "string" }, "in": "query", "name": "cursor", "required": false, "description": "Pagination cursor from previous response" }, { "schema": { "type": "string", "enum": [ "email", "web", "popup", "document" ] }, "in": "query", "name": "displayMode", "required": false, "description": "Filter by display mode" }, { "schema": { "type": "string" }, "in": "query", "name": "userId", "required": false, "description": "Only blocks saved by this end-user (exact match on the user id your app passes to the editor)" }, { "schema": { "type": "string", "enum": [ "all", "shared", "user" ], "default": "all" }, "in": "query", "name": "scope", "required": false, "description": "Filter by block ownership: shared project blocks, end-user saved blocks, or both" }, { "schema": { "type": "string" }, "in": "query", "name": "category", "required": false, "description": "Filter by category (case-insensitive search)" }, { "schema": { "type": "boolean", "default": true }, "in": "query", "name": "includeData", "required": false, "description": "Include the block design JSON in each item. Pass false for lightweight sweeps (e.g. usage reports)." } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Block ID" }, "userId": { "type": [ "string", "null" ], "description": "End-user ID the block was saved under (the user id your app passes to the editor). Null for shared project blocks." }, "displayMode": { "type": "string", "description": "Display mode the block was saved for: email, web, popup, or document" }, "category": { "type": "string", "description": "Block category" }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Block tags" }, "data": { "type": "object", "additionalProperties": true, "description": "The block design JSON. Omitted when includeData=false is passed." }, "thumbnailUrl": { "type": [ "string", "null" ], "description": "URL of the auto-generated block thumbnail, if available" }, "syncId": { "type": [ "string", "null" ], "description": "Synced-block ID referenced by designs using this block. Null when the block has never been synced." }, "isSyncEnabled": { "type": "boolean", "description": "Whether the block is currently a synced block" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } } }, "next_cursor": { "type": [ "string", "null" ], "description": "Cursor for the next page. Null if no more results." }, "has_more": { "type": "boolean", "description": "Whether there are more results after this page" } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/domains": { "get": { "operationId": "listDomains", "summary": "List sender domains", "tags": [ "domains" ], "description": "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.", "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number" }, "domain": { "type": "string" }, "status": { "type": "string", "enum": [ "pending", "verified", "failed" ] }, "createdAt": { "type": "string", "format": "date-time" } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "post": { "operationId": "createDomain", "summary": "Add a sender domain", "tags": [ "domains" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "domain" ], "properties": { "domain": { "type": "string", "description": "Domain name to register, such as example.com." } } } } }, "required": true }, "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number" }, "domain": { "type": "string" }, "status": { "type": "string", "enum": [ "pending", "verified", "failed" ] }, "createdAt": { "type": "string", "format": "date-time" }, "dkimTokens": { "type": "array", "items": { "type": "string" } }, "dnsRecords": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string" }, "name": { "type": "string" }, "value": { "type": "string" }, "purpose": { "type": "string" } } } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/domains/{id}": { "get": { "operationId": "getDomain", "summary": "Get domain details", "tags": [ "domains" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Domain ID" } ], "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number" }, "domain": { "type": "string" }, "status": { "type": "string" }, "dkimTokens": { "type": "array", "items": { "type": "string" } }, "dnsRecords": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string" }, "name": { "type": "string" }, "value": { "type": "string" }, "purpose": { "type": "string" } } } }, "createdAt": { "type": "string", "format": "date-time" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "delete": { "operationId": "deleteDomain", "summary": "Delete a sender domain", "tags": [ "domains" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Domain ID" } ], "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "success": { "type": "boolean" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/domains/{id}/verify": { "post": { "operationId": "verifyDomain", "summary": "Verify domain status", "tags": [ "domains" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Domain ID" } ], "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number" }, "domain": { "type": "string" }, "status": { "type": "string" }, "ownership": { "type": "object", "properties": { "verified": { "type": "boolean" } } }, "dkim": { "type": "object", "properties": { "status": { "type": "string" }, "tokens": { "type": "array", "items": { "type": "string" } } } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/editor-sessions": { "post": { "operationId": "createEditorSession", "summary": "Create editor session", "tags": [ "editor-sessions" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "design" ], "properties": { "design": { "type": "object", "additionalProperties": true, "description": "Design JSON to load into the editor." }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ], "description": "Editor display mode. Defaults to email." } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "201": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "token": { "type": "string" }, "editorUrl": { "type": "string" }, "expiresAt": { "type": "string" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails": { "get": { "operationId": "listEmails", "summary": "List sent emails", "tags": [ "emails" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "Project ID (auto-resolved for API key auth)" }, { "schema": { "type": "string", "enum": [ "queued", "sending", "sent", "delivered", "bounced", "complained", "failed" ] }, "in": "query", "name": "status", "required": false, "description": "Filter by email delivery status" }, { "schema": { "type": "string" }, "in": "query", "name": "search", "required": false, "description": "Search recipient addresses and subjects by case-sensitive substring" }, { "schema": { "type": "string" }, "in": "query", "name": "tag", "required": false, "description": "Filter by tag in \"key=value\" format (e.g. \"campaign=welcome\")" }, { "schema": { "type": "string", "format": "date" }, "in": "query", "name": "from", "required": false, "description": "Start date (ISO date). Bounds acceptance time normally, or status transition time when status is supplied." }, { "schema": { "type": "string", "format": "date" }, "in": "query", "name": "to", "required": false, "description": "End date (ISO date). Bounds acceptance time normally, or status transition time when status is supplied." }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "in": "query", "name": "limit", "required": false, "description": "Number of emails to return (1-100)" }, { "schema": { "type": "string" }, "in": "query", "name": "cursor", "required": false, "description": "Pagination cursor from previous response" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "from": { "type": "string" }, "to": {}, "subject": { "type": [ "string", "null" ] }, "status": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "statusUpdatedAt": { "type": "string", "format": "date-time", "description": "When the email entered its current status. For a newly queued email, this equals createdAt." } } } }, "next_cursor": { "type": [ "string", "null" ], "description": "Cursor for the next page. Null if no more results." }, "has_more": { "type": "boolean", "description": "Whether there are more results after this page" } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "post": { "operationId": "sendEmail", "summary": "Send an email", "tags": [ "emails" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "from", "to", "subject", "html" ], "properties": { "from": { "type": "string", "description": "Sender email address or \"Name \" format. Domain must be verified." }, "to": { "type": "array", "items": { "type": "string", "format": "email" }, "minItems": 1, "maxItems": 1, "description": "Exactly one recipient. Each request creates one independently tracked delivery." }, "cc": { "type": "array", "maxItems": 0, "description": "CC is not supported by this endpoint." }, "bcc": { "type": "array", "maxItems": 0, "description": "BCC is not supported by this endpoint." }, "subject": { "type": "string", "maxLength": 998, "description": "Email subject line" }, "html": { "type": "string", "description": "HTML content of the email" }, "text": { "type": "string", "description": "Plain text version of the email. If provided, a multipart/alternative message is sent." }, "replyTo": { "type": "string", "format": "email", "description": "Reply-To email address" }, "tags": { "type": "object", "maxProperties": 10, "propertyNames": { "maxLength": 64, "pattern": "^[A-Za-z0-9_-]{1,64}$" }, "additionalProperties": { "type": "string", "maxLength": 256, "pattern": "^[A-Za-z0-9_-]{0,256}$" }, "description": "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)." }, "headers": { "type": "object", "maxProperties": 9, "propertyNames": { "maxLength": 126, "pattern": "^[Xx]-[A-Za-z0-9][A-Za-z0-9-]{0,123}$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 995, "pattern": "^[ -~]+$" }, "description": "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." }, "attachments": { "type": "array", "maxItems": 10, "items": { "type": "object", "required": [ "filename", "content", "contentType" ], "properties": { "filename": { "type": "string", "description": "The filename as it will appear to the recipient. Line breaks are rejected; quotes are stripped before it is written into the message." }, "content": { "type": "string", "description": "Base64-encoded file content. Whitespace and MIME line wrapping are removed before validation; invalid base64 is rejected with a 400 error." }, "contentType": { "type": "string", "enum": [ "application/pdf", "application/zip", "application/json", "application/xml", "application/csv", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "text/plain", "text/html", "text/csv", "text/xml", "text/calendar", "image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml", "audio/mpeg", "audio/wav", "video/mp4" ], "description": "MIME type of the attachment. Required; must be one of the allowed types." } } }, "description": "File attachments. Max 10 files per email, max 5 MB total payload size (including headers and base64 overhead)." } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string", "maxLength": 255 }, "in": "header", "name": "idempotency-key", "required": false, "description": "Unique key for idempotent sends (max 255 characters). If provided, duplicate requests within 24 hours return the cached response." } ], "responses": { "202": { "description": "Email accepted and queued for delivery", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "description": "Email accepted and queued for delivery", "properties": { "data": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique email ID (UUID). Use this with GET /v3/emails/:id to retrieve delivery status and events." }, "from": { "type": "string", "description": "The sender address the email was sent from, either a plain email or \"Name \" format." }, "to": { "type": "array", "items": { "type": "string" }, "description": "The single accepted recipient address." }, "subject": { "type": "string", "description": "The subject line of the email that was sent." }, "status": { "type": "string", "enum": [ "queued", "sending", "sent", "delivered", "bounced", "complained", "failed" ], "description": "Usually \"queued\" for a fresh send. An idempotent replay of a previously accepted request returns that email's current status instead. Use webhooks or GET /v3/emails/:id for live delivery status." }, "createdAt": { "type": "string", "format": "date-time", "description": "When the email was accepted and queued for delivery (ISO-8601)." } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "409": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/{id}": { "get": { "operationId": "getEmail", "summary": "Get email details", "tags": [ "emails" ], "description": "Retrieve details of a sent email, including its current delivery status, during the rolling 90-day history window. Expired emails return 404.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Email ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "string" }, "from": { "type": "string" }, "to": {}, "cc": { "type": [ "array", "null" ], "items": { "type": "string" } }, "bcc": { "type": [ "array", "null" ], "items": { "type": "string" } }, "subject": { "type": [ "string", "null" ] }, "status": { "type": "string" }, "failureReason": { "type": [ "string", "null" ] }, "tags": { "type": [ "object", "null" ], "additionalProperties": { "type": "string" } }, "createdAt": { "type": "string", "format": "date-time" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/{id}/events": { "get": { "operationId": "getEmailEvents", "summary": "Get email event timeline", "tags": [ "emails" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Email ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "description": "Event type (send, delivery, bounce, complaint)" }, "timestamp": { "type": "string", "format": "date-time" }, "metadata": { "type": [ "object", "null" ], "additionalProperties": true } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/render": { "post": { "operationId": "renderEmail", "summary": "Render an email template", "tags": [ "emails" ], "description": "Render a saved email template with optional merge variables. Returns the final HTML without sending. Useful for previewing emails before sending.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "templateId" ], "properties": { "templateId": { "type": "string", "pattern": "^[1-9][0-9]*$", "description": "Template ID to render" }, "variables": { "type": "object", "maxProperties": 100, "propertyNames": { "maxLength": 64 }, "additionalProperties": { "type": "string", "maxLength": 100000 }, "description": "Merge variables to substitute. Use {{key}} syntax in your template." } } } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "html": { "type": "string", "description": "Rendered HTML content" }, "subject": { "type": [ "string", "null" ], "description": "Template name (can be used as default subject)" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/settings": { "get": { "operationId": "getEmailSettings", "summary": "Get email settings", "tags": [ "emails" ], "description": "Get the email sender settings for this project.", "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "defaultFromName": { "type": "string", "maxLength": 255, "description": "Default sender display name" }, "createdAt": { "type": "string", "format": "date-time", "description": "When the settings row was first created." }, "updatedAt": { "type": "string", "format": "date-time", "description": "When the settings were last updated." } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "patch": { "operationId": "updateEmailSettings", "summary": "Update email settings", "tags": [ "emails" ], "description": "Update the email sending configuration for this project. Only include the fields you want to change.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "defaultFromName": { "type": "string", "maxLength": 255, "description": "Default sender display name" } }, "additionalProperties": false } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "defaultFromName": { "type": "string", "maxLength": 255, "description": "Default sender display name" }, "createdAt": { "type": "string", "format": "date-time", "description": "When the settings row was first created." }, "updatedAt": { "type": "string", "format": "date-time", "description": "When the settings were last updated." } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/stats": { "get": { "operationId": "getEmailStats", "summary": "Get email statistics", "tags": [ "emails" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "Project ID (auto-resolved for API key auth)" }, { "schema": { "type": "string", "enum": [ "7d", "30d", "90d" ], "default": "30d" }, "in": "query", "name": "period", "required": false, "description": "Time period for stats" }, { "schema": { "type": "string", "enum": [ "day" ] }, "in": "query", "name": "groupBy", "required": false, "description": "Group results by day for chart data" } ], "responses": { "200": { "description": "Email statistics. Shape depends on the `groupBy` query parameter: an aggregated totals object by default, or a daily breakdown array when groupBy=day.", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "description": "Email statistics. Shape depends on the `groupBy` query parameter: an aggregated totals object by default, or a daily breakdown array when groupBy=day.", "properties": { "data": { "oneOf": [ { "type": "object", "description": "Aggregated totals for the requested period (default response).", "properties": { "period": { "type": "string", "enum": [ "7d", "30d", "90d" ], "description": "The period these stats cover." }, "sent": { "type": "number", "description": "Total emails sent (one per recipient)." }, "delivered": { "type": "number", "description": "Number of successfully delivered emails." }, "bounced": { "type": "number", "description": "Number of emails that were bounced by the recipient mail server." }, "complained": { "type": "number", "description": "Number of spam complaint events received." }, "deliveryRate": { "type": "number", "description": "Delivered / sent as a percentage (0-100, 2 decimal places)." }, "bounceRate": { "type": "number", "description": "Bounced / sent as a percentage (0-100, 2 decimal places)." } } }, { "type": "array", "description": "Daily breakdown (returned when groupBy=day). Ordered chronologically.", "items": { "type": "object", "properties": { "date": { "type": "string", "format": "date", "description": "The email send-cohort day in YYYY-MM-DD format." }, "sent": { "type": "number", "description": "Emails sent on this day." }, "delivered": { "type": "number", "description": "Emails from this send cohort that were delivered." }, "bounced": { "type": "number", "description": "Emails bounced on this day." }, "complained": { "type": "number", "description": "Spam complaints received for this send cohort." } } } } ] } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/suppressions": { "get": { "operationId": "listSuppressions", "summary": "List suppressed email addresses", "tags": [ "emails" ], "description": "List all email addresses suppressed for this project due to bounces, complaints, or manual suppression. Cursor-paginated.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "Project ID (auto-resolved for API key auth)" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 100 }, "in": "query", "name": "limit", "required": false, "description": "Max number of results (1-200)" }, { "schema": { "type": "string" }, "in": "query", "name": "cursor", "required": false, "description": "Pagination cursor from a previous response. Omit to start from the beginning." } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string" }, "reason": { "type": "string", "enum": [ "hard_bounce", "complaint", "manual", "unsubscribe" ] }, "createdAt": { "type": "string", "format": "date-time" } } } }, "has_more": { "type": "boolean" }, "next_cursor": { "type": [ "null", "string" ] } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "post": { "operationId": "addSuppression", "summary": "Suppress an email address", "tags": [ "emails" ], "description": "Manually add an email address to the suppression list. Future sends to this address will be blocked.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "email" ], "properties": { "email": { "type": "string", "format": "email", "description": "Email address to suppress" } } } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "email": { "type": "string" }, "reason": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "delete": { "operationId": "removeSuppression", "summary": "Remove email from suppression list", "tags": [ "emails" ], "description": "Remove an email address from the suppression list so it can receive emails again.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "Project ID (auto-resolved for API key auth)" }, { "schema": { "type": "string" }, "in": "query", "name": "email", "required": true, "description": "Email address to unsuppress" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "email": { "type": "string" }, "removed": { "type": "boolean" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/suppressions/check": { "get": { "operationId": "checkSuppression", "summary": "Check if an email is suppressed", "tags": [ "emails" ], "description": "Look up a specific email address to see if it is currently on the suppression list.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "Project ID (auto-resolved for API key auth)" }, { "schema": { "type": "string" }, "in": "query", "name": "email", "required": true, "description": "Email address to check" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "email": { "type": "string" }, "suppressed": { "type": "boolean" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/emails/template": { "post": { "operationId": "sendTemplateEmail", "summary": "Send an email using a template", "tags": [ "emails" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "from", "to", "templateId" ], "properties": { "from": { "type": "string", "description": "Sender email address or \"Name \" format. Domain must be verified." }, "to": { "type": "array", "items": { "type": "string", "format": "email" }, "minItems": 1, "maxItems": 1, "description": "Exactly one recipient. Each request creates one independently tracked delivery." }, "cc": { "type": "array", "maxItems": 0, "description": "CC is not supported by this endpoint." }, "bcc": { "type": "array", "maxItems": 0, "description": "BCC is not supported by this endpoint." }, "templateId": { "type": "string", "pattern": "^[1-9][0-9]*$", "description": "Template ID to use for the email body" }, "subject": { "type": "string", "maxLength": 998, "description": "Email subject line. Supports {{variable}} merge syntax. Defaults to template name if omitted." }, "variables": { "type": "object", "maxProperties": 100, "propertyNames": { "maxLength": 64 }, "additionalProperties": { "type": "string", "maxLength": 100000 }, "description": "Merge variables to substitute in the template and subject. Use {{key}} syntax in your template." }, "text": { "type": "string", "description": "Plain text version of the email. Supports {{variable}} merge syntax." }, "replyTo": { "type": "string", "format": "email", "description": "Reply-To email address" }, "tags": { "type": "object", "maxProperties": 10, "propertyNames": { "maxLength": 64, "pattern": "^[A-Za-z0-9_-]{1,64}$" }, "additionalProperties": { "type": "string", "maxLength": 256, "pattern": "^[A-Za-z0-9_-]{0,256}$" }, "description": "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)." }, "headers": { "type": "object", "maxProperties": 9, "propertyNames": { "maxLength": 126, "pattern": "^[Xx]-[A-Za-z0-9][A-Za-z0-9-]{0,123}$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 995, "pattern": "^[ -~]+$" }, "description": "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." }, "attachments": { "type": "array", "maxItems": 10, "items": { "type": "object", "required": [ "filename", "content", "contentType" ], "properties": { "filename": { "type": "string", "description": "The filename as it will appear to the recipient. Line breaks are rejected; quotes are stripped before it is written into the message." }, "content": { "type": "string", "description": "Base64-encoded file content. Whitespace and MIME line wrapping are removed before validation; invalid base64 is rejected with a 400 error." }, "contentType": { "type": "string", "enum": [ "application/pdf", "application/zip", "application/json", "application/xml", "application/csv", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "text/plain", "text/html", "text/csv", "text/xml", "text/calendar", "image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml", "audio/mpeg", "audio/wav", "video/mp4" ], "description": "MIME type of the attachment. Required; must be one of the allowed types." } } }, "description": "File attachments. Max 10 files per email, max 5 MB total payload size." } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string", "maxLength": 255 }, "in": "header", "name": "idempotency-key", "required": false, "description": "Unique key for idempotent sends (max 255 characters). Duplicate requests within 24 hours return the cached response." } ], "responses": { "202": { "description": "Email accepted and queued for delivery", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "description": "Email accepted and queued for delivery", "properties": { "data": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique email ID (UUID). Use this with GET /v3/emails/:id to retrieve delivery status and events." }, "from": { "type": "string", "description": "The sender address the email was sent from." }, "to": { "type": "array", "items": { "type": "string" }, "description": "The single accepted recipient address." }, "subject": { "type": "string", "description": "The resolved subject line after merge variables were applied." }, "status": { "type": "string", "enum": [ "queued", "sending", "sent", "delivered", "bounced", "complained", "failed" ], "description": "Usually \"queued\" for a fresh send. An idempotent replay of a previously accepted request returns that email's current status instead. Use webhooks or GET /v3/emails/:id for live delivery status." }, "createdAt": { "type": "string", "format": "date-time", "description": "When the email was accepted and queued for delivery (ISO-8601)." } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "409": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/me/subscription": { "get": { "operationId": "getMySubscription", "summary": "Get current plan and features.", "tags": [ "me" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "planName": { "type": [ "string", "null" ] }, "status": { "type": [ "string", "null" ] }, "expiresAt": { "type": [ "string", "null" ] }, "features": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "available": { "type": "boolean" } } } }, "limits": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "value": { "type": "number" }, "unit": { "type": "string" } } } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}": { "get": { "operationId": "getProject", "summary": "Get project.", "tags": [ "projects" ], "description": "Get project details by ID.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "id": { "type": "number", "description": "The project ID." }, "name": { "type": "string", "description": "The project name." }, "status": { "type": "string", "description": "The project status." }, "createdAt": { "type": "string", "format": "date-time", "description": "When the project was created." }, "workspace": { "type": "object", "properties": { "id": { "type": "number" }, "name": { "type": "string" } } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits": { "get": { "operationId": "getProjectAiCredits", "summary": "Get AI credit balance.", "tags": [ "ai-credits" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "credits_total", "credits_used", "credits_remaining", "reset_date" ], "properties": { "credits_total": { "type": "number", "description": "Total AI credits available for the current period." }, "credits_used": { "type": "number", "description": "AI credits consumed so far in the current period." }, "credits_remaining": { "type": "number", "description": "AI credits remaining in the current period." }, "reset_date": { "type": [ "null", "string" ], "format": "date-time", "description": "When the current credit period resets, or null if there is no active billing period — including once a subscription is cancelled or its term has ended." } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits/settings": { "get": { "operationId": "getProjectAiCreditsSettings", "summary": "Get AI credit settings.", "tags": [ "ai-credits" ], "description": "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`).", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "exhaustion_behavior", "threshold_alerts", "webhook_url", "has_signing_secret" ], "properties": { "exhaustion_behavior": { "type": "string", "enum": [ "disable", "show_error" ] }, "threshold_alerts": { "type": "array", "items": { "type": "integer" } }, "webhook_url": { "type": [ "null", "string" ] }, "has_signing_secret": { "type": "boolean" } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "put": { "operationId": "updateProjectAiCreditsSettings", "summary": "Update AI credit settings.", "tags": [ "ai-credits" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "properties": { "exhaustion_behavior": { "type": "string", "enum": [ "disable", "show_error" ], "description": "What the editor does when the credit balance is exhausted." }, "threshold_alerts": { "type": "array", "items": { "type": "integer", "minimum": 1, "maximum": 100 }, "description": "Usage percentages (1-100) at which a threshold_reached webhook fires, once per crossing per period." }, "webhook_url": { "type": [ "string", "null" ], "format": "uri", "pattern": "^https://", "description": "HTTPS endpoint that receives AI credit webhooks." } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "exhaustion_behavior", "threshold_alerts", "webhook_url", "has_signing_secret" ], "properties": { "exhaustion_behavior": { "type": "string", "enum": [ "disable", "show_error" ] }, "threshold_alerts": { "type": "array", "items": { "type": "integer" } }, "webhook_url": { "type": [ "null", "string" ] }, "has_signing_secret": { "type": "boolean" }, "signing_secret": { "type": "string", "description": "The HMAC signing secret. Returned ONLY on the response that first generates it." } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits/settings/rotate-secret": { "post": { "operationId": "rotateProjectAiCreditsSigningSecret", "summary": "Rotate the AI credit webhook signing secret.", "tags": [ "ai-credits" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "signing_secret" ], "properties": { "signing_secret": { "type": "string", "description": "The new HMAC signing secret. Shown only once." } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits/usage": { "get": { "operationId": "getProjectAiCreditsUsage", "summary": "Get AI credit usage breakdown.", "tags": [ "ai-credits" ], "description": "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.", "parameters": [ { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }, "in": "query", "name": "start", "required": false, "description": "Start date (inclusive), YYYY-MM-DD." }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }, "in": "query", "name": "end", "required": false, "description": "End date (inclusive), YYYY-MM-DD." }, { "schema": { "type": "string" }, "in": "query", "name": "end_user_id", "required": false, "description": "Filter to a single end user id." }, { "schema": { "type": "string", "enum": [ "full_template_gen", "block_edit", "html_import", "image_import", "image_generation" ] }, "in": "query", "name": "feature_type", "required": false, "description": "Filter to a single feature type." }, { "schema": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 }, "in": "query", "name": "limit", "required": false, "description": "Max breakdown rows to return (1-1000)." }, { "schema": { "type": "integer", "minimum": 0, "default": 0 }, "in": "query", "name": "offset", "required": false, "description": "Number of breakdown rows to skip (pagination)." }, { "schema": { "type": "string", "enum": [ "credits", "end_user_id", "feature_type" ], "default": "credits" }, "in": "query", "name": "sort", "required": false, "description": "Field the breakdown is ordered by. Defaults to credits." }, { "schema": { "type": "string", "enum": [ "asc", "desc" ], "default": "desc" }, "in": "query", "name": "order", "required": false, "description": "Sort direction. Defaults to desc (highest credits first)." }, { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "total_credits_used", "total", "breakdown" ], "properties": { "total_credits_used": { "type": "integer", "description": "Total AI credits used across the full filtered range (not just the returned page)." }, "total": { "type": "integer", "description": "Number of breakdown rows matching the filter (ignores paging)." }, "breakdown": { "type": "array", "items": { "type": "object", "required": [ "end_user_id", "feature_type", "credits" ], "properties": { "end_user_id": { "type": [ "null", "string" ], "description": "The end user id, or null for unattributed usage." }, "feature_type": { "type": "string", "enum": [ "full_template_gen", "block_edit", "html_import", "image_import", "image_generation" ], "description": "The partner-facing feature type." }, "credits": { "type": "integer", "description": "AI credits used by this end user and feature type." } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits/webhooks/deliveries": { "get": { "operationId": "listProjectAiCreditsWebhookDeliveries", "summary": "List AI credit webhook deliveries.", "tags": [ "ai-credits" ], "description": "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.", "parameters": [ { "schema": { "type": "string", "enum": [ "pending", "delivered", "failed" ] }, "in": "query", "name": "status", "required": false, "description": "Filter to a single delivery status." }, { "schema": { "type": "string", "enum": [ "ai.credits.usage_recorded", "ai.credits.threshold_reached", "ai.credits.exhausted" ] }, "in": "query", "name": "event", "required": false, "description": "Filter to a single event type." }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "in": "query", "name": "limit", "required": false, "description": "Max deliveries to return (1-100)." }, { "schema": { "type": "integer", "minimum": 0, "default": 0 }, "in": "query", "name": "offset", "required": false, "description": "Number of deliveries to skip (pagination)." }, { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "deliveries", "total" ], "properties": { "deliveries": { "type": "array", "items": { "type": "object", "required": [ "id", "event", "status", "attempts", "last_status_code", "end_user_id", "created_at", "delivered_at", "payload" ], "properties": { "id": { "type": "string" }, "event": { "type": "string", "enum": [ "ai.credits.usage_recorded", "ai.credits.threshold_reached", "ai.credits.exhausted" ] }, "status": { "type": "string", "enum": [ "pending", "delivered", "failed" ] }, "attempts": { "type": "integer" }, "last_status_code": { "type": [ "null", "integer" ] }, "end_user_id": { "type": [ "null", "string" ] }, "created_at": { "type": "string", "format": "date-time" }, "delivered_at": { "type": [ "null", "string" ], "format": "date-time" }, "payload": { "type": "object", "additionalProperties": true } } } }, "total": { "type": "integer", "description": "Total deliveries matching the filter (ignores limit/offset)." } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits/webhooks/deliveries/{deliveryId}/attempts": { "get": { "operationId": "listProjectAiCreditsWebhookDeliveryAttempts", "summary": "List a webhook delivery’s attempts.", "tags": [ "ai-credits" ], "description": "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.", "parameters": [ { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "in": "query", "name": "limit", "required": false, "description": "Max attempts to return (1-100)." }, { "schema": { "type": "integer", "minimum": 0, "default": 0 }, "in": "query", "name": "offset", "required": false, "description": "Number of attempts to skip (pagination)." }, { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The project ID" }, { "schema": { "type": "string" }, "in": "path", "name": "deliveryId", "required": true, "description": "The webhook delivery ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "attempts", "total" ], "properties": { "attempts": { "type": "array", "items": { "type": "object", "required": [ "attempt", "status_code", "error", "attempted_at" ], "properties": { "attempt": { "type": "integer" }, "status_code": { "type": [ "null", "integer" ] }, "error": { "type": [ "null", "string" ] }, "attempted_at": { "type": "string", "format": "date-time" } } } }, "total": { "type": "integer", "description": "Total attempts for the delivery (ignores limit/offset)." } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/projects/{id}/ai-credits/webhooks/deliveries/{deliveryId}/retry": { "post": { "operationId": "retryProjectAiCreditsWebhookDelivery", "summary": "Retry a webhook delivery.", "tags": [ "ai-credits" ], "description": "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.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The project ID" }, { "schema": { "type": "string" }, "in": "path", "name": "deliveryId", "required": true, "description": "The webhook delivery ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "requeued" ] } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "409": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates": { "get": { "operationId": "listTemplates", "summary": "List templates", "tags": [ "templates" ], "description": "List templates with cursor-based pagination. Returns templates in descending order by update time.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID to list templates for" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "in": "query", "name": "limit", "required": false, "description": "Number of templates to return (1-100)" }, { "schema": { "type": "string" }, "in": "query", "name": "cursor", "required": false, "description": "Pagination cursor from previous response" }, { "schema": { "type": "string", "enum": [ "email", "web", "document" ] }, "in": "query", "name": "displayMode", "required": false, "description": "Filter by template type" }, { "schema": { "type": "string" }, "in": "query", "name": "name", "required": false, "description": "Filter by name (case-insensitive search)" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Template ID" }, "name": { "type": "string", "description": "Template name" }, "displayMode": { "type": "string", "enum": [ "email", "web", "document" ], "description": "Template type/display mode" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } } }, "next_cursor": { "type": [ "string", "null" ], "description": "Cursor for the next page. Null if no more results." }, "has_more": { "type": "boolean", "description": "Whether there are more results after this page" } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates/{id}": { "get": { "operationId": "getTemplate", "summary": "Get template by ID.", "tags": [ "templates" ], "description": "Get template by ID.", "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" }, { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "The resource ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "displayMode": { "type": "string", "enum": [ "email", "web", "document" ] }, "design": { "type": "object", "additionalProperties": true }, "html": { "type": [ "string", "null" ] }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates/convert/full-to-simple": { "post": { "operationId": "convertFullToSimple", "summary": "Convert Full to Simple schema.", "tags": [ "templates" ], "description": "Convert design json from Full to Simple schema.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "design": { "type": "object", "properties": { "body": { "type": "object", "additionalProperties": true }, "counters": { "type": "object", "additionalProperties": true }, "schemaVersion": { "type": "number" } }, "additionalProperties": true, "required": [ "body" ] }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ], "default": "email", "description": "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": { "type": "boolean", "default": false }, "includeConversion": { "type": "boolean", "default": false, "description": "When true, includes _conversion metadata in the response. This metadata can be passed to simple-to-full to restore original values without data loss." } }, "required": [ "design" ] } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ] }, "data": { "type": "object", "properties": { "design": { "type": "object", "additionalProperties": true } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "INVALID_DESIGN, or VALIDATION_ERROR for request-schema failures." }, "message": { "type": "string", "description": "Human-readable summary of the first issues." }, "errors": { "type": "array", "items": { "type": "object", "required": [ "path", "message", "code" ], "properties": { "path": { "type": "string" }, "message": { "type": "string" }, "code": { "type": "string" } } }, "description": "Issue list for INVALID_DESIGN — same path/message/code shape as POST /v3/templates/validate, capped at 100 entries. Absent on VALIDATION_ERROR." }, "errorCount": { "type": "number", "description": "Total number of issues found; greater than errors.length when the list was capped." } } } } } } } } }, "/v3/templates/convert/simple-to-full": { "post": { "operationId": "convertSimpleToFull", "summary": "Convert Simple to Full schema.", "tags": [ "templates" ], "description": "Convert design json from Simple to Full schema.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "design": { "type": "object", "properties": { "body": { "type": "object", "additionalProperties": true }, "counters": { "type": "object", "additionalProperties": true }, "schemaVersion": { "type": "number" }, "_conversion": { "type": "object", "properties": { "data": { "type": "string" }, "version": { "type": "number" } } } }, "additionalProperties": true, "required": [ "body" ] }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ], "default": "email", "description": "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": { "type": "boolean", "default": false } }, "required": [ "design" ] } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ] }, "data": { "type": "object", "properties": { "design": { "type": "object", "additionalProperties": true } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "INVALID_DESIGN, or VALIDATION_ERROR for request-schema failures." }, "message": { "type": "string", "description": "Human-readable summary of the first issues." }, "errors": { "type": "array", "items": { "type": "object", "required": [ "path", "message", "code" ], "properties": { "path": { "type": "string" }, "message": { "type": "string" }, "code": { "type": "string" } } }, "description": "Issue list for INVALID_DESIGN — same path/message/code shape as POST /v3/templates/validate, capped at 100 entries. Absent on VALIDATION_ERROR." }, "errorCount": { "type": "number", "description": "Total number of issues found; greater than errors.length when the list was capped." } } } } } } } } }, "/v3/templates/export/html": { "post": { "operationId": "exportHtml", "summary": "Export HTML", "tags": [ "export" ], "description": "Export a design as rendered HTML.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "design" ], "properties": { "design": { "type": "object", "description": "Unlayer design JSON" }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ] }, "customJS": { "type": [ "string", "array" ], "items": { "type": "string" } }, "editorVersion": { "type": "string" }, "mergeTags": { "type": "object" }, "mergeTagsSchema": { "type": "object" }, "designTags": { "type": "object" }, "designTagsConfig": { "type": "object" }, "safeHtml": { "type": "boolean" }, "language": { "type": "string" }, "languages": { "type": "array", "items": { "type": "string" } } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object", "properties": { "html": { "type": "string" }, "chunks": { "type": "object", "properties": { "css": { "type": "string" }, "js": { "type": "string" }, "body": { "type": "string" }, "fonts": { "type": "array" }, "tags": { "type": "array", "items": { "type": "string" } } } }, "design": { "type": "object", "additionalProperties": true }, "amp": { "type": "object", "additionalProperties": true } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "422": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "500": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "502": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates/export/image": { "post": { "operationId": "exportImage", "summary": "Export image", "tags": [ "export" ], "description": "Export a design as a PNG image.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "design" ], "properties": { "design": { "type": "object", "description": "Unlayer design JSON" }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ] }, "customJS": { "type": [ "string", "array" ], "items": { "type": "string" } }, "editorVersion": { "type": "string" }, "mergeTags": { "type": "object" }, "mergeTagsSchema": { "type": "object" }, "designTags": { "type": "object" }, "designTagsConfig": { "type": "object" }, "safeHtml": { "type": "boolean" }, "language": { "type": "string" }, "languages": { "type": "array", "items": { "type": "string" } }, "width": { "type": "number" }, "height": { "type": "number" }, "fullPage": { "type": "boolean" }, "deviceScaleFactor": { "type": "number" } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object", "properties": { "url": { "type": "string" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "422": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "500": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "502": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates/export/pdf": { "post": { "operationId": "exportPdf", "summary": "Export PDF", "tags": [ "export" ], "description": "Export a design as a PDF document.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "design" ], "properties": { "design": { "type": "object", "description": "Unlayer design JSON" }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ] }, "customJS": { "type": [ "string", "array" ], "items": { "type": "string" } }, "editorVersion": { "type": "string" }, "mergeTags": { "type": "object" }, "mergeTagsSchema": { "type": "object" }, "designTags": { "type": "object" }, "designTagsConfig": { "type": "object" }, "safeHtml": { "type": "boolean" }, "language": { "type": "string" }, "languages": { "type": "array", "items": { "type": "string" } }, "pageSize": { "type": "string", "enum": [ "Letter", "Legal", "Tabloid", "Ledger", "A0", "A1", "A2", "A3", "A4", "A5", "A6" ] }, "contentWidth": { "oneOf": [ { "type": "number" }, { "type": "string", "enum": [ "full" ] } ] } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object", "properties": { "url": { "type": "string" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "422": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "500": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "502": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates/export/zip": { "post": { "operationId": "exportZip", "summary": "Export ZIP", "tags": [ "export" ], "description": "Export a design as a ZIP archive containing HTML and assets.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "design" ], "properties": { "design": { "type": "object", "description": "Unlayer design JSON" }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ] }, "customJS": { "type": [ "string", "array" ], "items": { "type": "string" } }, "editorVersion": { "type": "string" }, "mergeTags": { "type": "object" }, "mergeTagsSchema": { "type": "object" }, "designTags": { "type": "object" }, "designTagsConfig": { "type": "object" }, "safeHtml": { "type": "boolean" }, "language": { "type": "string" }, "languages": { "type": "array", "items": { "type": "string" } } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object", "properties": { "url": { "type": "string" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "422": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "500": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "502": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "503": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/templates/generate": { "post": { "operationId": "generateDesign", "summary": "AI design generation", "tags": [ "templates" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "messages", "output" ], "properties": { "model": { "type": "string", "description": "Preferred AI model in \"provider/id\" form, e.g. \"anthropic/claude-opus-5\". Optional — server resolves a default per output kind." }, "fallbackModels": { "anyOf": [ { "type": "boolean" }, { "type": "array", "maxItems": 10, "items": { "type": "string", "maxLength": 200 } } ], "description": "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." }, "messages": { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "object", "required": [ "role", "content" ], "properties": { "role": { "type": "string", "enum": [ "user", "assistant", "system" ] }, "content": { "type": "array", "minItems": 0, "maxItems": 50, "items": { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "text", "image", "file" ] }, "text": { "type": "string", "maxLength": 20000 }, "image": { "type": "string", "description": "URL or data URL of the image" }, "file": { "type": "object", "properties": { "url": { "type": "string" }, "mediaType": { "type": "string" } }, "required": [ "url" ], "additionalProperties": true } } } }, "metadata": { "type": "object", "properties": { "action": { "type": "object", "properties": { "id": { "type": "string" } }, "required": [ "id" ], "additionalProperties": true } }, "additionalProperties": true } } }, "description": "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)." }, "output": { "type": "object", "required": [ "kind", "displayMode" ], "properties": { "kind": { "type": "string", "enum": [ "template", "page", "body", "header", "footer", "row", "column", "content", "text" ] }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ] }, "schemaVersion": { "type": "integer" } } }, "context": { "type": "object", "properties": { "fullDesign": { "type": [ "object", "null" ], "additionalProperties": true }, "selection": { "type": [ "object", "null" ], "properties": { "collection": { "type": "string", "enum": [ "pages", "bodies", "rows", "columns", "contents", "headers", "footers" ] }, "id": { "anyOf": [ { "type": "string" }, { "type": "number" } ] }, "value": { "type": "string" } }, "required": [ "collection", "id" ], "additionalProperties": true }, "availableTools": { "type": "array", "items": { "type": "string" } }, "availableFonts": { "type": "array", "maxItems": 100, "items": { "type": "object", "required": [ "label", "value" ], "properties": { "label": { "type": "string", "minLength": 1, "maxLength": 500 }, "value": { "type": "string", "minLength": 1, "maxLength": 500 } }, "additionalProperties": false } }, "customTools": { "type": "array", "items": { "type": "object", "required": [ "slug", "options" ], "properties": { "slug": { "type": "string" }, "options": { "type": "object", "additionalProperties": true } }, "additionalProperties": true } }, "brand": { "type": [ "object", "null" ], "properties": { "companyName": { "type": "string", "maxLength": 200 }, "productDescription": { "type": "string", "maxLength": 2000 }, "targetAudience": { "type": "string", "maxLength": 2000 }, "colors": { "type": "object", "properties": { "primary": { "type": "string" }, "secondary": { "type": "string" }, "accent": { "type": "string" } }, "additionalProperties": false }, "fonts": { "type": "object", "properties": { "heading": { "type": "string", "maxLength": 200 }, "body": { "type": "string", "maxLength": 200 } }, "additionalProperties": false }, "logos": { "type": "object", "properties": { "primary": { "type": "string", "maxLength": 2048, "format": "uri", "pattern": "^https://" }, "secondary": { "type": "string", "maxLength": 2048, "format": "uri", "pattern": "^https://" } }, "additionalProperties": false }, "voice": { "type": "string", "maxLength": 2000 }, "guidelines": { "type": "string", "maxLength": 2000 } }, "additionalProperties": false } }, "additionalProperties": true }, "locale": { "type": "string", "maxLength": 100, "pattern": "^[A-Za-z0-9]{1,8}(?:-[A-Za-z0-9]{1,8})*$", "description": "BCP-47 fallback locale for AI status messages." }, "conversationId": { "type": "string", "description": "Reserved for future server-side conversation memory." } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "The generated (or modified) design plus model metadata and optional usage metadata.", "content": { "application/json": { "schema": { "description": "The generated (or modified) design plus model metadata and optional usage metadata.", "type": "object", "properties": { "id": { "type": "string", "description": "Provider response id for the generation turn." }, "output": { "type": "object", "description": "The generated output for the requested block.", "properties": { "kind": { "type": "string", "description": "Echoes the requested `output.kind`." }, "data": { "type": "object", "additionalProperties": true, "description": "The generated design JSON, scoped to the requested kind (the full design for template/page/body; the row/column/content/element for narrower kinds)." } } }, "model": { "type": "object", "description": "The provider + model that actually produced the output (may differ from the requested model after failover).", "properties": { "provider": { "type": "string", "description": "e.g. \"anthropic\", \"openai\"." }, "id": { "type": "string", "description": "Resolved model id, e.g. \"claude-opus-5\"." } } }, "usage": { "type": "object", "description": "Aggregate token usage and billed AI credits for the turn. Estimated provider cost is included only by builder copilot endpoints in local/dev/QA.", "properties": { "inputTokens": { "type": "number" }, "outputTokens": { "type": "number" }, "totalTokens": { "type": "number" }, "cachedInputTokens": { "type": "number" }, "reasoningTokens": { "type": "number" }, "aiCreditsUsed": { "type": "number", "description": "Marked-up integer AI credits used by the complete turn, including failover attempts." }, "estimatedCostMicroUsd": { "type": "number" } } } } } } } }, "304": { "description": "No changes detected — AI output is identical to input", "content": { "application/json": { "schema": { "description": "No changes detected — AI output is identical to input" } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } } } } } } } } }, "/v3/templates/import": { "post": { "operationId": "importTemplate", "summary": "Import a template from HTML or an image", "tags": [ "templates" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "displayMode", "input" ], "properties": { "model": { "type": "string", "maxLength": 200, "description": "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." }, "fallbackModels": { "anyOf": [ { "type": "boolean" }, { "type": "array", "maxItems": 10, "items": { "type": "string", "maxLength": 200 } } ], "description": "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": { "type": "string", "enum": [ "email", "web", "popup", "document" ], "description": "Display mode for the imported design" }, "input": { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "html", "image", "text" ], "description": "The type of input part. \"html\" or \"image\" carries the source content; \"text\" carries optional instructions to apply during import." }, "html": { "type": "string", "description": "HTML string to import (for type: \"html\")" }, "url": { "type": "string", "description": "Image URL to import (for type: \"image\")" }, "data": { "type": "string", "description": "Base64 image data URL, e.g. \"data:image/png;base64,…\" (for type: \"image\")" }, "text": { "type": "string", "maxLength": 20000, "description": "Optional natural-language instructions to apply during import (for type: \"text\")" } } }, "description": "Array of input parts. Must contain exactly one \"html\" or \"image\" part; may also contain one or more \"text\" parts with optional instructions." } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "projectId", "required": false, "description": "The project ID (required for PAT auth, auto-resolved for API key auth)" } ], "responses": { "200": { "description": "Successfully imported template", "content": { "application/json": { "schema": { "description": "Successfully imported template", "type": "object", "properties": { "id": { "type": "string" }, "output": { "type": "object", "properties": { "type": { "type": "string" }, "blockType": { "type": "string" }, "data": { "type": "object", "additionalProperties": true, "description": "Imported design data" } } }, "model": { "type": "string" }, "provider": { "type": "string" }, "usage": { "type": "object", "properties": { "inputTokens": { "type": "integer" }, "outputTokens": { "type": "integer" }, "totalTokens": { "type": "integer" }, "reasoningTokens": { "type": "integer" }, "cachedInputTokens": { "type": "integer" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "429": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } } } } } } } } }, "/v3/templates/schema": { "get": { "operationId": "getDesignSchema", "summary": "Get the design JSON Schema.", "tags": [ "templates" ], "description": "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.", "parameters": [ { "schema": { "type": "boolean", "default": false }, "in": "query", "name": "simple", "required": false, "description": "When true, returns the Simple schema instead of the Full schema." }, { "schema": { "type": "string", "enum": [ "email", "web", "popup", "document" ], "default": "email" }, "in": "query", "name": "displayMode", "required": false, "description": "Display mode whose rules the schema describes (email, web, document, popup). Defaults to \"email\"." } ], "security": [], "responses": { "200": { "description": "Default Response" } } } }, "/v3/templates/validate": { "post": { "operationId": "validateDesign", "summary": "Validate a design against the Unlayer schema.", "tags": [ "templates" ], "description": "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.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "design": { "type": "object", "description": "The design JSON to validate.", "additionalProperties": true }, "schema": { "type": "string", "enum": [ "full", "simple" ], "default": "full", "description": "Which form of the schema to validate against. Defaults to \"full\"." }, "displayMode": { "type": "string", "enum": [ "email", "web", "popup", "document" ], "default": "email", "description": "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": { "type": "boolean", "default": true, "description": "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." }, "customTools": { "type": "array", "description": "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.", "maxItems": 100, "items": { "type": "object", "required": [ "slug", "options" ], "properties": { "slug": { "type": "string" }, "type": { "type": "string", "default": "custom" }, "label": { "type": "string" }, "options": { "type": "object", "maxProperties": 100, "additionalProperties": { "type": "object", "properties": { "options": { "type": "object", "maxProperties": 200 } } } }, "values": { "type": "object", "additionalProperties": true }, "supportedDisplayModes": { "type": "array", "items": { "type": "string", "enum": [ "email", "web", "popup", "document" ] } } }, "additionalProperties": true } } }, "required": [ "design" ] } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "enum": [ true ] }, "data": { "type": "object", "required": [ "valid" ], "properties": { "valid": { "type": "boolean" }, "migratedFrom": { "type": "number", "description": "Present when the design was upgraded from an older schemaVersion before validation; carries the original version number." }, "errors": { "type": "array", "items": { "type": "object", "required": [ "path", "message", "code" ], "properties": { "path": { "type": "string" }, "message": { "type": "string" }, "code": { "type": "string" } } }, "description": "Populated when valid is false, capped at 100 entries. Each issue carries the dotted path to the offending field, a human-readable message, and the underlying Zod issue code." }, "errorCount": { "type": "number", "description": "Total number of issues found; greater than errors.length when the list was capped." } } } } } } } }, "400": { "description": "The request itself is malformed — e.g. the design field is missing or displayMode is unknown. The design was not checked.", "content": { "application/json": { "schema": { "description": "The request itself is malformed — e.g. the design field is missing or displayMode is unknown. The design was not checked.", "type": "object", "properties": { "error": { "type": "string", "description": "VALIDATION_ERROR" }, "message": { "type": "string" } } } } } } } } }, "/v3/webhooks": { "get": { "operationId": "listWebhooks", "summary": "List webhooks", "tags": [ "webhooks" ], "description": "List all webhook endpoints configured for a project.", "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number", "description": "Webhook ID" }, "url": { "type": "string", "description": "The HTTPS URL receiving webhook events" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "email.sent", "email.delivered", "email.bounced", "email.complained" ] }, "description": "Event types this webhook is subscribed to" }, "active": { "type": "boolean", "description": "Whether the webhook is actively receiving events" }, "createdAt": { "type": "string", "format": "date-time", "description": "When the webhook was created" } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "post": { "operationId": "createWebhook", "summary": "Create a webhook", "tags": [ "webhooks" ], "description": "Create a new webhook endpoint. A signing secret is auto-generated and returned once. Use it to verify webhook signatures.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string", "format": "uri", "description": "The HTTPS URL to receive webhook events" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "email.sent", "email.delivered", "email.bounced", "email.complained" ] }, "description": "Event types to subscribe to. If omitted or empty, all events are sent." }, "active": { "type": "boolean", "default": true, "description": "Whether the webhook is active" } } } } }, "required": true }, "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number", "description": "Webhook ID" }, "url": { "type": "string", "description": "The HTTPS URL receiving webhook events" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "email.sent", "email.delivered", "email.bounced", "email.complained" ] }, "description": "Event types this webhook is subscribed to" }, "active": { "type": "boolean", "description": "Whether the webhook is actively receiving events" }, "secret": { "type": "string", "description": "Signing secret — only returned on creation. Store it securely; you will not be able to retrieve it again." }, "createdAt": { "type": "string", "format": "date-time", "description": "When the webhook was created" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/webhooks/{id}": { "get": { "operationId": "getWebhook", "summary": "Get webhook details", "tags": [ "webhooks" ], "description": "Get details of a specific webhook endpoint.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Webhook ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number", "description": "Webhook ID" }, "url": { "type": "string", "description": "The HTTPS URL receiving webhook events" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "email.sent", "email.delivered", "email.bounced", "email.complained" ] }, "description": "Event types this webhook is subscribed to" }, "active": { "type": "boolean", "description": "Whether the webhook is actively receiving events" }, "createdAt": { "type": "string", "format": "date-time", "description": "When the webhook was created" }, "updatedAt": { "type": "string", "format": "date-time", "description": "When the webhook was last updated" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "patch": { "operationId": "updateWebhook", "summary": "Update a webhook", "tags": [ "webhooks" ], "description": "Update a webhook endpoint URL, events, or active status.", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "url": { "type": "string", "format": "uri", "description": "The HTTPS URL to receive webhook events" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "email.sent", "email.delivered", "email.bounced", "email.complained" ] }, "description": "Event types to subscribe to. If omitted or empty, all events are sent." }, "active": { "type": "boolean", "description": "Whether the webhook is actively receiving events" } } } } }, "required": true }, "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Webhook ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number", "description": "Webhook ID" }, "url": { "type": "string", "description": "The HTTPS URL receiving webhook events" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "email.sent", "email.delivered", "email.bounced", "email.complained" ] }, "description": "Event types this webhook is subscribed to" }, "active": { "type": "boolean", "description": "Whether the webhook is actively receiving events" }, "updatedAt": { "type": "string", "format": "date-time", "description": "When the webhook was last updated" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } }, "delete": { "operationId": "deleteWebhook", "summary": "Delete a webhook", "tags": [ "webhooks" ], "description": "Delete a webhook endpoint. It will no longer receive events.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Webhook ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "success": { "type": "boolean" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/webhooks/{id}/rotate-secret": { "post": { "operationId": "rotateWebhookSecret", "summary": "Rotate webhook signing secret", "tags": [ "webhooks" ], "description": "Generate a new signing secret for a webhook. The new secret is returned once — store it securely. The old secret is invalidated immediately.", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true, "description": "Webhook ID" } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "required": [ "data" ], "properties": { "data": { "type": "object", "properties": { "id": { "type": "number" }, "secret": { "type": "string", "description": "New signing secret — only returned once. Store it securely." }, "updatedAt": { "type": "string", "format": "date-time" } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/workspaces": { "get": { "operationId": "listWorkspaces", "summary": "List accessible workspaces.", "tags": [ "workspaces" ], "description": "Get all workspaces accessible by the current token. Requires a Personal Access Token (PAT).", "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number" }, "name": { "type": "string" } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } }, "/v3/workspaces/{workspaceId}": { "get": { "operationId": "getWorkspace", "summary": "Get workspace by ID.", "tags": [ "workspaces" ], "description": "Get a specific workspace by ID with its projects. Requires a Personal Access Token (PAT).", "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "workspaceId", "required": true, "description": "The workspace ID" } ], "security": [ { "personalAccessTokenAuth": [] } ], "responses": { "200": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "id": { "type": "number" }, "name": { "type": "string" }, "projects": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number" }, "name": { "type": "string" }, "status": { "type": "string" } } } } } } } } } } }, "400": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "401": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "403": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } }, "404": { "description": "Default Response", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "description": "Error code" }, "message": { "type": "string", "description": "Human-readable error message" } }, "required": [ "error", "message" ] } } } } } } } }, "servers": [ { "url": "https://api.unlayer.com" } ], "security": [ { "apiKeyAuth": [] }, { "personalAccessTokenAuth": [] } ], "tags": [ { "name": "me", "description": "Current user and token context." }, { "name": "projects", "description": "Project details and configuration." }, { "name": "templates", "description": "Template management — list, retrieve, generate, import, export, and convert designs." }, { "name": "workspaces", "description": "Workspace access and management." }, { "name": "blocks", "description": "Reusable design blocks — list shared project blocks and end-user saved blocks for backup, migration, and usage reporting." }, { "name": "ai-credits", "description": "AI credit balance, usage breakdown, and webhook/alert settings. Credits are pooled per workspace; settings are per project." }, { "name": "editor-sessions", "description": "Ephemeral editor session creation and access." }, { "name": "export", "description": "Render designs as HTML, images, PDFs, or ZIP files." }, { "name": "emails", "description": "Send and manage transactional email." }, { "name": "domains", "description": "Manage verified sender domains." }, { "name": "webhooks", "description": "Manage Developer Email API webhooks." } ], "x-tagGroups": [ { "name": "Resources", "tags": [ "me", "projects", "templates", "workspaces", "blocks", "ai-credits", "editor-sessions", "export", "emails", "domains", "webhooks" ] } ] }