Skip to content

Templates

One row per template, addressed by the key its author gave the file. A template has versions and nothing else, no switch, because a send resolves the latest version that finished compiling at the moment it sends, so fixing copy reaches runs already in flight. preview renders that version with whatever props you pass, in the sandbox, and answers the subject, HTML and text as they would go out; test-send renders the same way and sends the result to your own address through the organization’s default sender, which walks no consent gate, counts against nothing, and is logged as a test rather than as mail to a recipient. Deleting a key deletes every version of it and is refused while a journey still sends it, naming the journeys. Templates arrive with a push, so there is no create and no update here.

List the organization’s email templates

Auth: Session token.

Query parameters

{
"cursor": "string",
"limit": 50,
"q": "string"
}
Field Type Required Constraints
cursor string no
limit integer no default 50; 1 ≤ x ≤ 100
q string no length 0–200

Response 200

{
"data": [
{
"key": "string",
"appId": "string",
"tags": {},
"sendClass": "marketing",
"verifyLink": true,
"unsubscribeLink": false,
"propsSchema": {
"key": {}
},
"latestVersion": {
"id": "string",
"status": "compiling",
"moduleDigest": "string",
"pushId": "string",
"appId": "string",
"error": "string",
"pushedAt": "2026-01-15T09:30:00.000Z"
},
"journeys": [
"string"
]
}
],
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object[] yes
data[] object yes
data[].key string yes length 0–64
data[].appId string yes
data[].tags any yes
data[].sendClass “marketing” | “transactional” yes
data[].verifyLink boolean yes
data[].unsubscribeLink boolean yes default false
data[].propsSchema record<string, any> yes
data[].latestVersion object yes
data[].latestVersion.id string yes
data[].latestVersion.status “compiling” | “ready” | “failed” yes
data[].latestVersion.moduleDigest string | null yes
data[].latestVersion.pushId string yes
data[].latestVersion.appId string yes
data[].latestVersion.error string | null yes
data[].latestVersion.pushedAt string (date-time) yes
data[].journeys string[] yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Inspect one email template

Auth: Session token.

Response 200

{
"data": {
"key": "string",
"appId": "string",
"tags": {},
"sendClass": "marketing",
"verifyLink": true,
"unsubscribeLink": false,
"propsSchema": {
"key": {}
},
"latestVersion": {
"id": "string",
"status": "compiling",
"moduleDigest": "string",
"pushId": "string",
"appId": "string",
"error": "string",
"pushedAt": "2026-01-15T09:30:00.000Z"
},
"journeys": [
"string"
]
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.key string yes length 0–64
data.appId string yes
data.tags any yes
data.sendClass “marketing” | “transactional” yes
data.verifyLink boolean yes
data.unsubscribeLink boolean yes default false
data.propsSchema record<string, any> yes
data.latestVersion object yes
data.latestVersion.id string yes
data.latestVersion.status “compiling” | “ready” | “failed” yes
data.latestVersion.moduleDigest string | null yes
data.latestVersion.pushId string yes
data.latestVersion.appId string yes
data.latestVersion.error string | null yes
data.latestVersion.pushedAt string (date-time) yes
data.journeys string[] yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Render a template with the props you pass

Auth: Session token.

Request body

{
"data": {
"props": {}
}
}
Field Type Required Constraints
data object yes
data.props record<string, any> no default {}

Response 200

{
"data": {
"subject": "string",
"html": "string",
"text": "string",
"versionId": "string"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.subject string yes
data.html string yes
data.text string yes
data.versionId string yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Send a rendered template to your own address

Auth: Session token.

Request body

{
"data": {
"props": {}
}
}
Field Type Required Constraints
data object yes
data.props record<string, any> no default {}

Response 201

{
"data": {
"id": "string",
"orgId": "string",
"profileId": "string",
"journey": "string",
"executionId": "string",
"kind": "journey",
"step": "string",
"channel": "email",
"status": "sent",
"dryRun": true,
"recipient": "string",
"providerId": "string",
"error": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"sentAt": "2026-01-15T09:30:00.000Z",
"settledAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.id string yes
data.orgId string yes
data.profileId string | null yes
data.journey string | null yes
data.executionId string | null yes
data.kind “journey” | “test” | “api” yes
data.step string yes
data.channel “email” | “webhook” yes
data.status “sent” | “delivered” | “bounced” | “complained” | “failed” | “skipped_disabled” | “skipped_paused” | “skipped_suppressed” | “skipped_quota” | “skipped_unknown_purpose” | “skipped_frequency_cap” | “skipped_consent” | “skipped_domain” | “skipped_ssrf” | “would_send” | “would_skip_disabled” | “would_skip_paused” | “would_skip_suppressed” | “would_skip_quota” | “would_skip_unknown_purpose” | “would_skip_frequency_cap” | “would_skip_consent” | “would_skip_domain” | “would_skip_ssrf” yes
data.dryRun boolean yes
data.recipient string | null yes
data.providerId string | null yes
data.error string | null yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
data.sentAt string (date-time) | null yes
data.settledAt string (date-time) | null yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Delete an email template

Auth: Session token.

Response 200

{
"data": {
"deleted": true
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.deleted true yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.