Sign inGet started

Submit an email template version

POST
/v1/email/templates/{template_ref}/versions/{version_id}/submit
bird email templates versions submit <template-ref> <version-id> \
  --expected-revision 3
Resposta200
{
  "errors": [
    {
      "language": "pt-BR",
      "field": "subject",
      "code": "E04051",
      "message": "A subject is required to submit."
    }
  ],
  "version": {
    "id": "emv_01krdgeqcxet5s7t44vh8rt9mg",
    "template_id": "emt_01krdgeqcxet5s7t44vh8rt9mg",
    "status": "published",
    "variables": [
      {
        "type": "code"
      }
    ],
    "default_language": "pt-BR",
    "updated_by": {
      "id": "usr_01krdgeqcxet5s7t44vh8rt9mg",
      "type": "user"
    }
  },
  "template_ref": "emt_01krdgeqcxet5s7t44vh8rt9mg",
  "version_id": "emv_01krdgeqcxet5s7t44vh8rt9mg",
  "compatibility_severity": "warning",
  "compatibility": [
    {
      "rule_id": "css_display_flex_grid",
      "severity": "warning",
      "language": "pt-BR",
      "field": "html",
      "message": "`display: flex` and `grid` don't work in Outlook (Windows/Windows Mail).",
      "fix": "Use tables for layout.",
      "partial": "Partial support for `display: flex` and `grid` in Gmail (iOS/Android).",
      "line": 14,
      "column": 6,
      "match": "display: flex",
      "unsupported_clients": [
        {
          "family": "outlook",
          "platforms": [
            "windows",
            "windows_mail"
          ]
        }
      ],
      "partial_clients": [
        {
          "family": "outlook",
          "platforms": [
            "windows",
            "windows_mail"
          ]
        }
      ]
    }
  ]
}
Submits the template's draft as a new immutable, numbered version and makes it the live version used by sends. The draft remains editable.
Every language the draft has must have a subject and a body, and the default language must be present. Submission is all or nothing: an incomplete language rejects the request and the response reports every language error. A submit freezes every language the draft carries, so it cannot name a subset. The draft does not have to hold every language you plan to support: add more in a later version.
Set validate_only: true to run the checks without creating a version. Set expected_revision to reject a concurrent edit. An unchanged draft is rejected. Submission is synchronous, and a returned version is live.
Parâmetros
template_ref
string
The template's id (emt_…) or slug. Submit freezes a draft, and a built-in system template has no draft, so its bird_ slug returns 404 not_found_error here.
version_id
string
Corpo da requisição
validate_only
boolean
Check the draft without actually submitting it. Every language gets checked and every problem gets reported back to you, but nothing is frozen and no new version gets created. Give a validation run its own Idempotency-Key, separate from the real submit that follows it. You can also send no key. The validation request and real submit have different bodies, so using the same key for both is rejected as key reuse.
expected_revision
integer
The draft revision you last read (from the template's revision field). A stale value returns a conflict so you can reload and retry.
languages
array of string
Languages to process when submitting an already-published version. Email templates accept submissions only for drafts, so setting this field for an email template is rejected.
Payload de resposta
valid
boolean
obrigatório
Whether the version passed every check.
errors
array of object
obrigatório
Every problem found across the draft's languages. Empty when valid is true.
Mostrar atributos secundários
errors.language
nullable string
The language this problem is about. Null when the problem is about the whole version rather than one language, for example an empty draft, or a default language the draft does not have.
errors.field
nullable string
Which field within that language has the problem, such as subject or html. Null when the problem is not about one particular field.
errors.code
string
obrigatório
The error code a real submit would fail with. Look it up in the error catalog to see what it means and what to do about it.
errors.message
string
obrigatório
What is wrong, worded so you can show it directly to whoever is authoring the template.
version
nullable object
The version this submit created, or null when it was only a validation run and nothing got frozen. As soon as this is not null, sends already use that version. No further action is required to make it live.
Mostrar atributos secundários
version.id
string
obrigatório
Template version ID.
version.template_id
string
obrigatório
The template this version belongs to.
version.version_number
nullable integer
Sequential published-version number (1, 2, 3…). Null while the version is a draft.
version.status
string
obrigatório
Whether this version is still being edited or has been published. It records the version's publication history: a version that a later one replaced stays published. The template's live_version_id names the version a send resolves to now.
archived is reserved and no version carries it yet. Version retirement will produce it, so it is declared here ahead of that feature: a client written against this list today keeps working when the first archived version arrives, rather than the value's arrival being a breaking change.
Possible values: draft, published, archived
version.revision
integer
obrigatório
The version's revision counter.
version.variables
array of object
obrigatório
Every variable this version's content uses. You supply a value for each of them when you send.
The list combines all the languages, because languages do not have to use the same variables: if the English body uses discount_code and the French body uses shipping_date, both appear here. Send a value for every variable in the list rather than only the ones you expect the language you are sending to use. A language that does not use a variable ignores the value you sent for it, and a variable the sent language does use but you left out is rejected with a 422 naming it.
Variables under the reserved bird. namespace are not listed here. We fill those in ourselves from the recipient's contact record.
Mostrar atributos secundários
version.variables.key
string
obrigatório
The key this slot is filled by. On email and SMS it is the key you set in the send's parameters object. On WhatsApp it is the name you repeat on the matching parameter inside components, or, for a template whose placeholders are positional, the position itself as 1, 2 and so on.
version.variables.type
string
obrigatório
The value type this slot accepts. SMS templates use the typed slots (code, amount and the rest), each of which rejects a value that does not match its constraint. Email and WhatsApp templates use text, which accepts any value. Open enum: treat an unrecognized value as a future type rather than an error.
Possible values (may grow over time): code, ttl, count, ref, date, date_time, amount, currency, text
version.variables.required
boolean
obrigatório
Whether the send must supply this variable. Omitting a required value returns 422 on email, SMS, and WhatsApp sends.
version.variables.constraint
string
obrigatório
A plain-language description of what values this variable accepts.
version.variables.sensitive
boolean
Whether this slot's value is kept out of durable storage. A sensitive slot's rendered value never appears in message content read back through the API: a stand-in placeholder is stored instead.
version.languages
object
obrigatório
The content this version holds, keyed by language tag in BCP-47 form such as en or pt-BR. Publishing freezes every language together, so a version shows exactly what it would send in each of them. On a published version this is the send content.
version.default_language
string
obrigatório
The language this version treats as its default: the one a send uses when it names none, and the last resort when a requested language is not available.
version.created_at
string
obrigatório
When this version was created.
version.published_at
nullable string
When this version was published, or null if it has not been published.
version.updated_by
nullable object
Who last saved this version: a member's own session, an OAuth token delegated from one, or a workspace API key. Publishing freezes a version, so on a published one this is whoever published it. Null means no actor is on record: a built-in template, which is code-defined rather than stored, or a version last saved by an API key before this field existed. Every other version has one, even when its display_name could not be resolved (a member whose account is gone, say).
Mostrar atributos secundários
version.updated_by.id
string
obrigatório
Actor identifier.
version.updated_by.type
string
obrigatório
Who or what performed the action: user for a member's own session, oauth_token for a token issued to a caller on a member's behalf, api_key for a workspace API key, system for our own automation, sso for an organization's SSO connection, and service_account for a workspace's connected Integration acting with no member behind it. Open enum: new actor types may be added over time, so treat any unrecognized value as a future type rather than an error.
Possible values (may grow over time): user, api_key, oauth_token, system, sso, service_account
version.updated_by.display_name
nullable string
The label the actor is shown under: typically a member's name or email address, or the API key's name. Null when it could not be resolved.
template_ref
string
obrigatório
The template this submit addressed.
version_id
string
obrigatório
The draft this submit addressed: the one it froze, or on a validation run the one it checked and left as it was. The frozen version, when there is one, is version.
compatibility_severity
string
obrigatório
The worst severity across every finding the response was computed from, which is the authoritative reading: a response that caps how many findings it lists still accounts here for the ones it left out. Each response's compatibility says which content it covered.
  • problem: at least one finding is a problem.
  • warning: every finding is a warning.
  • none: there are no findings.
Possible values: problem, warning, none
compatibility
array of object
obrigatório
What the draft's HTML uses that mail clients remove, ignore, or render inconsistently, across every language, in alphabetical order of language tag and then the order the patterns appear. Empty when nothing is worth reporting. Advisory, and separate from errors: a finding never fails a submit, so the version froze either way. Each finding names the language it is in, and its line and column count in that language's HTML, which the language read returns as content.html. At most 200 findings come back, the first 200 in that order, so a draft that reaches the cap can omit a later language's findings entirely rather than trimming each language: read a language's own findings from its read or its write. compatibility_severity is derived from every finding the draft produced, including any beyond those 200.
Mostrar atributos secundários
compatibility.rule_id
string
obrigatório
The rule that produced this finding.
Possible values (may grow over time): html_script, html_event_handlers, html_embedded_content, html_linked_stylesheet, css_at_import, html_form, html_svg, html_media, css_display_flex_grid, css_position_fixed_sticky, css_variables_no_fallback, css_viewport_units, html_button, css_math_functions, css_modern_color, html_web_page_markup
compatibility.severity
string
obrigatório
What a finding costs you.
  • problem: the pattern does nothing at all. The client removes the markup, never loads the stylesheet carrying it, or will not operate the control. Where a finding names clients, that is what happens in those clients.
  • warning: it does something, but not what you wrote.
Neither one refuses a save, a submit, or a send.
Possible values: problem, warning
compatibility.language
nullable string
obrigatório
Which language's content this finding is in. Null when the call covered a single language.
compatibility.field
string
obrigatório
Which field of that language the finding is in. Always html; the subject and the plain-text body are not checked.
compatibility.message
string
obrigatório
What is wrong and which clients it affects, worded to show to whoever is authoring the template. It covers the rule's whole category rather than the exact text that matched, so a rule covering <video> and <audio> names both whichever one is on the line. Show fix and then partial after it.
compatibility.fix
nullable string
obrigatório
What to use instead. Null when there is no drop-in alternative and the fix is a restructure.
compatibility.partial
nullable string
obrigatório
Which clients support the feature only partly. Null when no client's support is partial.
compatibility.line
integer
obrigatório
The 1-based line the pattern is on, in the HTML the containing response's compatibility says it covered.
compatibility.column
integer
obrigatório
The 1-based column the pattern starts at, on that line.
compatibility.match
string
obrigatório
The source text that matched, starting at line and column: the smallest span that identifies what is wrong. Never the enclosing line. For a finding on a whole element, the span runs from the opening tag through the close tag, because the client drops the element's content along with its markup. Cut at 256 characters, so an element holding a long body is quoted from its start rather than in full.
compatibility.unsupported_clients
array of object
obrigatório
Every client family that does not support the feature at all, in alphabetical order by each entry's family. Empty on a finding whose message, fix, and partial name no client. message names at most four families; this names all of them.
Mostrar atributos secundários
compatibility.unsupported_clients.family
string
obrigatório
Which mail client a finding applies to. A finding's message names at most Apple Mail, Gmail, Outlook, and Yahoo; its unsupported_clients and partial_clients name every client affected.
  • gmail: Gmail
  • outlook: Outlook
  • yahoo: Yahoo
  • apple_mail: Apple Mail
  • aol: AOL
  • thunderbird: Mozilla Thunderbird
  • samsung_email: Samsung Email
  • sfr: SFR
  • orange: Orange
  • protonmail: ProtonMail
  • hey: HEY
  • mail_ru: Mail.ru
  • fastmail: Fastmail
  • laposte: LaPoste.net
  • gmx: GMX
  • web_de: WEB.DE
  • ionos_1and1: 1&1
  • wp_pl: WP.pl
Possible values (may grow over time): gmail, outlook, yahoo, apple_mail, aol, thunderbird, samsung_email, sfr, orange, protonmail, hey, mail_ru, fastmail, laposte, gmx, web_de, ionos_1and1, wp_pl
compatibility.unsupported_clients.platforms
array of string
obrigatório
Which of the family's platforms this applies to, in alphabetical order.
compatibility.partial_clients
array of object
obrigatório
Every client family that renders something other than what you wrote, in alphabetical order by each entry's family. Empty when no client's support is partial, which is also when partial is null. partial names at most four families; this names all of them.
Mostrar atributos secundários
compatibility.partial_clients.family
string
obrigatório
Which mail client a finding applies to. A finding's message names at most Apple Mail, Gmail, Outlook, and Yahoo; its unsupported_clients and partial_clients name every client affected.
  • gmail: Gmail
  • outlook: Outlook
  • yahoo: Yahoo
  • apple_mail: Apple Mail
  • aol: AOL
  • thunderbird: Mozilla Thunderbird
  • samsung_email: Samsung Email
  • sfr: SFR
  • orange: Orange
  • protonmail: ProtonMail
  • hey: HEY
  • mail_ru: Mail.ru
  • fastmail: Fastmail
  • laposte: LaPoste.net
  • gmx: GMX
  • web_de: WEB.DE
  • ionos_1and1: 1&1
  • wp_pl: WP.pl
Possible values (may grow over time): gmail, outlook, yahoo, apple_mail, aol, thunderbird, samsung_email, sfr, orange, protonmail, hey, mail_ru, fastmail, laposte, gmx, web_de, ionos_1and1, wp_pl
compatibility.partial_clients.platforms
array of string
obrigatório
Which of the family's platforms this applies to, in alphabetical order.