Skip to content
Pidgely Docs

API reference · Template builder & AI

Render a builder document

POSThttps://api.pidgely.com/template-builder/render
View as Markdown

Scale plan. Renders a builder document to the exact HTML and plain text a send would use (variable tags such as {{{FIRST_NAME|there}}} are kept for send time) and lints it for deliverability: all caps, spam phrases, link shorteners, image-only content, placeholder links, missing unsubscribe link. Nothing is stored.

Returns the exact HTML and text a send would use (variable tags kept) and the deliverability lint. Scale plan (403 plan_required otherwise).

Authorization: Bearer pdg_…. An API key with full_access. A sending_access key gets 401 restricted_api_key.

Body parameters

JSON object.

Name Type Required Description
document object Yes Visual builder document (Pidgely extension, Scale plan). The server renders it to table-based e-mail HTML with Outlook (VML) buttons, responsive and dark-mode rules, and a plain-text version.
document.version integer No One of 1.
document.preview_text string No Preview text shown by mail clients next to the subject (inserted as hidden text at the top of the HTML).
document.theme object No Global look of a builder e-mail. Colors are hex (#rrggbb).
document.theme.brand_color string No —
document.theme.text_color string No —
document.theme.background_color string No —
document.theme.content_color string No Background of the content card.
document.theme.link_color string No —
document.theme.font string No One of system, inter, helvetica, georgia, verdana, trebuchet.
document.theme.content_width integer No Between 480 and 800.
document.theme.radius integer No Between 0 and 32.
document.theme.logo_url string No —
document.theme.logo_width integer No —
document.theme.logo_alt string No —
document.theme.logo_align string No One of left, center, right.
document.theme.logo_dark_url string No Logo variant shown in dark mode by clients that support it (Apple Mail, iOS); others keep logo_url.
document.theme.button_text_color string No Label color of buttons on the brand color; empty picks white or near-black automatically.
document.theme.web_font string No Google Fonts family loaded where e-mail clients support web fonts; font is the fallback stack.
document.theme.heading_font string No Heading stack (empty = font). One of system, inter, helvetica, georgia, verdana, trebuchet.
document.theme.heading_web_font string No Google Fonts family for headings (empty = web_font).
document.blocks object[] Yes —
document.blocks[].id string No Unique id (UUID).
document.blocks[].type string Yes One of heading, text, button, image, divider, spacer, columns, list, quote, code, social, footer.
document.blocks[].style object No —
document.blocks[].style.align string No One of left, center, right.
document.blocks[].style.color string No —
document.blocks[].style.background string No —
document.blocks[].style.font_size integer No Between 10 and 64.
document.blocks[].style.padding object No —
document.blocks[].level integer No One of 1, 2, 3.
document.blocks[].text string No —
document.blocks[].runs object[] No —
document.blocks[].runs[].text string Yes —
document.blocks[].runs[].bold boolean No —
document.blocks[].runs[].italic boolean No —
document.blocks[].runs[].href string No —
document.blocks[].label string No —
document.blocks[].href string No —
document.blocks[].full_width boolean No —
document.blocks[].src string No —
document.blocks[].alt string No —
document.blocks[].width integer No —
document.blocks[].height integer No —
document.blocks[].thickness integer No —
document.blocks[].columns object[] No —
document.blocks[].columns[].blocks object[] Yes —
document.blocks[].ordered boolean No —
document.blocks[].items object[][] No —
document.blocks[].links object[] No —
document.blocks[].links[].network string Yes One of x, linkedin, instagram, facebook, youtube, github, tiktok, discord, website.
document.blocks[].links[].url string Yes Public https URL that receives the events.
document.blocks[].unsubscribe boolean No —
document.blocks[].unsubscribe_label string No —
document.blocks[].unsubscribe_url string No Default {{{PIDGELY_UNSUBSCRIBE_URL}}} (filled per recipient by broadcasts; pass it as a variable on API sends).
subject string No Subject line, up to 998 bytes. Required unless a template provides it.

Request

This endpoint is in the Node.js SDK; the other SDKs don't cover it yet, so call it over HTTP from them.

Node.js
import { Pidgely } from 'pidgely';

const pidgely = new Pidgely(process.env.PIDGELY_API_KEY);

const { data, error } = await pidgely.templateBuilder.render({
  document: {
    blocks: [
      {
        type: 'heading',
        text: 'Welcome, {{{FIRST_NAME|there}}}',
      },
      {
        type: 'button',
        label: 'Get started',
        href: 'https://acme.com/start',
      },
    ],
  },
  subject: 'Welcome to Acme',
});
console.log(data ?? error);
cURL
curl -X POST 'https://api.pidgely.com/template-builder/render' \
  -H "Authorization: Bearer $PIDGELY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "document": {
    "blocks": [
      {
        "type": "heading",
        "text": "Welcome, {{{FIRST_NAME|there}}}"
      },
      {
        "type": "button",
        "label": "Get started",
        "href": "https://acme.com/start"
      }
    ]
  },
  "subject": "Welcome to Acme"
}'

