Skip to main content

AI Edit Email Template (stream)

POST 

/api/store-email-templates/ai-edit/stream

Server-Sent Events: one AI assistant turn on an email template's subject, preheader and body (or a first draft when template_id is null — an empty current_html then starts from SKU's built-in default for the context + event).

Required scope: settings:write

Grant this scope to your token under Settings → Developer → Personal Access Tokens.

Authentication: Requires Bearer token and the email_templates.update permission.

Body: template_id (int|type string|null), context + event (required when template_id is null), store_id (int|null — whose brand layout and sample data), instruction (required, max 5000), current_subject (max 255), current_preheader (max 255), current_html (max 200000), history (max 10 × {instruction, summary}; the last 6 are replayed), target ({label ≤120, html ≤2000} — the preview element the user pointed at; changes are confined to it), reference_images, provider (anthropic|openai|google|deepseek|null), model.

Events: status {message} — Reading template → Writing changes → Checking variables → (Fixing problems the checks found) → Rendering preview; complete {success, proposal {subject|null, preheader|null, html, summary, unresolved[]}, validation {ok, errors[], warnings[], error_details[], warning_details[]}, usage {input_tokens, output_tokens}, rendered_preview_html, provider, model, error}; error {message, status?}. subject / preheader are null when the model kept the current value.

Errors arrive as an error event {type: "error", message, status?} on a 200 stream: the template editor switched off in AI settings (503), no API key for the provider (503), the hourly limit (AiSettings::max_requests_per_user_per_hour, default 60, per user per tenant; 429 — "You've hit the hourly AI limit; try again at 15:40."), provider failures mapped to friendly copy (quota, rate limit, bad key, timeout). Request validation failures are a normal 422 JSON response.

Nothing is saved: the editor applies the proposal to its buffer and the user saves (with version_source: ai). A proposal that fails the content checks is retried once with the errors fed back; still invalid → success: false, validation.ok: false, no rendered_preview_html.

reference_images (max 3; {mime_type, data (base64, no prefix), name} objects or data:image/...;base64, URIs; png/jpeg/webp/gif) are sent as vision input and stored as email assets so the proposal can embed them by URL; images the proposal does not embed are deleted again.

Request​

Responses​

OK

Response Headers
    Content-Type