Skip to content
Norbelys
Esc
↑↓navigate↵open⌘Jpreview
On this page

Text, native HTML and Zapier

Write normally or bring your own HTML. One body contract for variants and messages.

The same fields work in campaign variants, standalone messages and inline sent previews.

Input Result
text only Escaped HTML with line breaks, plus the original plain-text alternative.
html only Your authored layout, colors, tables, images and CSS, with resolved variables.
Both Your HTML and your separate plain-text alternative.

Supply at least one non-null, nonempty body. Empty supplied strings are rejected, including when the other body exists. No automatic HTML detection, Markdown parsing, AI rewriting, brand theme or template resource is involved. With prompt: null, authored content remains deterministic. A generation prompt explicitly opts into AI.

Write normally

For a campaign variant:

{
  "name": "Short introduction",
  "subject": "A quick question",
  "text": "Hello {{ recipient.given_name | default(\"team\") }},\n\nWould you like to see an example?\n\n{{ footer }}",
  "prompt": null
}

Newlines become HTML breaks. Literal <, > and & are escaped, so writing <strong>hello</strong> in text displays those characters rather than adding bold. MiniJinja variables and conditions work in both formats. Supplied values are data, never executable template code. Put actual markup in html when you want a design.

The API converts text once when accepting content. Campaign reads expose the normalized html alongside text; the existing queue and renderer handle delivery. When replacing a variant with new text-only content, omit html or set it to null. Sending an old HTML value alongside new text intentionally preserves that HTML. Each source and rendered body is limited to 100,000 characters, including generated markup and an inherited signature. Escaping can expand text past that limit.

Bring your own HTML

{
  "name": "Our own design",
  "subject": "Hello {{ recipient.given_name | default(\"team\") }}",
  "html": "<!doctype html><html><head><style>.brand { color: #18332f; }</style></head><body><table role=\"presentation\" width=\"100%\"><tr><td style=\"background:#fff;color:#111;padding:24px\"><h1 class=\"brand\">Hello {{ recipient.given_name | default(\"team\") }}</h1><p>Your own content.</p>{{ footer }}</td></tr></table></body></html>",
  "prompt": null
}

Your styles and markup remain the source; Norbelys does not regenerate or recolor them. Only the supported personalization syntax is evaluated. Inserted values are HTML-escaped. Do not use untrusted values as entire HTML fragments, CSS rules or unchecked URLs. Email clients decide which CSS and images they display; custom HTML does not override their rendering limitations. Use images for stable image URLs.

Configured features still apply: the optional preheader, sender signature, campaign open/click tracking and campaign unsubscribe handling. Use {{ footer }} to position the optional sender signature inside your layout; without a slot it appends before </body> where available. A sender without a footer adds none. Standalone messages and previews do not gain campaign engagement tracking. See signatures.

A small Zapier mapping

Use an HTTP POST action with a JSON body, such as API by Zapier. For Webhooks by Zapier, choose Custom Request with method POST to preserve the nested JSON shape:

{
  "from": "connected-sender@example.com",
  "to": ["recipient@example.com"],
  "subject": "A quick question",
  "text": "Hello {{ variables.first_name }},\n\nWould you like an example?",
  "variables": { "first_name": "Ada" }
}

Send it to https://api.norbelys.com/v1/messages, with Authorization: Bearer YOUR_KEY, Content-Type: application/json, and an Idempotency-Key derived from the source event. Map the upstream person’s name into variables.first_name rather than assembling template source from their data. Map the body to text, or to html for customer HTML; omit unused body fields rather than sending empty strings. Never send a new idempotency key just because the response was lost. 202 means queued; use the response ID to check delivery through the same API. Authentication, pacing and suppression stay on the server.

This is an HTTP mapping, not a claim that a separately published Zapier app exists. No preprocessing code step or external template engine is required.

Was this page helpful?