Response

200 OK

JSON
{
  "object": "template_builder",
  "html": "<p>Hello!</p>",
  "text": "Hello!",
  "variables": [
    "variable"
  ],
  "issues": [
    {
      "code": "code",
      "severity": "error",
      "block_id": "0199d8a2-6f3c-7c51-9e2a-3b1f0c6d4e21",
      "field": "field",
      "message": "The `to` field is required.",
      "detail": "detail"
    }
  ],
  "document": {
    "version": 1,
    "preview_text": "preview_text",
    "theme": {
      "brand_color": "brand_color",
      "text_color": "text_color",
      "background_color": "background_color",
      "content_color": "content_color",
      "link_color": "link_color",
      "font": "system",
      "content_width": 480,
      "radius": 0,
      "logo_url": "logo_url",
      "logo_width": 1,
      "logo_alt": "logo_alt",
      "logo_align": "left",
      "logo_dark_url": "logo_dark_url",
      "button_text_color": "button_text_color",
      "web_font": "web_font",
      "heading_font": "system",
      "heading_web_font": "heading_web_font"
    },
    "blocks": [
      {
        "id": "0199d8a2-6f3c-7c51-9e2a-3b1f0c6d4e21",
        "type": "heading",
        "style": {
          "align": "left",
          "color": "color",
          "background": "background",
          "font_size": 10,
          "padding": {
            "top": 1,
            "right": 1,
            "bottom": 1,
            "left": 1
          }
        },
        "level": 1,
        "text": "Hello!",
        "runs": [
          {
            "text": "Hello!",
            "bold": false,
            "italic": false,
            "href": "href"
          }
        ],
        "label": "label",
        "href": "href",
        "full_width": false,
        "src": "src",
        "alt": "alt",
        "width": 1,
        "height": 1,
        "thickness": 1,
        "columns": [
          {
            "blocks": [
              null
            ]
          }
        ],
        "ordered": false,
        "items": [
          [
            {
              "text": null,
              "bold": null,
              "italic": null,
              "href": null
            }
          ]
        ],
        "links": [
          {
            "network": "x",
            "url": "https://acme.com/webhooks/pidgely"
          }
        ],
        "unsubscribe": false,
        "unsubscribe_label": "unsubscribe_label",
        "unsubscribe_url": "unsubscribe_url"
      }
    ]
  }
}

Response fields

