> ## Documentation Index
> Fetch the complete documentation index at: https://spreecommerce.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List email templates

> Returns every email template merchants may edit: the emails customers
receive, the email layout and the shared partials. Each shows what
customers receive now (the store's published version, else Spree's
default) and any draft in progress. Staff emails are not editable.


**Required scope:** `read_email_templates` (for API-key authentication).



## OpenAPI

````yaml /api-reference/admin.yaml get /api/v3/admin/email_templates
openapi: 3.0.3
info:
  title: Admin API
  contact:
    name: Spree Commerce
    url: https://spreecommerce.org
    email: hello@spreecommerce.org
  description: >
    Spree Admin API v3 - Administrative API for managing products, orders, and
    store settings.


    ## Authentication


    The Admin API requires a secret API key passed in the `x-spree-api-key`
    header.

    Secret API keys can be generated in the Spree admin dashboard.


    ## Response Format


    All responses are JSON. List endpoints return paginated responses with
    `data` and `meta` keys.

    Single resource endpoints return a flat JSON object.


    ## Resource IDs


    Every resource is identified by an opaque string ID (e.g. `prod_86Rf07xd4z`,

    `variant_k5nR8xLq`, `or_UkLWZg9DAJ`). Use these IDs everywhere — URL paths,

    request bodies, and Ransack filters all accept them directly.


    ## Error Handling


    Errors return a consistent format:

    ```json

    {
      "error": {
        "code": "validation_error",
        "message": "Validation failed",
        "details": { "name": ["can't be blank"] }
      }
    }

    ```
  version: v3
servers:
  - url: http://{defaultHost}
    variables:
      defaultHost:
        default: localhost:3000
security: []
tags:
  - name: Authentication
    description: Admin user login, logout, token refresh, and current user profile
  - name: Allowed Origins
    description: CORS allowlist for storefront and admin client origins
  - name: API Keys
    description: Secret and publishable API keys
  - name: Categories
    description: >-
      Hierarchical product categories — tree management, repositioning, and
      product assignments
  - name: Channels
    description: >-
      Sales channels, product publication across channels, and per-channel order
      routing rules
  - name: Custom Fields
    description: >-
      Custom field definitions for products, variants, customers, and other
      resources
  - name: Customer Groups
    description: >-
      Customer groups for segmenting customers (e.g. wholesale, VIP) used by
      pricing and promotions
  - name: Customers
    description: Customer profiles, addresses, credit cards, and store credits
  - name: Email Templates
    description: >-
      Customer email templates, the email layout and shared partials: drafts,
      previews, publishing and history
  - name: Exports
    description: Async CSV exports of admin resources
  - name: Files
    description: Uploading the files that product media, imports, logos and documents use
  - name: Fulfillments
    description: Order fulfillments — shipments, fulfill, cancel, resume, split
  - name: Gift Cards
    description: Gift cards and gift card batches
  - name: Imports
    description: >-
      Async CSV imports of admin resources, with per-row status and failed-row
      retry
  - name: Markets
    description: >-
      Markets — geographic groupings of countries used for pricing, tax, and
      fulfillment rules
  - name: Option Types
    description: >-
      Option types and option values used to build product variants (e.g. Size,
      Color)
  - name: Orders
    description: Orders, order items, applied gift cards, and applied store credits
  - name: Payment Methods
    description: Configured payment providers and their available types
  - name: Payments
    description: Order payments — list, capture, void
  - name: Pricing
    description: >-
      Prices and price lists for currency-, market-, and customer-group-specific
      pricing
  - name: Products
    description: >-
      Products, taxons/categories, product custom field values, and bulk product
      operations
  - name: Policies
    description: The store's legal documents — terms of service, privacy, returns, shipping
  - name: Reasons
    description: >-
      Merchant-owned vocabularies for why a return, claim, refund, cancellation
      or tax exemption happened
  - name: Promotions
    description: Promotions, promotion rules, promotion actions, and coupon codes
  - name: Refunds
    description: Order refunds
  - name: Settings
    description: Store-level settings — store profile, tags, and configuration
  - name: Staff
    description: Admin users, roles, and invitations to the store
  - name: Stock Locations
    description: Warehouses and physical fulfillment locations
  - name: Store Credits
    description: Prepaid customer balances across all customers, and each balance's ledger
  - name: Variants
    description: >-
      Product variants — the individual SKUs (size/color combinations) sold
      under a product
  - name: Webhooks
    description: Webhook endpoints and webhook delivery history
