Templates API methods (unstable)
Sidemail Templates API lets you create and manage reusable email templates via API. Use templates to keep email subjects and content consistent, then send emails using a template name or ID.
Available API endpoints:
GET https://api.sidemail.io/v1/templates- List templatesGET https://api.sidemail.io/v1/templates/{id}- Retrieve a templatePOST https://api.sidemail.io/v1/templates- Create a templatePATCH https://api.sidemail.io/v1/templates/{id}- Update a templateGET https://api.sidemail.io/v1/templates/gallery- List gallery templatesGET https://api.sidemail.io/v1/templates/fonts- List available template fonts
Template Object
A template object represents a reusable email template.
id(string): Unique identifier of the template.name(string): Unique template name within the project.subject(string): Email subject. Template variables are supported.content(array): Template content nodes. Omitted from list responses unlessincludeContentistrue.emailText(string or null, optional): Custom plain-text email content.preheader(string or null, optional): Preview text displayed by supported email clients.sampleProps(object or null, optional): Example template variable values shown when previewing the template in the Sidemail editor. These values are not used when sending emails. Values can be strings, arrays of non-negative numbers, or arrays of objects.layoutId(string or null, optional): Identifier of the project template layout used to wrap the template. A null or unknown layout ID uses the default auto-generated layout.version(number, read-only): Template content format version. Templates returned by this API use version2.createdAt(string): ISO8601 date string when the template was created.updatedAt(string, optional): ISO8601 date string when the template was last updated.
Content nodes
The content array contains the nodes rendered in the email. Supported node
types are text, button, list, table, divider, image, chart,
code, and box.
Every content node uses these common fields:
id(string, optional): Unique identifier of the node. Sidemail generates an ID when it is missing or duplicated in a create or update request.type(string): Node type.styles(object, optional): Node style overrides.iterationKey(string, optional): Name of an array intemplateProps. The node is repeated for every item in the array.
Text values, links, labels, image properties, and table cells can contain
template variables using {variable_name} syntax.
Node styles
The fields supported inside styles depend on the node type. Common fields
include:
marginBottom(number): Space below the node in pixels.align(string): One ofleft,center, orright.width(number or string): Width in pixels or as a percentage such as"100%".height(number or string): Node height.fontFamily,fontSize,fontWeight,fontStyle,lineHeight,letterSpacing,color,textTransform, andtextDecoration: Text style overrides.linkColorandlinkTextDecoration: Link style overrides.backgroundColor,borderWidth,borderColor, andborderRadius: Color and border overrides.paddingTop,paddingBottom,paddingLeft, andpaddingRight: Padding in pixels.dark(object): Style overrides applied in dark mode when dark mode is enabled in the project template design.mobile(object): Style overrides applied on small screens.
Text element
text(string): Text content. Markdown and template variables are supported.preset(string, optional): Text style preset ID, such asdefault,title, ormuted.
{
"id": "text-title",
"type": "text",
"preset": "title",
"text": "Welcome to {project_name}",
"styles": {
"marginBottom": 20,
"align": "left"
}
}
Button element
label(string): Button label. Template variables are supported.url(string): Button destination URL. Template variables are supported.preset(string, optional): Button style preset ID.
{
"id": "button-account",
"type": "button",
"label": "Open your account",
"url": "{account_url}",
"styles": {
"marginBottom": 20,
"align": "left"
}
}
List element
items(array of strings): List item content. Markdown and template variables are supported.symbol(string, optional): List marker. Usenumberfor a numbered list or an empty string to hide markers.preset(string, optional): List style preset ID.
{
"id": "list-links",
"type": "list",
"items": [
"Read our [documentation]({docs_url})",
"Contact {support_email}"
],
"symbol": "›",
"styles": {
"marginBottom": 20
}
}
Table element
columns(array): Table column definitions.label(string): Column heading.align(string, optional): One ofleft,center, orright.
rows(array): Array of rows. Each row is an array of cells containing atextstring.iterationTarget(string, optional): Set tochildrentogether withiterationKeyto repeat the first row for every item in the array. The default repeats the complete table.
{
"id": "table-invoice",
"type": "table",
"columns": [
{ "label": "Item", "align": "left" },
{ "label": "Price", "align": "right" }
],
"rows": [
[
{ "text": "{name}" },
{ "text": "{price}" }
]
],
"iterationKey": "items",
"iterationTarget": "children",
"styles": {
"marginBottom": 20
}
}
Divider element
The divider has no content-specific fields. Use styles.borderWidth,
styles.borderColor, and styles.borderRadius to customize it.
{
"id": "divider-footer",
"type": "divider",
"styles": {
"marginBottom": 20,
"borderWidth": 1,
"borderColor": "#e6e6e6"
}
}
Image element
src(string): Image URL. Template variables are supported.darkModeSrc(string, optional): Image URL used in dark mode.alt(string): Alternative text. Template variables are supported.href(string or null, optional): Link opened when the image is clicked.
{
"id": "image-banner",
"type": "image",
"src": "https://example.com/banner.png",
"darkModeSrc": "https://example.com/banner-dark.png",
"alt": "Welcome to {project_name}",
"href": "{account_url}",
"styles": {
"marginBottom": 20,
"align": "center",
"width": "100%",
"borderRadius": 8
}
}
Chart element
dataKey(string): Name of an array of non-negative numbers intemplateProps.chartType(string): One oflineorbar.curve(string, optional): For line charts, one ofmonotoneorlinear.fill(boolean, optional): Whether to fill the chart background.maxValue(number, optional): Maximum value displayed on the Y axis.xAxisStartLabelandxAxisEndLabel(string, optional): Labels displayed at the start and end of the X axis.
{
"id": "chart-usage",
"type": "chart",
"dataKey": "usage",
"chartType": "line",
"curve": "monotone",
"fill": true,
"maxValue": 100,
"xAxisStartLabel": "30 days ago",
"xAxisEndLabel": "Now",
"styles": {
"marginBottom": 20
}
}
The matching template props would contain:
{
"usage": [20, 35, 42, 70, 85]
}
Code element
code(string): Code content.language(string): One oftext,javascript,php,ruby,python, orbash.
{
"id": "code-install",
"type": "code",
"code": "npm install @sidemail/sidemail",
"language": "bash",
"styles": {
"marginBottom": 20
}
}
Box element
columns(array): Box columns.width(string or number, optional): Column width, such as"50%"or"200px".elements(array): Content elements rendered inside the column. Elements can be nested recursively.
styles.gap(number, optional): Space between columns in pixels.styles.verticalAlign(string, optional): One oftop,middle, orbottom.styles.mobile.stackColumns(boolean, optional): Whether columns stack on small screens.
{
"id": "box-summary",
"type": "box",
"columns": [
{
"width": "50%",
"elements": [
{
"id": "box-summary-title",
"type": "text",
"text": "**Current plan**"
}
]
},
{
"width": "50%",
"elements": [
{
"id": "box-summary-value",
"type": "text",
"text": "{plan_name}"
}
]
}
],
"styles": {
"marginBottom": 20,
"gap": 20,
"verticalAlign": "top",
"mobile": {
"stackColumns": true
}
}
}
Example Template Object
{
"id": "65dc4595af2e7a530209b414",
"name": "Welcome",
"subject": "Welcome to {project_name}",
"preheader": "Your account is ready.",
"sampleProps": {
"project_name": "Acme"
},
"content": [
{
"id": "i3f5n6a8q",
"type": "text",
"preset": "title",
"text": "Welcome to {project_name}",
"styles": {
"marginBottom": 20
}
},
{
"id": "r2n9c4m7x",
"type": "button",
"label": "Open your account",
"url": "{account_url}"
}
],
"emailText": null,
"layoutId": "custom-layout",
"version": 2,
"createdAt": "2026-06-12T09:00:00.000Z",
"updatedAt": "2026-06-12T09:30:00.000Z"
}
List templates
GET https://api.sidemail.io/v1/templates
Returns templates sorted by creation date, with the most recent templates appearing first.
curl -X GET "https://api.sidemail.io/v1/templates?limit=100" \
-H "Authorization: Bearer replace-with-your-api-key"
Parameters
paginationCursorNext string optional
Cursor for fetching the next page of templates. Use the
paginationCursorNext value returned by the previous request.
limit number optional
Number of templates returned per page. The default and maximum value is 100.
includeContent boolean optional
Whether to include the content array for each template. Defaults to false
to reduce response size.
Returns
Returns a data property containing an array of template objects, hasMore
indicating whether another page is available, and paginationCursorNext for
fetching that page. Template content is omitted unless includeContent is
true.
{
"hasMore": true,
"paginationCursorNext": "65dc4595af2e7a530209b413",
"data": [
{
"id": "65dc4595af2e7a530209b414",
"name": "Welcome",
"subject": "Welcome to {project_name}",
"layoutId": null,
"version": 2
}
]
}
Retrieve a template
GET https://api.sidemail.io/v1/templates/{id}
Returns a template by ID.
curl -X GET "https://api.sidemail.io/v1/templates/65dc4595af2e7a530209b414" \
-H "Authorization: Bearer replace-with-your-api-key"
Parameters
id string
Unique identifier of the template.
Returns
Returns the template under the data property.
{
"data": {
"id": "65dc4595af2e7a530209b414",
"name": "Welcome",
"subject": "Welcome to {project_name}",
"content": [],
"layoutId": null,
"version": 2
}
}
Create a template
POST https://api.sidemail.io/v1/templates
Creates a template. Template names must be unique.
curl -X POST "https://api.sidemail.io/v1/templates" \
-H "Authorization: Bearer replace-with-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome",
"subject": "Welcome to {project_name}",
"preheader": "Your account is ready.",
"layoutId": "custom-layout",
"sampleProps": {
"project_name": "Acme"
},
"content": [
{
"type": "text",
"preset": "title",
"text": "Welcome to {project_name}"
},
{
"type": "button",
"label": "Open your account",
"url": "{account_url}"
}
]
}'
Parameters
name string
Required. Unique template name within the project. Maximum 200 characters.
subject string
Required. Email subject. Maximum 1,000 characters.
content array optional
Template content nodes. Sidemail generates IDs for nodes that do not have a unique ID.
emailText string or null optional
Custom plain-text email content. Maximum 1 MB.
preheader string or null optional
Email preview text. Maximum 200 characters.
sampleProps object or null optional
Example values for template variables shown when previewing the template in the Sidemail editor. These values are not used when sending emails. Values can be strings, arrays of non-negative numbers, or arrays of objects.
layoutId string or null optional
Identifier of the project template layout used to wrap the template. Maximum
20 characters. Use null or omit this field to use the default auto-generated
layout.
Returns
Returns the created template under the data property.
{
"data": {
"id": "65dc4595af2e7a530209b414",
"name": "Welcome",
"subject": "Welcome to {project_name}",
"content": [
{
"id": "i3f5n6a8q",
"type": "text",
"preset": "title",
"text": "Welcome to {project_name}"
}
],
"layoutId": "custom-layout",
"version": 2,
"createdAt": "2026-06-12T09:00:00.000Z"
}
}
Creating a template with an existing name returns 403 Forbidden with the
resource-duplicate error code.
Update a template
PATCH https://api.sidemail.io/v1/templates/{id}
Updates the provided fields of a template.
curl -X PATCH "https://api.sidemail.io/v1/templates/65dc4595af2e7a530209b414" \
-H "Authorization: Bearer replace-with-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"subject": "Welcome, {first_name}",
"preheader": "Your account is ready."
}'
Parameters
id string
Unique identifier of the template.
The request body accepts the same template fields as the create endpoint. All fields are optional and only the provided fields are updated.
Returns
Returns the updated template under the data property.
{
"data": {
"id": "65dc4595af2e7a530209b414",
"name": "Welcome",
"subject": "Welcome, {first_name}",
"preheader": "Your account is ready.",
"content": [],
"layoutId": "custom-layout",
"version": 2,
"updatedAt": "2026-06-12T09:30:00.000Z"
}
}
Updating a template to an existing name returns 403 Forbidden with the
resource-duplicate error code.
List gallery templates
GET https://api.sidemail.io/v1/templates/gallery
Returns the templates available in the Sidemail template gallery. Gallery templates can be submitted to the create template endpoint.
curl -X GET "https://api.sidemail.io/v1/templates/gallery" \
-H "Authorization: Bearer replace-with-your-api-key"
Parameters
No parameters.
Returns
Returns gallery templates under the data property. Gallery templates include
slug and tags metadata and do not include a saved template ID.
{
"data": [
{
"name": "Welcome",
"slug": "welcome",
"tags": ["transactional", "marketing"],
"subject": "Welcome to {project_name}",
"version": 2,
"sampleProps": {
"project_name": "Company name"
},
"content": [
{
"id": "i3f5n6a8q",
"type": "text",
"preset": "title",
"text": "Hi there!"
}
]
}
]
}
List available template fonts
GET https://api.sidemail.io/v1/templates/fonts
Returns fonts that can be used by the Sidemail template editor.
curl -X GET "https://api.sidemail.io/v1/templates/fonts" \
-H "Authorization: Bearer replace-with-your-api-key"
Parameters
No parameters.
Returns
{
"data": [
{
"name": "Roboto",
"category": "sans-serif",
"variants": ["regular", "700"],
"subsets": ["latin"]
}
]
}