Appearance
Email templates and campaigns
Prerequisites: configured outbound email, email.read/email.write, email.publish for template publication and email.send for sends. Examples use apiRequest. Use a controlled test audience before selecting real recipients.
Create a template version
ts
await apiRequest("/v1/admin/email/templates", {
method: "POST", body: JSON.stringify({ key: "release-update", name: "Release update", kind: "broadcast", subject: "Release news" }),
});
const draft = await apiRequest("/v1/admin/email/templates/release-update/draft", {
method: "POST", body: JSON.stringify({ subject: "Release news", html: "<p>Release news</p>", textBody: "Release news" }),
});
await apiRequest("/v1/admin/email/templates/release-update/publish", {
method: "POST", body: JSON.stringify({ version: Number(draft.version) }),
});Use previewEmailTemplate and sendEmailTemplateTest before publishing. Test sends use a positive version number and optionally a recipient/variables. Publication is 204. Template keys and versions are different identifiers.
Build an audience and campaign
createEmailAudience accepts a static audience or a dynamic audience with a filter. Populate static members through setEmailAudienceMembers; preview the resolved recipient count before sending.
ts
const audience = await apiRequest("/v1/admin/email/audiences", {
method: "POST", body: JSON.stringify({ name: "Release test audience", kind: "static" }),
});
const campaign = await apiRequest("/v1/admin/email/campaigns", {
method: "POST", body: JSON.stringify({ name: "Release update", template_key: "release-update", audience_id: audience.id, vars: {} }),
});
const launched = await apiRequest(`/v1/admin/email/campaigns/${campaign.id}/launch`, { method: "POST" });
console.log(launched.total);Fill and verify the audience before the launch call; the empty example audience is not a recipient list. scheduleEmailCampaign takes scheduled_at; use an explicit ISO timestamp for the intended instant. Campaign states include draft, scheduled, sending, paused, sent, cancelled and failed.
Observe and recover
Use getEmailCampaignProgress and listEmailCampaignDeliveries to inspect queued/sent/failed deliveries. Accepted or queued is not delivered. Pause/resume/cancel affect campaign processing; cancellation cannot unsend messages already delivered. Follow the reference's state restrictions rather than retrying invalid transitions.
Recipients can unsubscribe through the public email endpoints; those responses include HTML/plain OAuth-independent error shapes where documented. Template rollback selects an existing version for future use and does not alter already sent mail. If SMTP is unconfigured, treat it as an operational dependency and inspect delivery status rather than reporting success from a launch response alone.