API ReferenceEndpointsEmail

Email

Email settings and transactional templates (order confirmation, shipping notification, password reset, …). Templates support Handlebars with safe-by-default escaping. Use these endpoints to customize per-store branding and edit individual templates.

Two auth surfaces on this page.

  • Public API (Authorization: Bearer brainerce_*) — the 8 /v1/email/* operations are the part external integrators are meant to call: settings, templates CRUD, and preview.
  • Dashboard API (Clerk JWT) — the 34 operations mounted under /stores/{storeId}/email/* power the merchant dashboard. They are internal and not part of the public contract — paths, fields, and behaviour can change without notice.

Get email settings for a store

GET
/stores/{storeId}/email/settings
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/settings"
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "emailsEnabled": true,
  "defaultFromName": "My Store",
  "defaultReplyTo": "[email protected]",
  "eventSettings": {},
  "hourlyRateLimit": 100,
  "customDomainId": "string",
  "dailyCampaignSendLimit": 0,
  "clickTrackingEnabled": false,
  "footerAddress": "string",
  "footerSocialLinks": [
    {}
  ],
  "footerCustomText": "string",
  "fontFamily": "Georgia",
  "deliveryProviderOverride": "RESEND",
  "sesTenantName": "string",
  "marketingSendingPaused": false,
  "marketingPauseReason": "string",
  "marketingPausedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "customDomain": {
    "id": "clx1a2b3c4d5e6f7g8h9",
    "storeId": "string",
    "domain": "mail.mystore.com",
    "status": "PENDING",
    "dnsRecords": [
      {}
    ],
    "provider": "AWS_SES",
    "providerIdentityId": "string",
    "providerRegion": "string",
    "mailFromDomain": "bounce.mail.mystore.com",
    "dkimStatus": "string",
    "mailFromStatus": "string",
    "resendDomainId": "string",
    "verifiedAt": "2019-08-24T14:15:22Z",
    "lastCheckedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  },
  "hasOwnerEmail": true
}

Update email settings for a store

PUT
/stores/{storeId}/email/settings
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
emailsEnabled?boolean

Whether emails are enabled for this store

Defaulttrue
clickTrackingEnabled?boolean

Track link clicks in marketing campaigns. Off by default, because enabling it starts recording which recipients clicked, so the store owner must opt in rather than inherit it. Opens are never tracked.

defaultFromName?string

Default from name for emails

defaultReplyTo?string

Reply-to email address

eventSettings?object

Per-event settings

Empty Object

hourlyRateLimit?number

Hourly rate limit for emails

Default100
Range1 <= value <= 1000
customDomainId?string

Custom domain ID to use for sending

footerAddress?string

Physical postal address shown in the footer of marketing mail. Required before any marketing-class message can be sent. CAN-SPAM mandates a visible business address, and the send is refused without one.

curl -X PUT "https://api.brainerce.com/api/stores/string/email/settings" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "emailsEnabled": true,
  "defaultFromName": "My Store",
  "defaultReplyTo": "[email protected]",
  "eventSettings": {},
  "hourlyRateLimit": 100,
  "customDomainId": "string",
  "dailyCampaignSendLimit": 0,
  "clickTrackingEnabled": false,
  "footerAddress": "string",
  "footerSocialLinks": [
    {}
  ],
  "footerCustomText": "string",
  "fontFamily": "Georgia",
  "deliveryProviderOverride": "RESEND",
  "sesTenantName": "string",
  "marketingSendingPaused": false,
  "marketingPauseReason": "string",
  "marketingPausedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "customDomain": {
    "id": "clx1a2b3c4d5e6f7g8h9",
    "storeId": "string",
    "domain": "mail.mystore.com",
    "status": "PENDING",
    "dnsRecords": [
      {}
    ],
    "provider": "AWS_SES",
    "providerIdentityId": "string",
    "providerRegion": "string",
    "mailFromDomain": "bounce.mail.mystore.com",
    "dkimStatus": "string",
    "mailFromStatus": "string",
    "resendDomainId": "string",
    "verifiedAt": "2019-08-24T14:15:22Z",
    "lastCheckedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
}

Get all email templates for a store

GET
/stores/{storeId}/email/templates
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates"
{
  "templates": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "accountId": "string",
      "storeId": "string",
      "name": "Default",
      "eventType": "ORDER_CONFIRMATION",
      "language": "en",
      "subject": "Order {{orderNumber}} Confirmed",
      "htmlContent": "string",
      "textContent": "string",
      "variables": {},
      "isDefault": false,
      "isActive": true,
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "language": "en",
  "supportedLanguages": [
    "en",
    "he"
  ]
}

Create a new email template

POST
/stores/{storeId}/email/templates
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
namestring

Template display name

eventTypestring

Event type this template is for

Value in"ORDER_CONFIRMATION" | "ORDER_SHIPPED" | "ORDER_CANCELLED" | "ORDER_COMPLETED" | "ORDER_REFUNDED" | "ORDER_NOTE" | "NEW_ORDER_ADMIN" | "NEW_CUSTOMER" | "LOW_STOCK_ALERT" | "CART_ABANDONED" | "EMAIL_VERIFICATION" | "TEAM_INVITATION" | "ORDERS_LINKED" | "STORE_INVITATION" | "STORE_ROLE_CHANGED" | "STORE_DELETED" | "EXPORT_COMPLETE" | "SCHEDULED_BACKUP_SUCCESS" | "SCHEDULED_BACKUP_FAILED" | "PASSWORD_RESET" | "INQUIRY_NEW_ADMIN" | "INQUIRY_REPLY_CUSTOMER" | "INQUIRY_CONFIRMATION_CUSTOMER" | "MARKETING_CAMPAIGN"
languagestring

Locale this template is for (must be in store.supportedLanguages)

subjectstring

Email subject line (supports Handlebars)

htmlContentstring

HTML content of the email (supports Handlebars)

textContent?string

Plain text content of the email

variables?object

Variable schema for this template

Empty Object

isActive?boolean

Whether this template is active

Defaulttrue
curl -X POST "https://api.brainerce.com/api/stores/string/email/templates" \  -H "Content-Type: application/json" \  -d '{    "name": "Order Confirmation",    "eventType": "ORDER_CONFIRMATION",    "language": "en",    "subject": "Order #{{orderNumber}} Confirmed",    "htmlContent": "<h1>Thank you for your order!</h1>"  }'
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "accountId": "string",
  "storeId": "string",
  "name": "Default",
  "eventType": "ORDER_CONFIRMATION",
  "language": "en",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": false,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates"
}

Get default email templates

GET
/stores/{storeId}/email/templates/defaults
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates/defaults"
[
  {
    "eventType": "ORDER_CONFIRMATION",
    "subject": "Order #{{orderNumber}} Confirmed - {{storeName}}",
    "htmlContent": "string",
    "textContent": "string",
    "isDefault": true
  }
]

Get default template for event type

GET
/stores/{storeId}/email/templates/defaults/{eventType}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
eventTypestring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates/defaults/string"
{
  "eventType": "ORDER_CONFIRMATION",
  "subject": "Order #{{orderNumber}} Confirmed - {{storeName}}",
  "htmlContent": "string",
  "textContent": "string",
  "isDefault": true
}

Get a specific email template

GET
/stores/{storeId}/email/templates/{templateId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates/string"
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "accountId": "string",
  "storeId": "string",
  "name": "Default",
  "eventType": "ORDER_CONFIRMATION",
  "language": "en",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": false,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}"
}

Delete an email template

DELETE
/stores/{storeId}/email/templates/{templateId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
curl -X DELETE "https://api.brainerce.com/api/stores/string/email/templates/string"
Empty

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}"
}

Update an email template

PUT
/stores/{storeId}/email/templates/{templateId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
name?string

Template display name

subject?string

Email subject line (supports Handlebars)

htmlContent?string

HTML content of the email (supports Handlebars)

textContent?string

Plain text content of the email

variables?object

Variable schema for this template

Empty Object

isActive?boolean

Whether this template is active

curl -X PUT "https://api.brainerce.com/api/stores/string/email/templates/string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "accountId": "string",
  "storeId": "string",
  "name": "Default",
  "eventType": "ORDER_CONFIRMATION",
  "language": "en",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": false,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}"
}

Reset a template to its default design

POST
/stores/{storeId}/email/templates/{templateId}/reset
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/string/reset"
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "accountId": "string",
  "storeId": "string",
  "name": "Default",
  "eventType": "ORDER_CONFIRMATION",
  "language": "en",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": false,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}/reset"
}

Reset all templates to their default designs

POST
/stores/{storeId}/email/templates/reset-all
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/reset-all"
{
  "success": true,
  "message": "All templates reset to default"
}

Add a language to the store and seed its email templates

POST
/stores/{storeId}/email/templates/languages
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/languages"
{
  "added": true,
  "language": "he",
  "seeded": 48
}

Remove a language from the store and delete its email templates

DELETE
/stores/{storeId}/email/templates/languages/{language}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
languagestring
curl -X DELETE "https://api.brainerce.com/api/stores/string/email/templates/languages/string"
{
  "removed": true,
  "language": "he",
  "deleted": 48
}

Preview a template with sample data

POST
/stores/{storeId}/email/templates/{templateId}/preview
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
variables?object

Sample variables for rendering the template

Empty Object

curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/string/preview" \  -H "Content-Type: application/json" \  -d '{}'
{
  "subject": "Order #1042 Confirmed",
  "html": "string",
  "text": "string"
}

Send a test email

POST
/stores/{storeId}/email/templates/{templateId}/test
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
toEmailstring

Email address to send test to

variables?object

Sample variables for rendering the template

Empty Object

htmlContent?string

Current HTML content (for testing unsaved changes)

subject?string

Current subject line (for testing unsaved changes)

curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/string/test" \  -H "Content-Type: application/json" \  -d '{    "toEmail": "[email protected]"  }'
{
  "success": true,
  "emailLogId": "string",
  "resendEmailId": "string",
  "error": "Test email is taking longer than expected. Check the email logs for the result."
}

Preview a default template for an event type

GET
/stores/{storeId}/email/templates/default/{eventType}/preview
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
eventTypestring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates/default/string/preview"
{
  "subject": "Order #1042 Confirmed",
  "html": "string",
  "text": "string"
}

Get variable schema for an event type

GET
/stores/{storeId}/email/templates/variables/{eventType}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

eventTypestring
curl -X GET "https://api.brainerce.com/api/stores/{storeId}/email/templates/variables/string"
{
  "storeName": "Store name",
  "orderNumber": "Order number"
}

Generate a template using AI

POST
/stores/{storeId}/email/templates/ai/generate
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
eventTypestring

Event type for the template

Value in"ORDER_CONFIRMATION" | "ORDER_SHIPPED" | "ORDER_CANCELLED" | "ORDER_COMPLETED" | "ORDER_REFUNDED" | "ORDER_NOTE" | "NEW_ORDER_ADMIN" | "NEW_CUSTOMER" | "LOW_STOCK_ALERT" | "CART_ABANDONED" | "EMAIL_VERIFICATION" | "TEAM_INVITATION" | "ORDERS_LINKED" | "STORE_INVITATION" | "STORE_ROLE_CHANGED" | "STORE_DELETED" | "EXPORT_COMPLETE" | "SCHEDULED_BACKUP_SUCCESS" | "SCHEDULED_BACKUP_FAILED" | "PASSWORD_RESET" | "INQUIRY_NEW_ADMIN" | "INQUIRY_REPLY_CUSTOMER" | "INQUIRY_CONFIRMATION_CUSTOMER" | "MARKETING_CAMPAIGN"
descriptionstring

Description of the desired template style

language?string

Language for the template content

Default"en"
includeVariables?array<string>

Variables to include in the template

curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/ai/generate" \  -H "Content-Type: application/json" \  -d '{    "eventType": "ORDER_CONFIRMATION",    "description": "Modern minimalist design with blue colors"  }'
{
  "subject": "Order #{{orderNumber}} is on its way",
  "htmlContent": "string",
  "textContent": "string"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/ai/generate"
}

Stream tool-call driven edits for an email template (Editor v3)

Server-Sent Events endpoint. Each event is a JSON envelope on a data: line. Event types: email:thought, email:tool_call, email:tool_applied, email:tool_failed, email:summary, email:cap_reached, email:turn_complete, error. Frontend consumes via response.body.getReader() / TextDecoder, NOT EventSource (since the request body carries the instruction).

POST
/stores/{storeId}/email/templates/ai/stream-edit
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring

The template the merchant is editing. If currentHtml is not provided, the backend loads this template's saved HTML from the DB and applies tool-call edits to it.

instructionstring

Natural-language instruction in the merchant's language (Hebrew or English).

currentHtml?string

The merchant's LIVE in-canvas HTML (post-edit, pre-save). Sending this makes sequential edits compose correctly: turn B operates on the result of turn A even though A hasn't been saved to the DB yet. When omitted, the backend falls back to the DB-saved version of the template, which is appropriate for the very first edit of a session but causes silent loss of any unsaved in-memory edits across subsequent turns. The dashboard chat always sends this; external integrations may omit it.

curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/ai/stream-edit" \  -H "Content-Type: application/json" \  -d '{    "templateId": "tpl_abc123",    "instruction": "Change the CTA background to brand purple and make the headline friendlier."  }'
Empty

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/ai/stream-edit"
}

Proactive suggestions for an email template (Editor v3 Phase 6)

Runs 6 deterministic checks (touch-target size, subject length, missing image alt, WCAG AA contrast, missing unsubscribe link, brand color drift) and returns up to 6 suggestions. The merchant clicks a chip → fix_instruction flows through the existing tool-call pipeline. Cached server-side for 60s; invalidated on template save.

GET
/stores/{storeId}/email/templates/{templateId}/suggestions
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates/string/suggestions"
{
  "suggestions": [
    {
      "id": "string",
      "checkType": "subject-length",
      "severity": "warning",
      "message": "Your subject line is longer than 60 characters and will be cut off on mobile.",
      "fix_instruction": "string"
    }
  ]
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}/suggestions"
}

Insert a deterministic block fragment (Editor v3 Phase 4b.5)

No-LLM block insertion for the Add Block popover. Splices a pre-defined brand-aware fragment into the template via the same insert_section dispatcher the AI uses, then persists the result. Zero token cost.

POST
/stores/{storeId}/email/templates/{templateId}/blocks
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
blockTypestring

Type of block to insert. One of the canonical popover cards.

Value in"hero" | "text" | "cta" | "image" | "divider" | "items" | "footer"
afterUid?string

Optional: uid of the element to insert AFTER. When omitted, the block is appended at the end of the body.

curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/string/blocks" \  -H "Content-Type: application/json" \  -d '{    "blockType": "hero"  }'
{
  "htmlContent": "string"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}/blocks"
}

Snapshot the template after an accepted AI turn (Editor v3 Phase 7)

Writes a new EmailTemplateVersion row from the template's current htmlContent. Auto-seeds a pinned "Original" on first call. Oldest non-pinned rows beyond 20 are trimmed.

POST
/stores/{storeId}/email/templates/{templateId}/versions/snapshot
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
turnSummary?string

One-sentence description of the turn this snapshot captures (shown in the History drawer). Optional: null is rendered as "Auto-snapshot".

thumbnail?string

Optional base64 data-URL or remote URL of a thumbnail rendered from the email preview. Kept opaque to the backend, since the drawer just renders it.

curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/string/versions/snapshot" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}/versions/snapshot"
}

List version-history snapshots for a template (Editor v3 Phase 7)

Newest first, pinned Original last. Returns metadata + thumbnails only. The full htmlContent loads on restore.

GET
/stores/{storeId}/email/templates/{templateId}/versions
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/templates/string/versions"
{
  "versions": [
    {
      "id": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "createdBy": "user_2abc",
      "turnSummary": "Bumped CTA background to brand purple",
      "thumbnail": "string",
      "isOriginal": false
    }
  ]
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}/versions"
}

Restore a prior version (Editor v3 Phase 7)

Copies the version's htmlContent back into the EmailTemplate and writes a new snapshot capturing the restored state, so the restore is itself undoable via History.

POST
/stores/{storeId}/email/templates/{templateId}/versions/{versionId}/restore
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
templateIdstring
versionIdstring
curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/string/versions/string/restore"
{
  "htmlContent": "string"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/{templateId}/versions/{versionId}/restore"
}

Generate an image using gpt-image-2 for email templates

POST
/stores/{storeId}/email/templates/ai/generate-image
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
promptstring

Description of the image to generate

size?string

Size of the generated image

Default"1792x1024"
Value in"1024x1024" | "1792x1024" | "1024x1792"
curl -X POST "https://api.brainerce.com/api/stores/string/email/templates/ai/generate-image" \  -H "Content-Type: application/json" \  -d '{    "prompt": "A professional header image for an order confirmation email with shopping bags"  }'
{
  "url": "https://cdn.example.com/email-assets/store_123/9f3a2b1c8d7e.png",
  "revisedPrompt": "string"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/templates/ai/generate-image"
}

Get all domains for a store

GET
/stores/{storeId}/email/domains
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/domains"
[
  {
    "id": "clx1a2b3c4d5e6f7g8h9",
    "storeId": "string",
    "domain": "mail.mystore.com",
    "status": "PENDING",
    "dnsRecords": [
      {}
    ],
    "provider": "AWS_SES",
    "providerIdentityId": "string",
    "providerRegion": "string",
    "mailFromDomain": "bounce.mail.mystore.com",
    "dkimStatus": "string",
    "mailFromStatus": "string",
    "resendDomainId": "string",
    "verifiedAt": "2019-08-24T14:15:22Z",
    "lastCheckedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
]

Create a new domain

POST
/stores/{storeId}/email/domains
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
domainstring

Domain name for email sending

curl -X POST "https://api.brainerce.com/api/stores/string/email/domains" \  -H "Content-Type: application/json" \  -d '{    "domain": "mail.mystore.com"  }'
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "storeId": "string",
  "domain": "mail.mystore.com",
  "status": "PENDING",
  "dnsRecords": [
    {}
  ],
  "provider": "AWS_SES",
  "providerIdentityId": "string",
  "providerRegion": "string",
  "mailFromDomain": "bounce.mail.mystore.com",
  "dkimStatus": "string",
  "mailFromStatus": "string",
  "resendDomainId": "string",
  "verifiedAt": "2019-08-24T14:15:22Z",
  "lastCheckedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/domains"
}

Refresh a domain's verification status from the email provider

POST
/stores/{storeId}/email/domains/{domainId}/verify
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
domainIdstring
curl -X POST "https://api.brainerce.com/api/stores/string/email/domains/string/verify"
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "storeId": "string",
  "domain": "mail.mystore.com",
  "status": "PENDING",
  "dnsRecords": [
    {}
  ],
  "provider": "AWS_SES",
  "providerIdentityId": "string",
  "providerRegion": "string",
  "mailFromDomain": "bounce.mail.mystore.com",
  "dkimStatus": "string",
  "mailFromStatus": "string",
  "resendDomainId": "string",
  "verifiedAt": "2019-08-24T14:15:22Z",
  "lastCheckedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/domains/{domainId}/verify"
}

Delete a domain

DELETE
/stores/{storeId}/email/domains/{domainId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
domainIdstring
curl -X DELETE "https://api.brainerce.com/api/stores/string/email/domains/string"
Empty

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/domains/{domainId}"
}

Get email logs for a store

GET
/stores/{storeId}/email/logs
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring

Query Parameters

page?number

Page number

Default1
Range1 <= value
limit?number

Items per page

Default20
Range1 <= value
eventType?string

Filter by event type

Value in"ORDER_CONFIRMATION" | "ORDER_SHIPPED" | "ORDER_CANCELLED" | "ORDER_COMPLETED" | "ORDER_REFUNDED" | "ORDER_NOTE" | "NEW_ORDER_ADMIN" | "NEW_CUSTOMER" | "LOW_STOCK_ALERT" | "CART_ABANDONED" | "EMAIL_VERIFICATION" | "TEAM_INVITATION" | "ORDERS_LINKED" | "STORE_INVITATION" | "STORE_ROLE_CHANGED" | "STORE_DELETED" | "EXPORT_COMPLETE" | "SCHEDULED_BACKUP_SUCCESS" | "SCHEDULED_BACKUP_FAILED" | "PASSWORD_RESET" | "INQUIRY_NEW_ADMIN" | "INQUIRY_REPLY_CUSTOMER" | "INQUIRY_CONFIRMATION_CUSTOMER" | "MARKETING_CAMPAIGN"
status?string

Filter by status

Value in"QUEUED" | "SENDING" | "SENT" | "DELIVERED" | "BOUNCED" | "FAILED"
toEmail?string

Filter by recipient email address (substring match)

curl -X GET "https://api.brainerce.com/api/stores/string/email/logs?page=1&limit=20&eventType=ORDER_CONFIRMATION&status=QUEUED&toEmail=string"
{
  "data": [
    {
      "id": "string",
      "accountId": "string",
      "storeId": "string",
      "resendEmailId": "string",
      "eventType": "ORDER_CONFIRMATION",
      "templateId": "string",
      "toEmail": "[email protected]",
      "fromEmail": "[email protected]",
      "subject": "string",
      "status": "DELIVERED",
      "errorMessage": "string",
      "metadata": {},
      "provider": "RESEND",
      "providerMessageId": "string",
      "providerRequestId": "string",
      "attemptKey": "string",
      "queueJobId": "string",
      "providerRegion": "string",
      "acceptedAt": "2019-08-24T14:15:22Z",
      "complainedAt": "2019-08-24T14:15:22Z",
      "rejectedAt": "2019-08-24T14:15:22Z",
      "lastEventAt": "2019-08-24T14:15:22Z",
      "sentAt": "2019-08-24T14:15:22Z",
      "deliveredAt": "2019-08-24T14:15:22Z",
      "bouncedAt": "2019-08-24T14:15:22Z",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 137,
    "totalPages": 7
  }
}

Get a specific email log

GET
/stores/{storeId}/email/logs/{logId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

storeIdstring
logIdstring
curl -X GET "https://api.brainerce.com/api/stores/string/email/logs/string"
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "resendEmailId": "string",
  "eventType": "ORDER_CONFIRMATION",
  "templateId": "string",
  "toEmail": "[email protected]",
  "fromEmail": "[email protected]",
  "subject": "string",
  "status": "DELIVERED",
  "errorMessage": "string",
  "metadata": {},
  "provider": "RESEND",
  "providerMessageId": "string",
  "providerRequestId": "string",
  "attemptKey": "string",
  "queueJobId": "string",
  "providerRegion": "string",
  "acceptedAt": "2019-08-24T14:15:22Z",
  "complainedAt": "2019-08-24T14:15:22Z",
  "rejectedAt": "2019-08-24T14:15:22Z",
  "lastEventAt": "2019-08-24T14:15:22Z",
  "sentAt": "2019-08-24T14:15:22Z",
  "deliveredAt": "2019-08-24T14:15:22Z",
  "bouncedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/stores/{storeId}/email/logs/{logId}"
}

Get email settings for store

GET
/v1/email/settings
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

curl -X GET "https://api.brainerce.com/api/v1/email/settings"
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "emailsEnabled": true,
  "defaultFromName": "string",
  "defaultReplyTo": "string",
  "eventSettings": {},
  "hourlyRateLimit": 0,
  "customDomainId": "string",
  "dailyCampaignSendLimit": 0,
  "clickTrackingEnabled": true,
  "footerAddress": "string",
  "footerSocialLinks": {},
  "footerCustomText": "string",
  "fontFamily": "string",
  "deliveryProviderOverride": "string",
  "sesTenantName": "string",
  "marketingSendingPaused": true,
  "marketingPauseReason": "string",
  "marketingPausedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "customDomain": {
    "id": "string",
    "storeId": "string",
    "domain": "mail.mystore.com",
    "status": "string",
    "dnsRecords": {},
    "provider": "string",
    "providerIdentityId": "string",
    "providerRegion": "string",
    "mailFromDomain": "string",
    "dkimStatus": "string",
    "mailFromStatus": "string",
    "resendDomainId": "string",
    "verifiedAt": "2019-08-24T14:15:22Z",
    "lastCheckedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  },
  "hasOwnerEmail": true
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/settings"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/settings"
}

Update email settings for store

Supports Idempotency-Key header for safe retries.

PUT
/v1/email/settings
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
emailsEnabled?boolean

Whether emails are enabled for this store

Defaulttrue
clickTrackingEnabled?boolean

Track link clicks in marketing campaigns. Off by default, because enabling it starts recording which recipients clicked, so the store owner must opt in rather than inherit it. Opens are never tracked.

defaultFromName?string

Default from name for emails

defaultReplyTo?string

Reply-to email address

eventSettings?object

Per-event settings

Empty Object

hourlyRateLimit?number

Hourly rate limit for emails

Default100
Range1 <= value <= 1000
customDomainId?string

Custom domain ID to use for sending

footerAddress?string

Physical postal address shown in the footer of marketing mail. Required before any marketing-class message can be sent. CAN-SPAM mandates a visible business address, and the send is refused without one.

curl -X PUT "https://api.brainerce.com/api/v1/email/settings" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "emailsEnabled": true,
  "defaultFromName": "string",
  "defaultReplyTo": "string",
  "eventSettings": {},
  "hourlyRateLimit": 0,
  "customDomainId": "string",
  "dailyCampaignSendLimit": 0,
  "clickTrackingEnabled": true,
  "footerAddress": "string",
  "footerSocialLinks": {},
  "footerCustomText": "string",
  "fontFamily": "string",
  "deliveryProviderOverride": "string",
  "sesTenantName": "string",
  "marketingSendingPaused": true,
  "marketingPauseReason": "string",
  "marketingPausedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "customDomain": {
    "id": "string",
    "storeId": "string",
    "domain": "mail.mystore.com",
    "status": "string",
    "dnsRecords": {},
    "provider": "string",
    "providerIdentityId": "string",
    "providerRegion": "string",
    "mailFromDomain": "string",
    "dkimStatus": "string",
    "mailFromStatus": "string",
    "resendDomainId": "string",
    "verifiedAt": "2019-08-24T14:15:22Z",
    "lastCheckedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  },
  "hasOwnerEmail": true
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/settings"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/settings"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/settings"
}

Get all email templates for store

GET
/v1/email/templates
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

curl -X GET "https://api.brainerce.com/api/v1/email/templates"
{
  "templates": [
    {
      "id": "string",
      "accountId": "string",
      "storeId": "string",
      "name": "Order Confirmation",
      "eventType": "string",
      "language": "string",
      "subject": "Order {{orderNumber}} Confirmed",
      "htmlContent": "string",
      "textContent": "string",
      "variables": {},
      "isDefault": true,
      "isActive": true,
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "language": "string",
  "supportedLanguages": [
    "string"
  ]
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates"
}

Get email template by ID

GET
/v1/email/templates/{templateId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

templateIdstring

Template ID

curl -X GET "https://api.brainerce.com/api/v1/email/templates/string"
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "name": "Order Confirmation",
  "eventType": "string",
  "language": "string",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": true,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

Create a new email template

Supports Idempotency-Key header for safe retries.

POST
/v1/email/templates
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
namestring

Template display name

eventTypestring

Event type this template is for

Value in"ORDER_CONFIRMATION" | "ORDER_SHIPPED" | "ORDER_CANCELLED" | "ORDER_COMPLETED" | "ORDER_REFUNDED" | "ORDER_NOTE" | "NEW_ORDER_ADMIN" | "NEW_CUSTOMER" | "LOW_STOCK_ALERT" | "CART_ABANDONED" | "EMAIL_VERIFICATION" | "TEAM_INVITATION" | "ORDERS_LINKED" | "STORE_INVITATION" | "STORE_ROLE_CHANGED" | "STORE_DELETED" | "EXPORT_COMPLETE" | "SCHEDULED_BACKUP_SUCCESS" | "SCHEDULED_BACKUP_FAILED" | "PASSWORD_RESET" | "INQUIRY_NEW_ADMIN" | "INQUIRY_REPLY_CUSTOMER" | "INQUIRY_CONFIRMATION_CUSTOMER" | "MARKETING_CAMPAIGN"
languagestring

Locale this template is for (must be in store.supportedLanguages)

subjectstring

Email subject line (supports Handlebars)

htmlContentstring

HTML content of the email (supports Handlebars)

textContent?string

Plain text content of the email

variables?object

Variable schema for this template

Empty Object

isActive?boolean

Whether this template is active

Defaulttrue
curl -X POST "https://api.brainerce.com/api/v1/email/templates" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "name": "Order Confirmation",    "eventType": "ORDER_CONFIRMATION",    "language": "en",    "subject": "Order #{{orderNumber}} Confirmed",    "htmlContent": "<h1>Thank you for your order!</h1>"  }'
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "name": "Order Confirmation",
  "eventType": "string",
  "language": "string",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": true,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates"
}

Update an email template

Supports Idempotency-Key header for safe retries.

PUT
/v1/email/templates/{templateId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

templateIdstring

Template ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
name?string

Template display name

subject?string

Email subject line (supports Handlebars)

htmlContent?string

HTML content of the email (supports Handlebars)

textContent?string

Plain text content of the email

variables?object

Variable schema for this template

Empty Object

isActive?boolean

Whether this template is active

curl -X PUT "https://api.brainerce.com/api/v1/email/templates/string" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "accountId": "string",
  "storeId": "string",
  "name": "Order Confirmation",
  "eventType": "string",
  "language": "string",
  "subject": "Order {{orderNumber}} Confirmed",
  "htmlContent": "string",
  "textContent": "string",
  "variables": {},
  "isDefault": true,
  "isActive": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

Delete an email template

Supports Idempotency-Key header for safe retries.

DELETE
/v1/email/templates/{templateId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

templateIdstring

Template ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
curl -X DELETE "https://api.brainerce.com/api/v1/email/templates/string" \  -H "Idempotency-Key: string"
Empty

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}"
}

Preview an email template with sample data

Supports Idempotency-Key header for safe retries.

POST
/v1/email/templates/{templateId}/preview
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

templateIdstring

Template ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
variables?object

Sample variables for rendering the template

Empty Object

curl -X POST "https://api.brainerce.com/api/v1/email/templates/string/preview" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "subject": "string",
  "html": "string",
  "text": "string"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}/preview"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}/preview"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}/preview"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/email/templates/{templateId}/preview"
}

On this page

No Headings