POST
/templatesPOST /templates
Create a new template.
Request
curl -X POST 'https://api.sendheron.com/api/v1/templates' \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json'Required scopes
The key must carry these:
- templates:write
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Template name. |
| subject | string | Yes | Subject line. Supports Handlebars variables. |
| bodyHtml | string | No | HTML body, for a raw-HTML template. Supports Handlebars variables. Send exactly one of bodyHtml or document. |
| document | object | No | Block document, for a builder template. The server validates it and compiles bodyHtml from it. A block carries its props at the TOP LEVEL, not under a props key: {"id": "b1", "type": "heading", "text": "Hi", "level": 1}. Send exactly one of bodyHtml or document. |
| bodyMjml | string | No | MJML source. |
| emailType | MARKETING | TRANSACTIONAL | Yes | Required, with no default. The type decides how every future send of this template behaves, so the API asks for intent rather than guessing it. |
| tagIds | uuid[] | No | Tags to attach. |
Responses
Returns 201 on success.
- 400
- The payload failed validation, or the request is not valid for the current state. The body's `description` names the field and says what was wrong with it in words, e.g. "domain: domain must be a bare hostname such as acme.com, with no scheme, path, or port". The `error` code is stable and safe to branch on; `description` is for the human reading the log.
- 401
- Missing or invalid API key.
- 403
- Valid key, but it does not carry the required scope. The `error` code is `apiKeys.insufficientScopes` and the `description` names both halves of the problem: "Missing required scope(s): X. This key holds: Y." Neither is a secret, since the required scopes are on this page and the held ones are your own credential, and a bare "Forbidden" costs a debugging pass to work out which of the two it was.
- 404
- No such record in this workspace. An id belonging to a different workspace returns this too, never a 403, because the API will not confirm that a record exists outside the workspace your key was issued in. Read it as "not yours or not there" rather than as "definitely gone".
- 409
- A duplicate, or an idempotency key reused with a different payload.
- 429
- Either rate-limit ceiling was exceeded.
- 400
- Neither or both of `bodyHtml` and `document` were supplied.
- 400
- `emailType` was omitted. It used to default to `MARKETING` and no longer does.
Rate limits
100/min per key, counted against the organization's WRITE ceiling (400/min). Both windows are one minute. There is no hourly or daily quota.