openapi: 3.0.0
info:
contact: {}
description: API for managing email content, templates and universal layouts
title: Email Templates API
version: '5.0'
x-api-evangelist:
harvested: '2026-08-13'
method: searched
source: https://dash.readme.com/api/v1/api-registry/9c1ckrq8msfxryye
source-note: Published by Omnisend on its own docs host api-docs.omnisend.com (ReadMe project @omnisend,
branch v2026-03-15); registry document referenced by the reference page as oasPublicUrl.
paths:
/email-templates:
get:
description: 'With this endpoint you can get a paginated list of email templates.
**Sorting:**
Use `sort` and `direction` to control the order of results.
Supported sort fields: `createdAt` (default), `name`.
Supported directions: `asc`, `desc` (default).
**Filtering:**
Use `nameContains` to filter templates by name (case-insensitive partial match, max 200 characters)
**Pagination:**
This endpoint uses cursor-based pagination for efficient traversal of large datasets.
- Use the `paging.cursors.after` value from the response to get the next page
- Use the `paging.cursors.before` value from the response to get the previous page
- The `paging.hasMore` field indicates if more results are available
- Do not use both `after` and `before` parameters simultaneously
- Maximum page size is 100 items (default 50)
- If `limit` is less than 1 or greater than 100, returns 400 Bad Request
**Scopes:**
`email-templates.read`
**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.'
parameters:
- description: Number of items per page (1-100, default 50)
in: query
name: limit
schema:
type: integer
minimum: 1
maximum: 100
- description: Cursor for next page (base64-encoded, from previous response)
in: query
name: after
schema:
type: string
- description: Cursor for previous page (base64-encoded, from previous response)
in: query
name: before
schema:
type: string
- description: Sort field (createdAt, name; default createdAt)
in: query
name: sort
schema:
type: string
enum:
- createdAt
- name
- description: Sort direction (asc, desc; default desc)
in: query
name: direction
schema:
type: string
enum:
- asc
- desc
- description: Filter templates by name (case-insensitive partial match, max 200 characters)
in: query
name: nameContains
schema:
type: string
maxLength: 200
- $ref: '#/components/parameters/APIVersionHeader'
responses:
'200':
description: List of email templates with pagination
content:
application/json:
schema:
$ref: '#/components/schemas/TemplateListResponse'
'400':
description: Invalid query parameters or missing brand ID
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.read
- ApiKeyAuth: []
summary: Get email templates
tags:
- Email Templates
post:
description: 'With this endpoint you can create a new email template.
**Scopes:**
`email-templates.write`
**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.'
parameters:
- $ref: '#/components/parameters/APIVersionHeader'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
description: Template to create
required: true
responses:
'201':
description: Created Template
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'400':
description: Invalid request body, missing brand ID, invalid template structure, or validation
errors
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'413':
description: Request body too large - exceeds 1 MB limit
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.write
- ApiKeyAuth: []
summary: Create email template
tags:
- Email Templates
/email-templates/{id}:
delete:
description: 'With this endpoint you can delete email template by ID.
**Scopes:**
`email-templates.write`
**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.'
parameters:
- description: Email Template ID (24 character hexadecimal)
in: path
name: id
required: true
schema:
type: string
- $ref: '#/components/parameters/APIVersionHeader'
responses:
'204':
description: No Content
'400':
description: Invalid template ID or missing brand ID
content:
'*/*':
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
'*/*':
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
'*/*':
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
'*/*':
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
'*/*':
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
'*/*':
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.write
- ApiKeyAuth: []
summary: Delete email template
tags:
- Email Templates
get:
description: 'With this endpoint you can get email template by ID.
**Scopes:**
`email-templates.read`
**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.'
parameters:
- description: Email Template ID (24 character hexadecimal)
in: path
name: id
required: true
schema:
type: string
- $ref: '#/components/parameters/APIVersionHeader'
responses:
'200':
description: Template
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'400':
description: Invalid template ID or missing brand ID
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Template not found
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.read
- ApiKeyAuth: []
summary: Get email template
tags:
- Email Templates
put:
description: 'With this endpoint you can update (fully replace) an email template by ID.
**Scopes:**
`email-templates.write`
**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.'
parameters:
- description: Email Template ID (24 character hexadecimal)
in: path
name: id
required: true
schema:
type: string
- $ref: '#/components/parameters/APIVersionHeader'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
description: Template to update
required: true
responses:
'200':
description: Updated Template
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'400':
description: Invalid template ID, request body, missing brand ID, invalid template structure,
or validation errors
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Template not found
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'413':
description: Request body too large - exceeds 1 MB limit
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.write
- ApiKeyAuth: []
summary: Update email template
tags:
- Email Templates
/email-templates/{id}/render:
post:
description: 'With this endpoint you can render an email template by ID and get the full HTML body
for preview purposes.
**Scopes:**
`email-templates.write`
**Rate Limiting:**
This endpoint is rate limited to 40 requests per minute.'
parameters:
- description: Email Template ID (24 character hexadecimal)
in: path
name: id
required: true
schema:
type: string
- $ref: '#/components/parameters/APIVersionHeader'
responses:
'200':
description: Rendered HTML body
content:
application/json:
schema:
additionalProperties:
type: string
type: object
'400':
description: Invalid template ID or missing brand ID
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Template not found
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.write
- ApiKeyAuth: []
summary: Render email template
tags:
- Email Templates
/email-templates/import:
post:
description: 'With this endpoint you can import email template from raw HTML content.
The HTML will be parsed, styles extracted, and structured into a template.
**Request body size limit:** 1 MB
**Scopes:**
`email-templates.write`
**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.'
parameters:
- $ref: '#/components/parameters/APIVersionHeader'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ImportTemplateRequest'
description: Template name and HTML content to import
required: true
responses:
'201':
description: Imported Template
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'400':
description: Invalid request body or missing brand ID
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'401':
description: Authentication is missing or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'403':
description: Insufficient permissions for this operation
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'410':
description: API version has been retired
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'413':
description: Request body too large - exceeds 1 MB limit
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'500':
description: Unexpected error occurred
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
security:
- Bearer:
- email-templates.write
- ApiKeyAuth: []
summary: Import email template from HTML
tags:
- Email Templates
servers:
- url: https://api.omnisend.com/api
components:
parameters:
APIVersionHeader:
description: API version that specifies the response format and behaviour
in: header
name: Omnisend-Version
required: true
schema:
type: string
default: '2026-03-15'
securitySchemes:
ApiKeyAuth:
in: header
name: Authorization
type: apiKey
Bearer:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://app.omnisend.com/oauth2/token
scopes:
email-templates.read: Allows reading email templates and universal layouts
email-templates.write: Allows create, update, delete email templates and universal layouts
schemas:
APIErrorResponse:
description: RFC 9457 Problem Details error response
properties:
detail:
description: Human-readable explanation specific to this occurrence
example: One or more fields are invalid.
type: string
errors:
description: List of field-level validation errors
items:
$ref: '#/components/schemas/FieldError'
type: array
instance:
description: URI reference identifying the specific occurrence
example: urn:omnisend:request:abc123
type: string
status:
description: HTTP status code
example: 400
type: integer
title:
description: Short human-readable summary of the problem
example: Validation failed
type: string
type:
description: URI reference identifying the problem type
example: https://problems.omnisend.com/validation-failed
type: string
type: object
Annotation:
description: Gmail annotation settings
properties:
discountDescription:
description: Gmail discount description - description of the discount or promotion to display
in Gmail promotion tab together with the discount code.
example: 15% off
type: string
isEnabled:
description: Gmail annotation enabled
example: true
type: boolean
type: object
Block:
description: Block is a single element in the email template
properties:
button:
$ref: '#/components/schemas/Button'
components:
description: 'Components - the parts a block renders that are not covered by its own content
field.
Some blocks tag each part with a ''role'', and which roles they need is decided by their ''type'':
a ''discount'' block holds the code, the redeem button and the expiry date, a ''menu'' block
holds
its items, a ''product'' block holds the product''s image, title, description, prices and
button.
Other blocks nest components without a role, and blocks that render everything from a dedicated
content field have no components at all. See BlockComponent.'
items:
$ref: '#/components/schemas/BlockComponent'
type: array
discount:
$ref: '#/components/schemas/Discount'
dynamicDiscount:
$ref: '#/components/schemas/Discount'
html:
description: 'Deprecated: use HTMLCode instead. Read-only, will be removed in future versions.'
example: <p>Hello</p>
readOnly: true
type: string
htmlCode:
$ref: '#/components/schemas/HTMLCode'
id:
description: Block unique identifier - must be unique within the template
example: 6699a0000000000000000000
maxLength: 24
minLength: 24
type: string
image:
$ref: '#/components/schemas/Image'
lineSpace:
$ref: '#/components/schemas/LineSpace'
logo:
$ref: '#/components/schemas/Logo'
orderAddresses:
$ref: '#/components/schemas/OrderAddresses'
orderProducts:
$ref: '#/components/schemas/OrderProducts'
orderSummary:
$ref: '#/components/schemas/OrderSummary'
orderTotal:
$ref: '#/components/schemas/OrderTotal'
preheader:
$ref: '#/components/schemas/Preheader'
product:
$ref: '#/components/schemas/Product'
role:
description: Block role
enum:
- product_image
- product_title
- product_description
- product_prices
- product_price
- product_button
- discount_code
- discount_button
- discount_expiration_date
- product_current_price
- product_old_price
- menu_text
example: product_title
type: string
secondaryStylePresetID:
description: Secondary style preset ID - ID of the secondary style preset. Used for order blocks
styling as smaller text style.
example: paragraph
type: string
social:
$ref: '#/components/schemas/Social'
staticDiscount:
$ref: '#/components/schemas/Discount'
stylePresetID:
description: 'Style preset ID - ID of the style preset. Used for Button or Text block styling.
ID must be present in template General Settings.'
example: paragraph
type: string
styleProperties:
allOf:
- $ref: '#/components/schemas/StyleProperties'
description: Style properties - style properties of the block
text:
description: Text content of the block - supports HTML formatting and personalization tags
example: <p>Hello [[contact.first_name]]</p>
type: string
type:
description: "Block type.\nNotes:\n - 'html' is read-only and cannot be set on create/update.\n\
\ - 'menu' is a container block with no dedicated content field — items must be provided\
\ via 'components' as text blocks with role 'menu_text', and styling is configured through\
\ 'stylePresetID' and 'styleProperties'.\n - 'discount' is the block for an offer. The offer\
\ is configured in the 'discount' object, and everything the recipient sees must be provided\
\ via 'components' as role-tagged blocks — a text block with role 'discount_code' (required,\
\ exactly one), plus an optional button with role 'discount_button' and an optional text block\
\ with role 'discount_expiration_date'. The store issues a code per recipient when the email\
\ is sent, so 'discount.code' carries the placeholder XXXX-XXXX-XXXX. Writing the offer as\
\ plain text instead leaves a code that was never created in the store, so the recipient cannot\
\ redeem it.\n - 'dynamicDiscount' is the WooCommerce equivalent of 'discount' — same object,\
\ same components and placeholder, except that the 'discount_button' component is required.\
\ A 'discount' block on a WooCommerce store is skipped when the email is sent, so it ships\
\ the placeholder to the recipient as the code.\n - 'staticDiscount' (WooCommerce) instead\
\ carries one fixed code that already exists in the store, and gets no code at send time.\
\ It does not accept a 'discount_button'. Use it only when the brand explicitly asked for\
\ a fixed code."
enum:
- html
- htmlCode
- text
- image
- video
- logo
- menu
- social
- button
- product
- discount
- staticDiscount
- dynamicDiscount
- orderSummary
- orderProducts
- orderTotal
- orderAddresses
- lineSpace
- preheader
- price
example: text
type: string
video:
$ref: '#/components/schemas/Video'
type: object
BlockComponent:
description: 'BlockComponent is a block nested inside a parent block, carrying one part of what
that parent renders. Some parent blocks assign a ''role'' to each of their parts, and then the
parent''s ''type'' decides which roles it needs: a ''discount'' block requires text/discount_code
and accepts button/discount_button and text/discount_expiration_date; its WooCommerce equivalents
take the same roles, except that ''dynamicDiscount'' requires the button and ''staticDiscount''
does not accept one. A ''menu'' block holds its items as text/menu_text. The product_* roles belong
to a ''product'' block, whose price/product_prices component nests text/product_current_price
and text/product_old_price components of its own. Blocks that do not assign roles nest their components
without one.'
properties:
button:
allOf:
- $ref: '#/components/schemas/Button'
description: Button content of the component - used by roles 'discount_button' and 'product_button'.
components:
description: Components nested inside this component. Only role 'product_prices' uses them.
items:
$ref: '#/components/schemas/BlockComponent'
type: array
html:
description: 'Deprecated: use Text instead. Read-only, will be removed in future versions.'
example: <p>Hello</p>
readOnly: true
type: string
id:
description: Component unique identifier - must be unique within the template
example: 6699a0000000000000000000
maxLength: 24
minLength: 24
type: string
image:
allOf:
- $ref: '#/components/schemas/Image'
description: Image content of the component - used by role 'product_image'.
role:
description: 'Role the component plays inside its parent block - set only where the parent block
assigns
roles to its parts, and omitted otherwise.'
enum:
- discount_code
- discount_button
- discount_expiration_date
- menu_text
- product_image
- product_title
- product_description
- product_prices
- product_price
- product_button
- product_current_price
- product_old_price
example: discount_code
type: string
stylePresetID:
description: Style preset ID - ID of the style preset. ID must be present in template General
Settings.
example: paragraph
type: string
styleProperties:
allOf:
- $ref: '#/components/schemas/StyleProperties'
description: Style properties - style properties of the component
text:
description: 'Text content of the component - supports HTML formatting and personalization tags.
For role ''discount_code'' this is the code the recipient sees; on a platform that issues
its own codes
it is replaced at send time, so it carries the placeholder XXXX-XXXX-XXXX.'
example: <p>XXXX-XXXX-XXXX</p>
type: string
type:
description: Component type. Only these block types can be nested as a component.
enum:
- text
- button
- image
- price
example: text
type: string
type: object
Body:
description: Body settings for the template
properties:
backgroundColor:
description: Body background color
example: '#EDEEF0'
type: string
backgroundImageID:
description: Body background image ID - must be present in Image API
example: 68f0ad8a72105230579523cd
maxLength: 24
minLength: 24
type: string
backgroundRepeat:
description: Body background repeat
example: no-repeat
type: string
backgroundSize:
description: Body background size
example: cover
type: string
type: object
Button:
description: Button block settings
properties:
isFullWidth:
description: Button is full width
example: true
type: boolean
link:
description: Button link
example: https://www.omnisend.com
type: string
text:
description: Button text
example: Shop now
type: string
translationKey:
description: Button translation key - used for internationalization support
example: shop_now
type: string
type: object
ButtonPreset:
description: Button preset for consistent design
properties:
id:
description: Button preset unique identifier
example: primary_button
type: string
name:
description: Button preset name
example: Primary button
type: string
styles:
allOf:
- $ref: '#/components/schemas/ButtonStyle'
description: Button preset styles
type: object
ButtonStyle:
description: Button preset style properties
properties:
backgroundColor:
description: Button background color
example: '#383838'
type: string
border:
description: Button border style
example: '2px solid #BFDCFE'
type: string
borderRadius:
description: Button border radius
example: 0px
type: string
color:
description: Button font color
example: '#FFFFFF'
type: string
fontFamily:
description: Button font family
example: Alegreya, Georgia, Times New Roman, serif
type: s
# --- truncated at 32 KB (83 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/omnisend/refs/heads/main/openapi/omnisend-emailtemplates-api-openapi.yml