paths:
  /api/v3/admin/email_templates:
    get:
      tags:
        - Email Templates
      summary: List email templates
      description: |-
        Returns every email template merchants may edit: the emails customers
        receive, the email layout and the shared partials. Each shows what
        customers receive now (the store's published version, else Spree's
        default) and any draft in progress. Staff emails are not editable.


        **Required scope:** `read_email_templates` (for API-key authentication).
      parameters:
        - name: x-spree-api-key
          in: header
          required: true
          schema:
            type: string
        - name: Authorization
          in: header
          required: true
          description: Bearer token for admin authentication
          schema:
            type: string
        - name: language
          in: query
          required: false
          description: >-
            A language code, or `any` (the default) for the version every
            language uses
          schema:
            type: string
      responses:
        '200':
          description: email templates found
          content:
            application/json:
              example:
                data:
                  - id: spree.order_mailer.confirm_email
                    key: spree/order_mailer/confirm_email
                    subject: Order {{ order.number }} confirmed
                    body: >
                      <mj-section><mj-column><mj-text>Thanks for your order, {{
                      order.customer_name }}!</mj-text></mj-column></mj-section>
                    language: any
                    customized_languages: []
                    kind: email
                    customized: false
                    published_at: null
                    default_subject: Order {{ order.number }} confirmed
                    default_body: >
                      <mj-section><mj-column><mj-text>Thanks for your order, {{
                      order.customer_name }}!</mj-text></mj-column></mj-section>
                    published_language: null
                    default_changed: false
                    base_subject: null
                    base_body: null
                    draft: null
                  - id: layouts.spree.base_mailer
                    key: layouts/spree/base_mailer
                    subject: null
                    body: >
                      {% assign brand = store.branding %}<mjml lang="{{ locale
                      }}">
                        <mj-head>
                          <mj-title>{{ subject }}</mj-title>
                          {% if brand.font_url %}<mj-font name="{{ brand.font_family | split: ',' | first }}" href="{{ brand.font_url }}" />{% endif %}
                          <mj-attributes>
                            <mj-all font-family="{{ brand.font_family }}" />
                            <mj-section padding="0" />
                            <mj-column padding="0" />
                            <mj-text padding="0" color="{{ brand.text_color }}" font-size="14px" line-height="1.6" align="center" />
                            <mj-button background-color="{{ brand.button_color }}" border="{{ brand.button_border }}" border-radius="8px" color="{{ brand.button_text_color }}" font-size="15px" font-weight="500" line-height="1.6" inner-padding="12px 20px" padding="32px 0 0" />
                            <mj-table padding="0" color="{{ brand.text_color }}" font-size="14px" line-height="1.6" />
                            <mj-class name="heading" font-family="{{ brand.heading_font_family }}" font-size="40px" font-weight="700" line-height="1.2" letter-spacing="-0.8px" color="{{ brand.heading_color }}" css-class="heading" />
                            <mj-class name="greeting" padding="24px 0 0" font-size="15px" font-weight="500" color="{{ brand.heading_color }}" />
                            <mj-class name="lead" padding="12px 0 0" />
                            <mj-class name="note" padding="24px 0 0" font-size="13px" css-class="note" />
                            <mj-class name="section-heading" padding="48px 0 16px" font-family="{{ brand.heading_font_family }}" font-size="16px" font-weight="500" letter-spacing="-0.16px" align="left" />
                            <mj-class name="body" padding="16px 0 0" align="left" />
                            <mj-class name="footer" padding="12px 0 0" font-size="11px" line-height="1.5" />
                          </mj-attributes>
                          <mj-style>
                            {% if brand.font == 'inter' %}
                            @font-face { font-family: "Geist"; font-style: normal; font-weight: 500 700; src: url("https://fonts.gstatic.com/s/geist/v4/gyByhwUxId8gMEwcGFU.woff2") format("woff2"); }
                            @font-face { font-family: "Inter"; font-style: normal; font-weight: 400 450; src: url("https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuOKfMZg.ttf") format("truetype"); }
                            @font-face { font-family: "Inter"; font-style: normal; font-weight: 500; src: url("https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuI6fMZg.ttf") format("truetype"); }
                            @font-face { font-family: "Inter"; font-style: normal; font-weight: 600; src: url("https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuGKYMZg.ttf") format("truetype"); }
                            {% endif %}
                            a { color: {{ brand.link_color }}; }
                            .hero > table { max-width: 420px; margin: 0 auto; }
                            .note a { color: {{ brand.text_color }}; word-break: break-all; }
                            .footer a { color: {{ brand.text_color }}; }
                            .item { width: 100%; background-color: #F0F0F0; border-radius: 16px; margin: 0 0 8px; }
                            .item_image { padding: 8px; width: 96px; }
                            .item_thumb { display: block; width: 80px; height: auto; border-radius: 12px; }
                            .item_thumb_placeholder { width: 80px; height: 80px; background-color: #E4E4E4; border-radius: 12px; }
                            .item_info { padding: 8px 16px 8px 8px; }
                            .item_name { font-size: 15px; line-height: 1.5; font-weight: 500; color: {{ brand.heading_color }}; text-decoration: none; }
                            .item_meta { margin: 2px 0 0; font-size: 13px; line-height: 1.5; color: {{ brand.text_color }}; }
                            .item_amount { padding: 8px 16px 8px 8px; text-align: right; white-space: nowrap; }
                            .item_qty { margin: 0; font-size: 13px; line-height: 1.5; color: {{ brand.text_color }}; }
                            .item_price { margin: 2px 0 0; font-size: 15px; line-height: 1.5; font-weight: 500; color: {{ brand.heading_color }}; }
                            .summary td { padding: 6px 0; font-size: 14px; line-height: 1.6; color: {{ brand.text_color }}; }
                            .summary_value { font-size: 15px; font-weight: 500; text-align: right; white-space: nowrap; color: {{ brand.heading_color }}; }
                            .summary_sub { display: block; font-size: 13px; line-height: 1.5; }
                            .summary_total td { padding: 14px 0 0; border-top: 1px solid #E8E9E9; font-weight: 500; color: {{ brand.heading_color }}; }
                            .summary_total .summary_value { font-weight: 600; }
                            .mailer_hero h1 { margin: 0; font-family: {{ brand.heading_font_family }}; font-size: 40px; line-height: 1.2; letter-spacing: -0.8px; font-weight: 700; color: {{ brand.heading_color }}; }
                            .mailer_hero p { margin: 12px 0 0; }
                            .mailer_hero .greeting { margin-top: 24px; font-size: 15px; font-weight: 500; color: {{ brand.heading_color }}; }
                            .mailer_hero .sub { margin-top: 24px; font-size: 13px; }
                            @media only screen and (max-width: 600px) {
                              .heading div { font-size: 32px !important; letter-spacing: -0.64px !important; }
                            }
                          </mj-style>
                        </mj-head>
                        <mj-body background-color="{{ brand.background_color }}" width="640px">
                          <mj-wrapper background-color="{{ brand.card_color }}" padding="56px 24px">
                            <mj-section padding="0 0 32px">
                              <mj-column>
                                {% if store.logo_url and store.logo_width %}
                                  <mj-image src="{{ store.logo_url }}" href="{{ store.url }}" alt="{{ store.name }}" width="{{ store.logo_width }}px" height="32px" padding="0" />
                                {% elsif store.logo_url %}
                                  <mj-text><a href="{{ store.url }}"><img src="{{ store.logo_url }}" alt="{{ store.name }}" height="32" style="height: 32px; width: auto; border: 0;" /></a></mj-text>
                                {% else %}
                                  <mj-text font-size="22px" font-weight="700" color="{{ brand.heading_color }}" text-transform="uppercase"><a href="{{ store.url }}" style="color: {{ brand.heading_color }}; text-decoration: none;">{{ store.name }}</a></mj-text>
                                {% endif %}
                              </mj-column>
                            </mj-section>
                            {{ content_for_layout }}
                          </mj-wrapper>
                          <mj-section padding="64px 24px">
                            <mj-column>
                              <mj-text font-size="13px" line-height="1.5" css-class="footer"><a href="{{ store.url }}" style="font-weight: 500; text-decoration: none;">{{ store.name }}</a></mj-text>
                              {% if store.address != blank %}<mj-text mj-class="footer">{{ store.address }}</mj-text>{% endif %}
                              {% if store.support_email != blank %}<mj-text mj-class="footer" css-class="footer"><a href="mailto:{{ store.support_email }}">{{ store.support_email }}</a></mj-text>{% endif %}
                              <mj-text mj-class="footer" padding="20px 0 0">&copy; {{ 'now' | date: '%Y' }} {{ store.name }}</mj-text>
                            </mj-column>
                          </mj-section>
                        </mj-body>
                      </mjml>
                    language: any
                    customized_languages: []
                    kind: layout
                    customized: false
                    published_at: null
                    default_subject: null
                    default_body: >
                      {% assign brand = store.branding %}<mjml lang="{{ locale
                      }}">
                        <mj-head>
                          <mj-title>{{ subject }}</mj-title>
                          {% if brand.font_url %}<mj-font name="{{ brand.font_family | split: ',' | first }}" href="{{ brand.font_url }}" />{% endif %}
                          <mj-attributes>
                            <mj-all font-family="{{ brand.font_family }}" />
                            <mj-section padding="0" />
                            <mj-column padding="0" />
                            <mj-text padding="0" color="{{ brand.text_color }}" font-size="14px" line-height="1.6" align="center" />
                            <mj-button background-color="{{ brand.button_color }}" border="{{ brand.button_border }}" border-radius="8px" color="{{ brand.button_text_color }}" font-size="15px" font-weight="500" line-height="1.6" inner-padding="12px 20px" padding="32px 0 0" />
                            <mj-table padding="0" color="{{ brand.text_color }}" font-size="14px" line-height="1.6" />
                            <mj-class name="heading" font-family="{{ brand.heading_font_family }}" font-size="40px" font-weight="700" line-height="1.2" letter-spacing="-0.8px" color="{{ brand.heading_color }}" css-class="heading" />
                            <mj-class name="greeting" padding="24px 0 0" font-size="15px" font-weight="500" color="{{ brand.heading_color }}" />
                            <mj-class name="lead" padding="12px 0 0" />
                            <mj-class name="note" padding="24px 0 0" font-size="13px" css-class="note" />
                            <mj-class name="section-heading" padding="48px 0 16px" font-family="{{ brand.heading_font_family }}" font-size="16px" font-weight="500" letter-spacing="-0.16px" align="left" />
                            <mj-class name="body" padding="16px 0 0" align="left" />
                            <mj-class name="footer" padding="12px 0 0" font-size="11px" line-height="1.5" />
                          </mj-attributes>
                          <mj-style>
                            {% if brand.font == 'inter' %}
                            @font-face { font-family: "Geist"; font-style: normal; font-weight: 500 700; src: url("https://fonts.gstatic.com/s/geist/v4/gyByhwUxId8gMEwcGFU.woff2") format("woff2"); }
                            @font-face { font-family: "Inter"; font-style: normal; font-weight: 400 450; src: url("https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuOKfMZg.ttf") format("truetype"); }
                            @font-face { font-family: "Inter"; font-style: normal; font-weight: 500; src: url("https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuI6fMZg.ttf") format("truetype"); }
                            @font-face { font-family: "Inter"; font-style: normal; font-weight: 600; src: url("https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuGKYMZg.ttf") format("truetype"); }
                            {% endif %}
                            a { color: {{ brand.link_color }}; }
                            .hero > table { max-width: 420px; margin: 0 auto; }
                            .note a { color: {{ brand.text_color }}; word-break: break-all; }
                            .footer a { color: {{ brand.text_color }}; }
                            .item { width: 100%; background-color: #F0F0F0; border-radius: 16px; margin: 0 0 8px; }
                            .item_image { padding: 8px; width: 96px; }
                            .item_thumb { display: block; width: 80px; height: auto; border-radius: 12px; }
                            .item_thumb_placeholder { width: 80px; height: 80px; background-color: #E4E4E4; border-radius: 12px; }
                            .item_info { padding: 8px 16px 8px 8px; }
                            .item_name { font-size: 15px; line-height: 1.5; font-weight: 500; color: {{ brand.heading_color }}; text-decoration: none; }
                            .item_meta { margin: 2px 0 0; font-size: 13px; line-height: 1.5; color: {{ brand.text_color }}; }
                            .item_amount { padding: 8px 16px 8px 8px; text-align: right; white-space: nowrap; }
                            .item_qty { margin: 0; font-size: 13px; line-height: 1.5; color: {{ brand.text_color }}; }
                            .item_price { margin: 2px 0 0; font-size: 15px; line-height: 1.5; font-weight: 500; color: {{ brand.heading_color }}; }
                            .summary td { padding: 6px 0; font-size: 14px; line-height: 1.6; color: {{ brand.text_color }}; }
                            .summary_value { font-size: 15px; font-weight: 500; text-align: right; white-space: nowrap; color: {{ brand.heading_color }}; }
                            .summary_sub { display: block; font-size: 13px; line-height: 1.5; }
                            .summary_total td { padding: 14px 0 0; border-top: 1px solid #E8E9E9; font-weight: 500; color: {{ brand.heading_color }}; }
                            .summary_total .summary_value { font-weight: 600; }
                            .mailer_hero h1 { margin: 0; font-family: {{ brand.heading_font_family }}; font-size: 40px; line-height: 1.2; letter-spacing: -0.8px; font-weight: 700; color: {{ brand.heading_color }}; }
                            .mailer_hero p { margin: 12px 0 0; }
                            .mailer_hero .greeting { margin-top: 24px; font-size: 15px; font-weight: 500; color: {{ brand.heading_color }}; }
                            .mailer_hero .sub { margin-top: 24px; font-size: 13px; }
                            @media only screen and (max-width: 600px) {
                              .heading div { font-size: 32px !important; letter-spacing: -0.64px !important; }
                            }
                          </mj-style>
                        </mj-head>
                        <mj-body background-color="{{ brand.background_color }}" width="640px">
                          <mj-wrapper background-color="{{ brand.card_color }}" padding="56px 24px">
                            <mj-section padding="0 0 32px">
                              <mj-column>
                                {% if store.logo_url and store.logo_width %}
                                  <mj-image src="{{ store.logo_url }}" href="{{ store.url }}" alt="{{ store.name }}" width="{{ store.logo_width }}px" height="32px" padding="0" />
                                {% elsif store.logo_url %}
                                  <mj-text><a href="{{ store.url }}"><img src="{{ store.logo_url }}" alt="{{ store.name }}" height="32" style="height: 32px; width: auto; border: 0;" /></a></mj-text>
                                {% else %}
                                  <mj-text font-size="22px" font-weight="700" color="{{ brand.heading_color }}" text-transform="uppercase"><a href="{{ store.url }}" style="color: {{ brand.heading_color }}; text-decoration: none;">{{ store.name }}</a></mj-text>
                                {% endif %}
                              </mj-column>
                            </mj-section>
                            {{ content_for_layout }}
                          </mj-wrapper>
                          <mj-section padding="64px 24px">
                            <mj-column>
                              <mj-text font-size="13px" line-height="1.5" css-class="footer"><a href="{{ store.url }}" style="font-weight: 500; text-decoration: none;">{{ store.name }}</a></mj-text>
                              {% if store.address != blank %}<mj-text mj-class="footer">{{ store.address }}</mj-text>{% endif %}
                              {% if store.support_email != blank %}<mj-text mj-class="footer" css-class="footer"><a href="mailto:{{ store.support_email }}">{{ store.support_email }}</a></mj-text>{% endif %}
                              <mj-text mj-class="footer" padding="20px 0 0">&copy; {{ 'now' | date: '%Y' }} {{ store.name }}</mj-text>
                            </mj-column>
                          </mj-section>
                        </mj-body>
                      </mjml>
                    published_language: null
                    default_changed: false
                    base_subject: null
                    base_body: null
                    draft: null
                meta: {}
      security:
        - api_key: []
          bearer_auth: []
      x-codeSamples:
        - lang: javascript
          label: Spree Admin SDK
          source: |-
            import { createAdminClient } from '@spree/admin-sdk'

            const client = createAdminClient({
              baseUrl: 'https://your-store.com',
              secretKey: 'sk_xxx',
            })

            const templates = await client.emailTemplates.list()
        - lang: bash
          label: Spree CLI
          source: spree api get /email_templates
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: x-spree-api-key
      in: header
      description: Secret API key for admin access
    bearer_auth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for admin user authentication

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.