Skip to main content
POST
/
api
/
email
/
preview
Preview email content with resolved dynamic fields
curl --request POST \
  --url https://dev.exante.app/api/email/preview \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "body": "<string>",
  "context_type": "invoice",
  "subject": "<string>",
  "context_uid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "preview_mode": "live"
}
'
{
  "body": "<string>",
  "preview_mode": "live",
  "errors": [
    {
      "token": "{shipping_address}",
      "message": "Token '{shipping_address}' is not available for context_type 'invoice'."
    }
  ],
  "subject": "<string>"
}
Preview how an email template will look after dynamic fields are resolved. This endpoint lets you test templates before sending, either with real data from an existing entity or with sample placeholder values.

Preview Modes

Live Mode (preview_mode: "live")

Resolves dynamic fields using actual data from a specific entity. Use this when you want to see exactly what an email will look like for a particular invoice, customer, etc. Requirements:
  • context_uid - The UUID of the entity to pull data from
  • User must have access to the entity’s organization
Example:
{
  "preview_mode": "live",
  "context_type": "invoice",
  "context_uid": "a1b2c3d4-...",
  "subject": "Reminder: Invoice {invoice_number}",
  "body": "Hi {client_name},\n\nYour invoice for {amount_due} is due on {due_date}."
}
Response:
{
  "subject": "Reminder: Invoice INV-2024-001",
  "body": "Hi Acme Corp,\n\nYour invoice for $1,500.00 is due on March 15, 2024.",
  "preview_mode": "live",
  "errors": []
}

Sample Mode (preview_mode: "sample")

Resolves dynamic fields using placeholder sample data. Use this when designing templates before you have real data, or when you want to show a generic preview in the UI. Example:
{
  "preview_mode": "sample",
  "context_type": "invoice",
  "subject": "Reminder: Invoice {invoice_number}",
  "body": "Hi {client_name},\n\nYour invoice for {amount_due} is due on {due_date}."
}
Response:
{
  "subject": "Reminder: Invoice [Invoice Number]",
  "body": "Hi [Client Name],\n\nYour invoice for [Amount Due] is due on [Due Date].",
  "preview_mode": "sample",
  "errors": []
}
In sample mode, tokens are replaced with their human-readable labels wrapped in brackets (e.g., {client_name} becomes [Client Name]).

Request Parameters

ParameterRequiredDescription
context_typeYesEntity type (e.g., "invoice")
bodyYesEmail body template with dynamic tokens
subjectNoEmail subject template (optional)
preview_modeNo"live" or "sample" (defaults to "live")
context_uidConditionalRequired for live mode

Response

FieldDescription
bodyResolved email body
subjectResolved subject (if provided in request)
preview_modeThe mode used for resolution
errorsArray of tokens that couldn’t be resolved

Error Handling

When a token can’t be resolved (e.g., missing data), it appears in the errors array:
{
  "body": "Your payment link is: {payment_link}",
  "errors": [
    {
      "token": "{payment_link}",
      "message": "No payment link configured for this invoice"
    }
  ]
}
Unresolved tokens remain as-is in the output, making it clear what’s missing.

Use Cases

Template Editor Preview

Show live preview as the user types:
async function updatePreview(template, invoiceUid) {
  const response = await fetch('/api/email/preview', {
    method: 'POST',
    body: JSON.stringify({
      preview_mode: 'live',
      context_type: 'invoice',
      context_uid: invoiceUid,
      body: template
    })
  });
  const { body, errors } = await response.json();
  renderPreview(body);
  showWarnings(errors);
}
Show sample previews when no context is selected:
async function showTemplateSample(template) {
  const response = await fetch('/api/email/preview', {
    method: 'POST',
    body: JSON.stringify({
      preview_mode: 'sample',
      context_type: 'invoice',
      body: template
    })
  });
  const { body } = await response.json();
  renderSample(body);
}

Comparison: Preview vs Prepare

AspectPreviewPrepare
PurposeTest templates visuallyGenerate final email content
Modeslive / sampletemplate / inference
AI generationNoYes (inference mode)
HTML outputNoYes (body_html)
Use caseTemplate editing UIPre-send content generation

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json
body
string
required
context_type
string
required
Example:

"invoice"

subject
string
context_uid
string<uuid>

Context object UID. Required when preview_mode is 'live', optional when preview_mode is 'sample'.

preview_mode
enum<string>
default:live

Preview mode. 'live' resolves against a real context object, 'sample' uses provider sample data.

Available options:
live,
sample

Response

Resolved email preview

body
string
required
preview_mode
enum<string>
required
Available options:
live,
sample
errors
object[]
required
subject
string