Email Templates
Templates are reusable email bodies that you can use in campaign email steps.
Variables
Write variables with double curly braces, for example {{first_name}}. They are replaced when an email is sent. You can use any contact field, such as first_name, last_name, email or company, as well as the keys of custom_fields.
The template object
{
"id": 7,
"name": "SaaS intro",
"subject": "Quick question, {{first_name}}",
"body": "<p>Hi {{first_name}}, ...</p>",
"category": "prospection",
"variables": ["first_name"],
"is_library": false,
"created_at": "...",
"updated_at": "..."
}category is one of prospection, follow-up, welcome, newsletter, promotional, transactional or other.
Endpoints
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /templates | templates:read | List templates (paginated). Query: search, category |
| POST | /templates | templates:write | Create a template |
| GET | /templates/{id} | templates:read | Get a template |
| PUT | /templates/{id} | templates:write | Update a template (partial) |
| DELETE | /templates/{id} | templates:write | Delete a template. Returns 204. |
| POST | /templates/{id}/preview | templates:read | Render the template with a contact's data or with sample values |
| GET | /templates/{id}/variables | templates:read | The variables the template uses |
| POST | /templates/{id}/duplicate | templates:write | Copy a template |
List templates
GET /templates returns only templates in the authenticated token's workspace.
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number, starting at 1 |
per_page | integer | 15 | Results per page, from 1 to 100 |
search | string | Partial template name | |
category | string | One of the template categories listed above | |
sort | string | created_at | name, subject, category, created_at or updated_at |
direction | string | desc | asc or desc |
GET /api/v1/templates?search=welcome&category=welcome&sort=name&direction=asc&page=2The response follows the pagination contract. Equal sort values are ordered consistently by template ID.
Create a template
| Field | Type | Rules |
|---|---|---|
name | string | Required. Max 255 characters |
subject | string | Required. Max 500 characters |
body | string | Required. HTML |
category | enum | See the list above |
variables | array | Optional list of variable names |
is_library | boolean | Saves the template to your library |
201: { "data": Template }
Preview
POST /templates/{id}/preview{ "contact_id": 42 }If you leave out contact_id, you can send variables instead, for example { "variables": { "first_name": "Alice" } }. With neither, the template is rendered with sample values (John Doe, Example Inc).
200: { "data": { "subject": "Quick question, Alice", "body": "<p>Hi Alice, ...</p>" } }
Variables
GET /templates/{id}/variables returns { "data": { "variables": ["first_name", "company"] } }.
Duplicate
POST /templates/{id}/duplicate accepts an optional name. Without one, the copy is named "<name> (Copy)".
201: { "data": Template }
Marketplace
The marketplace holds ready-made templates published by Beeving. Copying a marketplace template creates an ordinary template in your workspace.
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /marketplace/templates | templates:read | Browse templates, featured and most popular first. Query: search, category, featured (1 or 0) |
| GET | /marketplace/templates/{id} | templates:read | Get a marketplace template |
| POST | /marketplace/templates/{id}/copy | templates:write | Copy it to your workspace. Accepts an optional name |
| GET | /marketplace/packs | templates:read | Browse published template packs |
| GET | /marketplace/packs/{id} | templates:read | Get a published pack |
Marketplace listings are global and return published records only.
List marketplace templates
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number, starting at 1 |
per_page | integer | 15 | Results per page, from 1 to 100 |
search | string | Partial name, subject or description | |
category | string | Template category | |
locale | string | fr or en | |
featured | boolean | Filter featured or non-featured records | |
sort | string | downloads_count | name, category, locale, is_featured, downloads_count, created_at or updated_at |
direction | string | desc | asc or desc |
Without an explicit sort, featured templates appear first, then the most downloaded. Equal values are ordered by template ID.
GET /api/v1/marketplace/templates?search=agency&locale=en&featured=1&sort=downloads_count&direction=descList marketplace packs
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number, starting at 1 |
per_page | integer | 15 | Results per page, from 1 to 100 |
search | string | Partial name, slug or description | |
locale | string | fr or en | |
featured | boolean | Filter featured or non-featured packs | |
sort | string | downloads_count | slug, locale, name, is_featured, downloads_count, created_at or updated_at |
direction | string | desc | asc or desc |
Without an explicit sort, featured packs appear first, then the most downloaded. Only published templates are embedded in each pack. Equal values are ordered by pack ID.
GET /api/v1/marketplace/packs?search=outreach&locale=en&sort=name&direction=asc&per_page=10Both list responses follow the pagination contract.
{
"id": 3,
"name": "Cold intro for agencies",
"description": "...",
"category": "prospection",
"subject": "...",
"body": "...",
"variables": ["first_name", "company"],
"is_featured": true,
"is_published": true,
"downloads_count": 1240,
"created_at": "...",
"updated_at": "..."
}A successful copy returns 201: { "data": Template, "message": "Template copied successfully" }.