Create a template
POST /templates
A new draft, holding version 1 of its content.
Body
namestringRequiredA name for the dashboard.
aliasstringA short name to address the template by instead of its ID: lower-case letters, digits,
-and_, starting with a letter or digit, at most 63 characters, and never a UUID. Unique among the team's templates.fromstringThe sender, as
Name <address@domain>or a bare address. A send that names its ownfromoverrides it.subjectstringThe subject line. May carry
{{key}}placeholders.htmlstringThe HTML body. May carry
{{key}}placeholders. On create, send this orstarter— exactly one.textstringThe plain-text body. May carry
{{key}}placeholders.variablesobject[]The variables the bodies use, at most 200:
{ key, type, fallback_value }, withtypeone ofstring,number,boolean,objectorlist. Every{{key}}must be declared here, and every declared key must be used.starterstringThe slug of a starter template to copy instead of writing
html. Its subject, layout and variables become version 1: the copy opens in the dashboard's visual editor, and its HTML and plain text are compiled from the layout. Send this orhtml, never both.
2 more fields (reply_to, brand_overrides)
reply_tostring[]Reply-to addresses.
brand_overridesobject | nullThis template's own values for your brand fields, for a one-off that should not wear the project brand:
logo_url,primary_color,accent_color,font,button_style,company_name,address,footer_text. A field you leave out follows the project brand; a field set tonulluses our plain default even when your brand sets one.nullfor the whole object means this template pins nothing.
Request
curl -X POST "https://api.rasket.com/templates" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome",
"alias": "welcome",
"subject": "Welcome, {{name}}",
"html": "<p>Hello {{name}}, thanks for joining.</p>",
"variables": [
{
"key": "name",
"type": "string",
"fallback_value": "there"
}
]
}'const response = await fetch("https://api.rasket.com/templates", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Welcome",
alias: "welcome",
subject: "Welcome, {{name}}",
html: "<p>Hello {{name}}, thanks for joining.</p>",
variables: [
{
key: "name",
type: "string",
fallback_value: "there"
}
]
}),
});
const { id } = await response.json();import os
import requests
response = requests.post(
"https://api.rasket.com/templates",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
json={
"name": "Welcome",
"alias": "welcome",
"subject": "Welcome, {{name}}",
"html": "<p>Hello {{name}}, thanks for joining.</p>",
"variables": [
{
"key": "name",
"type": "string",
"fallback_value": "there"
}
]
},
)
id = response.json()["id"]Response 201
{
"id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
"object": "template"
}- A new template is a draft. Nothing can be sent from it until you publish it.
- Send exactly one of
htmlandstarter. Neither is422 missing_required_field; both is422 invalid_parameter. The schema cannot express "exactly one", so a client will not catch it for you. starteris one of the slugsGET /starterslists. Any other value is400 validation_error.- With
starter, anything else you send wins over the starter's:subject,textandvariablesoverride it, andalias,fromandreply_toare yours to set. Atextyou send is kept as the plain text instead of the one generated from the layout. The copy keeps no link to the library, so improving a starter never changes it. - This route takes no
Idempotency-Key. A retry with noaliascreates a second template; set an alias, or check the list first. - A
{{key}}the bodies use butvariablesdoes not declare — or a declared key the bodies never use — is422 validation_error, with one entry inerrors[]per key. - An alias another live template holds is
422 validation_error. Deleting a template frees its alias. brand_overridesis not a send variable and declares nothing: a brand field is your project's and a{{key}}is the recipient's, so the declaration rule never sees one.- An unknown field name inside
brand_overridesis400 validation_errorrather than ignored, and afontorbutton_styleoutside its list is too. Everything else it refuses is422 invalid_parameter.