Create a draft notification template for a tenant, iterate with Elemental content, publish it, and read back the published version using the Courier Create template endpoints.
The Courier Create API lets you create and update stored notification templates over HTTP. It powers the same Elemental model you edit in Design Studio and embed with the Courier Create React package. Use it from a script or CI when you want versioned, repeatable changes (for example, promoting a template across environments).This tutorial walks through a realistic order confirmation email: save a draft, refine the content, publish, then fetch the published version. You should be comfortable with Elemental basics. For request fields and status codes, see the Courier Create API reference.
These endpoints manage templates scoped to a specific tenant (/tenants/{tenant_id}/templates/...). They are part of the Courier Create feature set and are separate from workspace-level notification templates you configure in the Courier dashboard.
Save an initial draft with published: false. The body uses TenantTemplateInput with required content (Elemental). This example uses email-oriented elements at the root: meta (subject), text, and an action link.
Copy
Ask AI
curl -X PUT "https://api.courier.com/tenants/$TENANT_ID/templates/$TEMPLATE_ID" \ -H "Authorization: Bearer $COURIER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "published": false, "template": { "content": { "version": "2022-01-01", "elements": [ { "type": "meta", "title": "Order {{order_id}} confirmed" }, { "type": "text", "content": "Hi {{name}}, we received your order and are preparing it." }, { "type": "action", "content": "View order", "href": "https://example.com/orders/{{order_id}}" } ] } } }'
Expect 201 if the template ID is new for that tenant, or 200 if you run the tutorial again.
Refine copy without publishing yet: send another PUT with the same template_id, still published: false. Add a divider and a support line so the email matches what you might ship after review.
In a real codebase, store the template.content object in one JSON file or shared module and merge edits there so you are not copying large payloads between steps.
Copy
Ask AI
curl -X PUT "https://api.courier.com/tenants/$TENANT_ID/templates/$TEMPLATE_ID" \ -H "Authorization: Bearer $COURIER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "published": false, "template": { "content": { "version": "2022-01-01", "elements": [ { "type": "meta", "title": "Order {{order_id}} confirmed" }, { "type": "text", "content": "Hi {{name}}, we received your order and are preparing it." }, { "type": "action", "content": "View order", "href": "https://example.com/orders/{{order_id}}" }, { "type": "divider" }, { "type": "text", "content": "Need help? Reply to this email or visit our help center.", "text_style": "subtext" } ] } } }'
You now have a published template with version history: drafts from PUT with published: false, a live version from POST .../publish, a way to audit what is live via GET .../versions/published, and a send call that delivers messages using the template.