Skip to content

Email templates ​

A template has a draft you edit and a list of published versions. Sending always uses the current published version, by slug. The Node.js client @funnelsgrove/emails and the fgrove email CLI call these endpoints; see Send lifecycle emails for the workflow.

Every endpoint below takes projectId as a query parameter with an API key.

json
{
  "id": "<template-id>",
  "slug": "order-confirmation",
  "name": "Order confirmation",
  "currentPublishedVersionId": null,
  "draft": {
    "subject": "Order {{ORDER_ID}}",
    "previewText": "Your order is confirmed.",
    "html": "<p>Order {{ORDER_ID}}</p>",
    "text": "Order {{ORDER_ID}}",
    "variables": { "ORDER_ID": "string" },
    "variableDescriptions": { "ORDER_ID": "Order reference shown on the receipt" }
  },
  "createdAt": "…",
  "updatedAt": "…"
}

Draft fields ​

FieldRequiredPurpose
subjectYesSubject line; may use placeholders.
previewTextYesInbox preview text, or null.
htmlYesHTML body.
textYesPlain-text body.
variablesYesDeclared variables and their type: string, number or boolean.
variableDescriptionsNoDescription per variable, shown to authors and by fgrove email library list.

List templates ​

Scope: email_templates:read

Request ​

http
GET /email/templates

Example ​

sh
curl "https://sdk-api.funnelsgrove.com/integration/v1/email/templates" \
  -H "Authorization: Bearer <project-sdk-secret-key>"

Response ​

A JSON array of templates.

Get template ​

Scope: email_templates:read

Request ​

http
GET /email/templates/:templateId

Example ​

sh
curl "https://sdk-api.funnelsgrove.com/integration/v1/email/templates/<template-id>" \
  -H "Authorization: Bearer <project-sdk-secret-key>"

Response ​

json
{
  "template": { "id": "<template-id>", "slug": "order-confirmation", "…": "…" },
  "versions": [{
    "id": "<version-id>",
    "templateId": "<template-id>",
    "version": 1,
    "subject": "Order {{ORDER_ID}}",
    "previewText": "Your order is confirmed.",
    "html": "…",
    "text": "…",
    "variables": { "ORDER_ID": "string" },
    "variableDescriptions": {},
    "publishedAt": "…"
  }]
}

Errors ​

StatusMeaning
400templateId is not a UUID.
404The template does not exist in this project.

Create template ​

Scope: email_templates:write

Request ​

http
POST /email/templates
Content-Type: application/json

Parameters ​

FieldRequiredPurpose
slugNoLowercase letters, digits and hyphens, up to 80 characters.
nameNoDisplay name, up to 120 characters.
draftNoThe draft fields.
starterNologin-code creates the starter template; if its slug exists, the existing template is returned.
publishNotrue validates and publishes the draft in the same call.

Example ​

sh
curl -X POST "https://sdk-api.funnelsgrove.com/integration/v1/email/templates" \
  -H "Authorization: Bearer <project-sdk-secret-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "slug": "order-confirmation",
    "name": "Order confirmation",
    "draft": {
      "subject": "Order {{ORDER_ID}}",
      "previewText": "Your order is confirmed.",
      "html": "<p>Order {{ORDER_ID}}</p><p>Total: {{PRICE}}</p>",
      "text": "Order {{ORDER_ID}}\nTotal: {{PRICE}}",
      "variables": { "ORDER_ID": "string", "PRICE": "number" }
    }
  }'

Response ​

201 with the template. With publish: true, the response is { "template": …, "version": … } as for Publish template.

Errors ​

StatusMeaning
400The body is invalid, or the draft fails validation when publishing.
409A template with this slug already exists.

Update template ​

Replaces the given draft fields. At least one draft field is required.

Scope: email_templates:write

Request ​

http
PATCH /email/templates/:templateId
Content-Type: application/json

Parameters ​

FieldRequiredPurpose
nameNoNew display name.
draftYesAny subset of the draft fields.

Example ​

sh
curl -X PATCH "https://sdk-api.funnelsgrove.com/integration/v1/email/templates/<template-id>" \
  -H "Authorization: Bearer <project-sdk-secret-key>" \
  -H "Content-Type: application/json" \
  --data '{ "draft": { "subject": "Order {{ORDER_ID}} confirmed" } }'

Response ​

The updated template.

Errors ​

StatusMeaning
400The body is invalid or draft is empty.
404The template does not exist in this project.

Validate template ​

Checks that the draft is valid without publishing it.

Scope: email_templates:read

Request ​

http
POST /email/templates/:templateId/validate

Example ​

sh
curl -X POST "https://sdk-api.funnelsgrove.com/integration/v1/email/templates/<template-id>/validate" \
  -H "Authorization: Bearer <project-sdk-secret-key>"

Response ​

json
{ "valid": true }

Errors ​

StatusMeaning
400The draft is invalid; the message names the problem.
404The template does not exist in this project.

Preview template ​

Renders the draft with the given values.

Scope: email_templates:read

Request ​

http
POST /email/templates/:templateId/preview
Content-Type: application/json

Parameters ​

FieldRequiredPurpose
valuesYesA value per declared variable: string, number or boolean.

Example ​

sh
curl -X POST "https://sdk-api.funnelsgrove.com/integration/v1/email/templates/<template-id>/preview" \
  -H "Authorization: Bearer <project-sdk-secret-key>" \
  -H "Content-Type: application/json" \
  --data '{ "values": { "ORDER_ID": "MV0002", "PRICE": 39.99 } }'

Response ​

The rendered subject, previewText, html and text.

Errors ​

StatusMeaning
400The values do not match the declared variables, or the draft does not render.
404The template does not exist in this project.

Test-send template ​

Renders the draft with the given values and sends it to one recipient through the test delivery path.

Scope: email_templates:write

Request ​

http
POST /email/templates/:templateId/test-send
Content-Type: application/json

Parameters ​

FieldRequiredPurpose
recipientEmailYesWhere to send the test.
valuesYesA value per declared variable.

Example ​

sh
curl -X POST "https://sdk-api.funnelsgrove.com/integration/v1/email/templates/<template-id>/test-send" \
  -H "Authorization: Bearer <project-sdk-secret-key>" \
  -H "Content-Type: application/json" \
  --data '{ "recipientEmail": "you@example.com", "values": { "ORDER_ID": "MV0002", "PRICE": 39.99 } }'

Response ​

202 with the queued delivery receipt, { "id": "<delivery-id>", "status": "queued" }.

Errors ​

StatusMeaning
400The recipient or values are invalid, or the draft does not render.
404The template does not exist in this project.

Publish template ​

Validates the draft and publishes it as a new version. Sending by slug uses this version from now on.

Scope: email_templates:write

Request ​

http
POST /email/templates/:templateId/publish

Example ​

sh
curl -X POST "https://sdk-api.funnelsgrove.com/integration/v1/email/templates/<template-id>/publish" \
  -H "Authorization: Bearer <project-sdk-secret-key>"

Response ​

json
{
  "template": { "id": "<template-id>", "currentPublishedVersionId": "<version-id>", "…": "…" },
  "version": { "id": "<version-id>", "version": 2, "publishedAt": "…", "…": "…" }
}

Errors ​

StatusMeaning
400The draft fails validation.
404The template does not exist in this project.
409The draft changed while publishing; read it again and retry.

Build. Launch. Grow.