Name Type Required Description
object string Yes Object type. One of template_render.
html string Yes HTML body. html or text is required (unless you send with a template).
text string Yes —
variables string[] Yes Typed variables (up to 50). FIRST_NAME, LAST_NAME, EMAIL and UNSUBSCRIBE_URL are reserved.
issues object[] Yes —
issues[].code string Yes all_caps, spam_words, excessive_punctuation, url_shortener, placeholder_link, insecure_link, empty_link, missing_image, missing_alt, missing_unsubscribe, image_only, link_ratio, missing_preview_text, missing_subject, subject_all_caps, subject_spam_words, subject_punctuation, subject_long, too_large, empty_document.
issues[].severity string Yes One of error, warning, info.
issues[].block_id string No —
issues[].field string No —
issues[].message string Yes —
issues[].detail string No —
document object Yes Visual builder document (Pidgely extension, Scale plan). The server renders it to table-based e-mail HTML with Outlook (VML) buttons, responsive and dark-mode rules, and a plain-text version.
document.version integer No One of 1.
document.preview_text string No Preview text shown by mail clients next to the subject (inserted as hidden text at the top of the HTML).
document.theme object No Global look of a builder e-mail. Colors are hex (#rrggbb).
document.theme.brand_color string No —
document.theme.text_color string No —
document.theme.background_color string No —
document.theme.content_color string No Background of the content card.
document.theme.link_color string No —
document.theme.font string No One of system, inter, helvetica, georgia, verdana, trebuchet.
document.theme.content_width integer No Between 480 and 800.
document.theme.radius integer No Between 0 and 32.
document.theme.logo_url string No —
document.theme.logo_width integer No —
document.theme.logo_alt string No —
document.theme.logo_align string No One of left, center, right.
document.theme.logo_dark_url string No Logo variant shown in dark mode by clients that support it (Apple Mail, iOS); others keep logo_url.
document.theme.button_text_color string No Label color of buttons on the brand color; empty picks white or near-black automatically.
document.theme.web_font string No Google Fonts family loaded where e-mail clients support web fonts; font is the fallback stack.
document.theme.heading_font string No Heading stack (empty = font). One of system, inter, helvetica, georgia, verdana, trebuchet.
document.theme.heading_web_font string No Google Fonts family for headings (empty = web_font).
document.blocks object[] Yes —
document.blocks[].id string No Unique id (UUID).
document.blocks[].type string Yes One of heading, text, button, image, divider, spacer, columns, list, quote, code, social, footer.
document.blocks[].style object No —
document.blocks[].style.align string No One of left, center, right.
document.blocks[].style.color string No —
document.blocks[].style.background string No —
document.blocks[].style.font_size integer No Between 10 and 64.
document.blocks[].style.padding object No —
document.blocks[].level integer No One of 1, 2, 3.
document.blocks[].text string No —
document.blocks[].runs object[] No —
document.blocks[].runs[].text string Yes —
document.blocks[].runs[].bold boolean No —
document.blocks[].runs[].italic boolean No —
document.blocks[].runs[].href string No —
document.blocks[].label string No —
document.blocks[].href string No —
document.blocks[].full_width boolean No —
document.blocks[].src string No —
document.blocks[].alt string No —
document.blocks[].width integer No —
document.blocks[].height integer No —
document.blocks[].thickness integer No —
document.blocks[].columns object[] No —
document.blocks[].columns[].blocks object[] Yes —
document.blocks[].ordered boolean No —
document.blocks[].items object[][] No —
document.blocks[].links object[] No —
document.blocks[].links[].network string Yes One of x, linkedin, instagram, facebook, youtube, github, tiktok, discord, website.
document.blocks[].links[].url string Yes Public https URL that receives the events.
document.blocks[].unsubscribe boolean No —
document.blocks[].unsubscribe_label string No —
document.blocks[].unsubscribe_url string No Default {{{PIDGELY_UNSUBSCRIBE_URL}}} (filled per recipient by broadcasts; pass it as a variable on API sends).

Errors

Errors have the shape {"statusCode", "name", "message"}. See Errors for the full list.

Status Name When
401 missing_api_key, restricted_api_key No Authorization: Bearer header, or a sending_access key called an endpoint that needs full_access.
403 invalid_api_key, validation_error The API key is invalid or revoked, or the request is not allowed for this account (unverified domain, plan limit, paused account).
422 validation_error A field is missing or invalid; message names it.
429 rate_limit_exceeded Too many requests per second. Wait for Retry-After seconds.