E-mailtemplates
Een template is een onderwerpregel en een e-mailbody die je één keer opslaat en vaak verstuurt. Je schrijft de wisselende delen als {{ variable }}-placeholders, publiceert het template, en verstuurt het daarna op slug in plaats van dezelfde HTML in elke API-aanroep te plakken. Een template hoort bij je werkruimte.
Maak en beheer templates in Email > Templates, via /v1/email/templates, met de bird CLI, of via de MCP server. Getypte methoden zitten in de TypeScript-, Python-, PHP- en Go-SDK's onder email.templates. Volledige request- en responseschema's staan in de API-referentie. Verstuur een gepubliceerde template via het reguliere send-endpoint.
Wat zit er in een template
Elk template heeft twee namen, en ze doen verschillende dingen:
- slug is de naam waarmee je het template verstuurt, bijvoorbeeld welcome-email. Je kiest hem bij het aanmaken van het template en hij kan daarna niet meer worden gewijzigd. Een slug mag kleine letters, cijfers, koppeltekens en underscores bevatten, moet beginnen en eindigen met een letter of een cijfer, en mag maximaal 63 tekens lang zijn. Twee voorvoegsels zijn niet toegestaan: bird_, dat gereserveerd is voor onze ingebouwde templates, en emt_, het formaat dat wordt gebruikt voor template-ID's. Het dashboard noemt dit veld Alias.
- name is een vrij tekstveld als weergavelabel. Het staat standaard op de slug, en je kunt het altijd wijzigen. Niets wordt via de naam opgelost, dus het hernoemen van een template voor weergave verstoort nooit een verzending.
Daarnaast heeft een template een permanent emt_-ID, dat voor de hele levensduur vaststaat. Het heeft ook een category, ofwel marketing ofwel transactional, en een auteursbron source: html, kant-en-klare markup die je aanlevert, optioneel gepersonaliseerd met Liquid. De categorie en de bron staan beide vast bij het aanmaken van het template.
We bieden een catalogus van ingebouwde templates, en hun slugs beginnen allemaal met bird_. Een ingebouwd template hoort bij geen enkele werkruimte, kan niet worden bewerkt, en is altijd direct te verzenden. Kopieer er een naar je werkruimte om het van jou te maken, en het wordt een gewoon template dat je kunt bewerken. De kopie komt binnen als een ongepubliceerd concept dat de categorie, bron en taalinstellingen van het origineel overneemt, dus publiceer het voordat je het verstuurt.
Concepten en gepubliceerde versies
Elk template heeft precies één concept, de werkkopie die je bewerkt. Het heeft ook een willekeurig aantal gepubliceerde versies, elk genummerd (1, 2, 3, enzovoort) en nooit meer gewijzigd zodra ze bestaan. Bewerken wijzigt het concept ter plekke. Publiceren maakt een momentopname van het huidige concept, zet het om in de volgende genummerde versie en maakt die versie de versie die verzendingen gebruiken. Het concept zelf blijft bewerkbaar, zodat je kunt doorwerken aan de volgende versie.
De regel die ertoe doet bij verzenden is deze: een verzending gebruikt altijd de gepubliceerde versie van het template, en een concept wordt nooit op zichzelf verzonden. Je kunt het concept blijven bewerken terwijl een stabiele versie wordt verstuurd, en dan publiceren wanneer de wijziging klaar is. Het publiceren van een nieuwe versie verandert wat latere verzendingen renderen. Een verzending die al geaccepteerd is, wordt niet beïnvloed door een publicatie die daarna plaatsvindt.

