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 templates
  • GET https://api.sidemail.io/v1/templates/{id} - Retrieve a template
  • POST https://api.sidemail.io/v1/templates - Create a template
  • PATCH https://api.sidemail.io/v1/templates/{id} - Update a template
  • GET https://api.sidemail.io/v1/templates/gallery - List gallery templates
  • GET 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 unless includeContent is true.
  • 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 version 2.
  • 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 in templateProps. 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 of left, center, or right.
  • 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, and textDecoration: Text style overrides.
  • linkColor and linkTextDecoration: Link style overrides.
  • backgroundColor, borderWidth, borderColor, and borderRadius: Color and border overrides.
  • paddingTop, paddingBottom, paddingLeft, and paddingRight: 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 as default, title, or muted.
{
  "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. Use number for 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 of left, center, or right.
  • rows (array): Array of rows. Each row is an array of cells containing a text string.
  • iterationTarget (string, optional): Set to children together with iterationKey to 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 in templateProps.
  • chartType (string): One of line or bar.
  • curve (string, optional): For line charts, one of monotone or linear.
  • fill (boolean, optional): Whether to fill the chart background.
  • maxValue (number, optional): Maximum value displayed on the Y axis.
  • xAxisStartLabel and xAxisEndLabel (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 of text, javascript, php, ruby, python, or bash.
{
  "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 of top, middle, or bottom.
  • 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.


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"]
    }
  ]
}