Appearance
Templates
A template is a reusable email — a subject line and a designed body you build once in the dashboard and then send from the API with per-recipient variables. Templates keep your markup out of your application code: your send call carries only the data, and SendGrail renders the message.
Building a template
Open Templates in the dashboard and create one. The editor is a drag-and-drop canvas for the body, with a header for the From, Reply-To, Subject and Preview text.
Your work is saved automatically as you type — there's no Save button. A new template becomes a draft the moment it has real content, and every later edit is saved in the background (you'll see a Saved indicator in the header).
Nothing is required to save a draft. Missing pieces surface later as non-blocking warnings when you publish, not as errors that stop you working.
Viewing the rendered HTML
The </> button in the top-left of the editor opens the send-ready HTML, with a live preview and a copy button — useful for inspecting exactly what a recipient's mail client will receive.
Variables
Anywhere in the subject or body, write a variable in triple braces:
Hi {{{first_name}}}, your order {{{order_id}}} has shipped.Every unique {{{name}}} you use appears in the editor's Variables panel. There you can give each one a fallback — the value rendered when a send call omits it. Without a fallback, a missing variable renders as empty.
At send time you supply the values as a variables object (see Sending with a template below).
Draft vs. published
A template is either a draft or published:
- Draft — a work in progress. It cannot be sent from the API; a send call that references it returns
422. - Published — live and callable from the send API.
Publishing is deliberate. The Publish New Version control shows any warnings first — a missing From address, preview text or subject, empty content, or a variable with no fallback — then a slide-to-publish confirm. None of the warnings block you; they're there so you don't ship an empty subject by accident. Use Move to draft from the editor menu to pull a template back offline.
Testing a template
From the editor menu, Test email sends a one-off copy through the real sending pipeline so you can see it in an inbox. Enter one or more recipients (separate them with commas or line breaks, up to 25), fill in sample variable values, and send.
A test needs a From address set on the template — you'll be prompted for one before the test panel opens. If the From domain isn't verified, the test falls back to a test@ address on one of your verified domains.
Sending with a template
Reference a published template from POST /v1/emails with template_id (the template's UUID) or template_slug (its human-friendly, team-scoped handle), plus a variables object:
bash
curl https://api.sendgrail.com/v1/emails \
-H "Authorization: Bearer $SENDGRAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@example.com>",
"to": "recipient@example.org",
"template_slug": "order-shipped",
"variables": {
"first_name": "Ada",
"order_id": "A-1024"
}
}'js
await fetch('https://api.sendgrail.com/v1/emails', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SENDGRAIL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'Acme <hello@example.com>',
to: 'recipient@example.org',
template_slug: 'order-shipped',
variables: { first_name: 'Ada', order_id: 'A-1024' },
}),
});python
import os, requests
requests.post(
"https://api.sendgrail.com/v1/emails",
headers={"Authorization": f"Bearer {os.environ['SENDGRAIL_API_KEY']}"},
json={
"from": "Acme <hello@example.com>",
"to": "recipient@example.org",
"template_slug": "order-shipped",
"variables": {"first_name": "Ada", "order_id": "A-1024"},
},
)php
$http->post('https://api.sendgrail.com/v1/emails', [
'headers' => ['Authorization' => 'Bearer '.getenv('SENDGRAIL_API_KEY')],
'json' => [
'from' => 'Acme <hello@example.com>',
'to' => 'recipient@example.org',
'template_slug' => 'order-shipped',
'variables' => ['first_name' => 'Ada', 'order_id' => 'A-1024'],
],
]);Notes:
- Give either
template_idortemplate_slug— you don't need both.template_idnever changes;template_slugis friendlier but can be renamed. - The template supplies the subject, HTML and text — you don't send a body. You may still pass your own
subjectto override the template's; it's rendered with the samevariables. - Passing
variables,template_idortemplate_slugthat don't resolve to a published template of yours returns a422— see Errors.
Next steps
- Send an email — the full send API, including
template_idandtemplate_slug. - Domains & verification — a template's From must be on a verified domain.