Versies ondersteunen twee extra acties. Wijzigingen van het concept verwerpen om het concept terug te zetten naar wat momenteel gepubliceerd is. Of terugdraaien om een eerder gepubliceerde versie weer de versie te maken die verzendingen gebruiken. Je kunt alleen terugdraaien naar een versie die gepubliceerd was, nooit naar het concept zelf. Terugdraaien vervangt het concept door de inhoud van die versie, dus alles wat niet is opgeslagen in het concept gaat verloren, en verdere bewerking begint vanaf de versie waarnaar je hebt teruggedraaid. Een terugdraaiactie maakt geen nieuwe versie aan.
Om een bestaande afbeelding te kiezen, heb je leestoegang tot de mediabibliotheek van de werkruimte nodig. Om een nieuwe afbeelding te uploaden, te plakken of te slepen en neer te zetten, heb je schrijftoegang nodig. Als Afbeelding invoegen is uitgeschakeld of je de bibliotheek niet kunt doorzoeken of geen afbeeldingen kunt uploaden, vraag dan een werkruimtebeheerder om de bijbehorende machtiging voor de mediabibliotheek. Alleen de machtiging om templates te bewerken geeft geen toegang tot de mediabibliotheek.
Kies in het dashboard Visueel > Afbeelding invoegen om je mediabibliotheek te doorzoeken of een PNG-, JPEG-, GIF- of WebP-afbeelding van maximaal 5 MB te uploaden. Statische WebP-afbeeldingen worden omgezet naar PNG of JPEG. Selecteer de afbeelding om de Afbeeldingsbeschrijving, weergavebreedte, uitlijning en link in te stellen. Markeer een afbeelding alleen als Decoratieve afbeelding als deze geen informatie toevoegt. Een afbeelding met een link heeft een beschrijving nodig die de bestemming uitlegt. Elke taal behoudt de eigen afbeeldingsbeschrijvingen en indeling.
Gebruik Afbeelding vervangen om de geselecteerde afbeelding te wijzigen met behoud van beschrijving, link, breedte en uitlijning. Je kunt ook één afbeeldingsbestand tegelijk in de visuele editor plakken of slepen. Wacht tot de upload klaar is of annuleer deze voordat je opslaat of een test verstuurt. Controleer het voorbeeld en open Meer acties > Testmail om de huidige inhoud naar jezelf te sturen. Code blijft beschikbaar om HTML te bewerken.
Als je een afbeelding uit de mediabibliotheek verwijdert, blijft deze in eerder verstuurde e-mails staan. Een vervangende afbeelding gebruikt een nieuwe URL, zodat eerdere berichten de oorspronkelijke afbeelding blijven tonen.
Opslaan wordt bewaakt door een revisienummer. Stuur het revision mee dat je het laatst hebt gelezen voor de taal die je opslaat. Als iemand anders die taal in de tussentijd heeft gewijzigd, wordt het opslaan geweigerd als conflict in plaats van het werk van de ander te overschrijven. Laat revision weg om onvoorwaardelijk op te slaan. Publiceren en terugdraaien gebruiken het eigen revision van het concept op dezelfde manier.
Inhoud in meer dan één taal
Een template bevat inhoud in maximaal 25 talen, elk met een eigen onderwerp en body, getagd met een BCP-47-code zoals en of pt-BR. Eén taal is de standaardtaal van het template. Publiceren van een template publiceert alle talen die het bevat tegelijk. Je kunt niet één taal apart publiceren, dus ze moeten allemaal af zijn. Elke taal heeft een onderwerp en een body nodig, en de standaardtaal van het template moet een van de talen zijn die je hebt ingevuld. Als er iets ontbreekt, wordt er niets gepubliceerd en vertelt de fout je wat er ontbreekt in elke taal, zodat je alles in één keer kunt oplossen. Je hoeft niet elke taal van tevoren af te hebben: publiceer de talen die klaar zijn en voeg de rest later toe.
Een taal heeft een HTML-body nodig. Je kunt het text weglaten: publiceren maakt dan automatisch een platte-tekstalternatief van de HTML, zodat je beide delen hebt zonder het tweede zelf te schrijven.
Elke taal kan ook previewtekst bevatten, ook wel preheader genoemd: de regel die een inbox na het onderwerp toont in de berichtenlijst. Het is optioneel, maximaal 255 tekens, en accepteert dezelfde {{ variable }}-placeholders als het onderwerp. Laat het weg en de inbox valt terug op de eerste regel van de body, wat zelden de regel is die je zou kiezen. Publiceren weigert previewtekst op een taal waarvan de body geen HTML-deel heeft, omdat een mailclient de previewregel alleen uit verborgen HTML-markup leest, en weigert {{ bird.unsubscribe_url }} erin om dezelfde reden waarom het onderwerp het niet kan bevatten: geen van beide is een plek waar een link thuishoort.
Twee instellingen dekken een verzending die geen taal noemt waarvoor het template inhoud heeft, en ze beschermen tegen verschillende fouten:
| Instelling | Wat het regelt |
|---|---|
| on_missing_language | Wat er gebeurt wanneer een verzending een taal opvraagt die het template niet heeft. fallback, de standaard, levert de dichtstbijzijnde overeenkomst. Het probeert eerst een bredere vorm van dezelfde taal, zodat een opgeslagen pt een verzoek voor pt-BR kan bedienen. Het valt daarna terug op de standaardtaal van het template. fail weigert de verzending in plaats daarvan, voor inhoud waarbij het versturen van de verkeerde taal erger is dan helemaal niet versturen. |
| language_source_required | Of een verzending verplicht een taal moet opgeven. Dit staat standaard uit, dus een verzending zonder taal krijgt de standaardtaal. Zet je het aan, dan wordt die verzending geweigerd. Een broadcast kiest één taal voor het hele publiek, dus een template met deze instelling aan heeft die taalkeuze nodig voordat de broadcast kan verzenden. |
Je kunt deze twee onafhankelijk instellen. Op zichzelf geldt fail alleen wanneer een verzending een taal noemt die we niet hebben, dus een verzending die geen taal noemt komt gewoon door. Zet beide instellingen samen aan wanneer je wilt dat elke verzending bewust een taal noemt.
Personaliseren met variabelen
Schrijf {{ variable }}-placeholders in het onderwerp, de previewtekst en de body. We pikken ze automatisch op, gecombineerd over alle talen, zodat je ze nooit apart hoeft te declareren. Het voorvoegsel van de placeholder onderscheidt de twee soorten. Een pad dat begint met bird. leest uit onze data, een contactrecord of de uitschrijflink. Al het andere is een parameter waarvoor je bij het verzenden een waarde meegeeft.
De naam van een parameter is een enkel woord, zoals {{ animal }}. Een naam met punten verwijst naar een structuur die een parameter niet heeft, dus het publiceren ervan wordt geweigerd: schrijf de waarde als een eigen parameter, of lees contactdata met bird.contact.<attribute>.
Bij een enkele verzending of een batch komt de waarde van een parameter uit het template.parameters-object van de verzending, op basis van de naam. Eén set waarden dekt alle ontvangers van die verzending. bird is de enige naam die je daar niet kunt gebruiken: een template.parameters-sleutel met de naam bird wordt geweigerd met een 422.
Een broadcast heeft geen parameters-object, dus de inhoud kan alleen bird.-placeholders gebruiken. bird.contact.<attribute> wordt gevuld vanuit de eigen contacteigenschappen van elke ontvanger, en dat is wat de inhoud per ontvanger personaliseert. Elke contacteigenschap is beschikbaar via de eigen sleutel, en dat geldt ook voor de drie ingebouwde velden: first_name, last_name en email.
Codevoorbeeld
Hi {{ bird.contact.first_name }},Elke parameter in het template heeft een waarde nodig bij het verzenden. Anders retourneert het API een 422 die de ontbrekende parameter noemt. Geef waarden mee voor parameters in alle talen, omdat de geselecteerde taal kan afhangen van terugvalinstellingen. Een ontbrekende contacteigenschap wordt als lege waarde gerenderd, dus voeg een terugvalwaarde toe voor klantgerichte inhoud: {{ bird.contact.first_name | default: "there" }}.
Een broadcast is strenger in welke namen het accepteert, omdat contacteigenschappen het enige zijn waarmee het placeholders kan vullen. De bird.contact.*-placeholders kunnen alleen een ingebouwd veld of een contacteigenschap benoemen die de werkruimte heeft geregistreerd. Elke andere placeholder, inclusief een parameter, kan de broadcast niet invullen. Het verzenden wordt geweigerd en de fout noemt de placeholder.
Wat het archiveren van een eigenschap verandert voor een template is alleen nieuwe content: de eigenschap verdwijnt uit de kiezer in de editor, en het publiceren van een versie waarvan de content die eigenschap uitleest wordt geweigerd, met vermelding van de eigenschap. Versies die vóór de archivering zijn gepubliceerd blijven ongewijzigd.
Placeholders gebruiken Liquid, dus filters en control flow werken naast gewone substitutie. Een {% if %}-conditional en een {% for %}-loop over een arraywaarde zijn allebei toegestaan. Een aantal constructies wordt geweigerd bij het publiceren, en de fout noemt precies wat je moet aanpassen:
- Partial includes, met {% include %} of {% render %}.
- De increment-, decrement- en ifchanged-tags.
- De money-, format_date-, format_time-, json-, inspect- en type-filters.
- Vergelijken met empty of blank. Gebruik in plaats daarvan .size == 0.
- Blocks die veel dieper genest zijn dan echte e-mailmarkup nodig heeft.
Het template van een broadcast kan helemaal geen {% for %}-loop gebruiken, omdat een broadcast één waarde per contacteigenschap invult en niets heeft om over te itereren. Als je content een loop nodig heeft, verstuur die dan via het API-endpoint.
Elk template gebruikt Liquid, ook als het alleen {{ variable }}-placeholders bevat. Vóór het publiceren valideren we het onderwerp, de previewtekst, de HTML en de platte-tekstcontent als Liquid. We voegen ook het escape-filter toe aan elke HTML-output die nog niet eindigt op escape of escape_once, zodat een waarde met & of < de omringende markup niet kan wijzigen. De gereserveerde unsubscribe-output blijft ongewijzigd, zodat het verzenden die kan vervangen. De onderwerpregel en platte-tekstbody worden ongewijzigd gelaten. Omdat het publiceren deze filters toevoegt, is de HTML die je uit een gepubliceerde versie uitleest mogelijk niet byte-identiek aan wat je hebt ingediend.
Zet een volledige URL rechtstreeks in een href, bijvoorbeeld <a href="{{ sign_in_url }}">Sign in</a>. Voeg url_encode niet toe aan de hele waarde. Het percent-encodeert https://, /, ? en &, waardoor het resultaat niet meer werkt als absolute link. We voegen HTML-escaping toe met behoud van de URL-structuur. Wanneer een parameter één URL-component levert, encodeer dat component dan expliciet: <a href="https://example.com/search?q={{ query | url_encode }}">Search</a>.
Voorbeeld bekijken vóór publicatie
Render een template met voorbeeldwaarden en ontvang de onderwerpregel en de HTML- en platte-tekstbody die een verzending zou opleveren. Preview gebruikt onze lokale Liquid-renderer en rendert standaard de draft, wat de manier is om een wijziging te controleren voordat die live gaat. Het kan ook een gepubliceerde versie renderen. Het werkt voor je eigen templates en voor onze ingebouwde templates, en er wordt niets verzonden.
Je kunt ook zelf de content aanleveren in plaats van de draft te laten uitlezen. Geef een onderwerp en body's mee en die worden gerenderd, precies als een draft, waardoor een editor een wijziging kan tonen terwijl die wordt getypt zonder eerst iets op te slaan.
Personalisatie wordt voor je ingevuld, zodat het resultaat leest als afgewerkte tekst in plaats van {{ }}-placeholders. Geef een contact op en elke bird.contact.<attribute> wordt opgehaald uit de eigen eigenschappen van dat contact, wat de manier is om je tekst te controleren tegen een echt record voordat iemand het ontvangt. De waarden komen uit dezelfde projectie die een broadcast gebruikt om zijn placeholders te vullen, dus de preview geeft hetzelfde antwoord als een verzending.
Laat contact weg en er worden standaardwaarden ingevuld: Bird en Test voor de voor- en achternaam, bird.test@example.com voor het e-mailadres, en de geregistreerde fallback van elke andere eigenschap. Een eigenschap zonder fallback wordt weergegeven als de sleutel tussen haakjes, zoals [loyalty_tier], waardoor je zowel ziet dat de waarde een placeholder is als welke eigenschap nog een fallback nodig heeft.
Een contact wordt gelezen zoals het er nu uitziet. Dat maakt een preview het juiste middel om content te controleren die je op het punt staat te versturen, en het verkeerde om te bekijken wat een eerdere verzending bevatte. Om te lezen wat een verzending daadwerkelijk heeft opgeleverd, open je dat bericht in het e-maillogboek, dat het rendert op basis van de waarden die die verzending meestuurde.
Voeg language toe om één specifieke taal te renderen, of laat het weg voor de standaardtaal van het template. Het antwoord vertelt welke taal is gerenderd, wat van belang is wanneer de gevraagde taal niet beschikbaar is en de on_missing_language van het template een nabije match heeft geserveerd.
Als de draft personalisatie bevat die bij publicatie geweigerd zou worden, geeft de preview dezelfde fout terug, waardoor het ook een manier is om problemen vroeg te ontdekken.
In de templatebuilder van het dashboard toont Preview with contact data onderaan de linkerbalk de gerenderde e-mail naast wat je aan het bewerken bent, in zowel de visuele als de code-editor. De kiezer eronder bepaalt wiens gegevens de placeholders vullen, en Sample data zijn de standaardwaarden hierboven.
Verzenden met een template
Stel het template-veld van de verzending in op een object dat het template benoemt, op id (emt_...) of op slug, met precies een van de twee. Zet de variabelewaarden in template.parameters. Voeg language toe om een specifieke taal te kiezen, of laat het weg om de standaardtaal van het template te versturen, tenzij het template vereist dat elke verzending er een opgeeft. Laat subject, html en text helemaal weg, omdat het template die al levert.
Codevoorbeeld
{
"from": "hello@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"category": "transactional",
"template": {
"slug": "welcome-email",
"parameters": { "first_name": "Jane" }
}
}Eén gedrag om rekening mee te houden: de categorie van het template is een standaard, en de eigen category van de verzending overschrijft die. Laat category weg, en de verzending erft de categorie van het template, zodat een operationeel template als transactioneel verstuurt zonder dat je het bij elke aanroep herhaalt. Stel category in, en jouw waarde wint. De rest van het contract aan verzendzijde staat in verzenden met een template.
Opmaak buiten het dashboard
De volledige levenscyclus is beschikbaar buiten het dashboard. De publicatiestap heet daar submit, en dat is de bewerking die de draft omzet in de volgende gepubliceerde versie:
Codevoorbeeld
bird email templates create welcome-email --category marketing --source html
bird email templates versions languages set <emt_...> <emv_...> en --subject "Hi {{ bird.contact.first_name }}" --html "<p>Hello</p>"
bird email templates versions submit <emt_...> <emv_...> --validate-only # report problems, freeze nothing
bird email templates versions submit <emt_...> <emv_...> # freeze, go livecreate geeft het template terug samen met zijn draft_version_id, die elk versie- en taalcommando nodig heeft. --validate-only voert dezelfde volledigheidscontroles uit als een echte submit, zonder iets vast te leggen, dus het is de goedkope manier om elk probleem in alle talen in één keer te vinden. Het teruglezen van een template geeft je de metadata en de status per taal, maar geen content. Content zit op de talen van een versie, één taal tegelijk.
De SDK's bieden dezelfde levenscyclus als getypte methoden onder email.templates, met de versie- en taalbewerkingen eronder genest als email.templates.versions en email.templates.versions.languages. Een agent bereikt dezelfde bewerkingen via de email_templates_* MCP-tools.
Volgende stappen
- E-mail verzenden: de volledige verzendpayload, en hoe templateverzendingen daarin passen
- Categorieën: marketing vs transactional kiezen per verzending
- bird email templates: templates beheren vanuit de terminal
- API reference: volledige request- en responseschema's voor alle achttien templatebewerkingen
- SDKs: de getypte email.templates-methoden in TypeScript, Python, PHP en Go
- MCP server: een agent templates laten opstellen en publiceren
- Een e-mailtemplate bouwen: een video die er een bouwt in het dashboard en daarna een agent er een laat bouwen
Gerelateerde bronnen
Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.