BrandparserInvite Only

3. Generate Branded Emails for Your Customers

Build HTML email templates using brand colors, fonts, and logos from Brandparser

Fetch a customer's brand data and generate a ready-to-send HTML email template with their colors, logo, and font styling.

What you'll build

A TypeScript function that takes a brand ID and generates a complete HTML email template -header with logo, brand-colored CTA button, and proper font stacks.

Step 1: Fetch brand data

const API_KEY = process.env.BRANDPARSER_API_KEY!;
const BASE_URL = "https://api.brandparser.com";

async function getBrand(brandId: string) {
  const res = await fetch(`${BASE_URL}/v1/api/brands/${brandId}`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
  const { data } = await res.json();
  return data;
}

Step 2: Extract email-relevant brand data

Email clients have limited CSS support. Extract the essentials:

type EmailBrand = {
  primaryColor: string;
  primaryHoverColor: string;
  buttonTextColor: string;
  textColor: string;
  backgroundColor: string;
  fontStack: string;
  logoUrl: string | null;
  brandName: string;
};

function extractEmailBrand(brand: any): EmailBrand {
  const colors = brand.analysis.colors;
  const fonts = brand.analysis.typography.font_families;
  const logos = brand.analysis.logos.slots;
  const buttons = colors.button_colors?.[0];
  const primaryColor = colors.primary_palette[0];

  // Build a web-safe font stack from the brand font
  const mainFont = fonts[0]?.name ?? "Arial";
  const fontStack = `'${mainFont}', Arial, Helvetica, sans-serif`;

  // Find the first available logo URL
  const logoSlot = Object.values(logos).find(
    (slot): slot is { source_url: string } =>
      slot !== null && "source_url" in slot
  );

  return {
    primaryColor: primaryColor.hex,
    primaryHoverColor: buttons?.hover_background_hex ?? primaryColor.hex,
    buttonTextColor: buttons?.text_hex ?? "#FFFFFF",
    textColor: "#1a1a1a",
    backgroundColor: "#f8f9fa",
    fontStack,
    logoUrl: logoSlot?.source_url ?? null,
    brandName: brand.name,
  };
}

Step 3: Generate the HTML email

Email templates use tables and inline CSS for maximum compatibility:

function generateBrandedEmail(
  emailBrand: EmailBrand,
  content: {
    heading: string;
    body: string;
    ctaText: string;
    ctaUrl: string;
  }
): string {
  const { heading, body, ctaText, ctaUrl } = content;
  const b = emailBrand;

  return `<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin:0; padding:0; background-color:${b.backgroundColor}; font-family:${b.fontStack};">
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0">
    <tr>
      <td align="center" style="padding:40px 20px;">
        <table role="presentation" width="600" cellpadding="0" cellspacing="0"
               style="background-color:#ffffff; border-radius:8px; overflow:hidden;">

          <!-- Header with logo -->
          <tr>
            <td style="padding:32px 40px; background-color:${b.primaryColor}; text-align:center;">
              ${b.logoUrl
                ? `<img src="${b.logoUrl}" alt="${b.brandName}" height="40"
                     style="height:40px; width:auto;">`
                : `<span style="color:${b.buttonTextColor}; font-size:24px;
                     font-weight:bold; font-family:${b.fontStack};">${b.brandName}</span>`
              }
            </td>
          </tr>

          <!-- Body content -->
          <tr>
            <td style="padding:40px;">
              <h1 style="margin:0 0 16px; font-size:24px; color:${b.textColor};
                  font-family:${b.fontStack};">
                ${heading}
              </h1>
              <p style="margin:0 0 32px; font-size:16px; line-height:1.6;
                 color:#555555; font-family:${b.fontStack};">
                ${body}
              </p>

              <!-- CTA Button -->
              <table role="presentation" cellpadding="0" cellspacing="0">
                <tr>
                  <td style="border-radius:6px; background-color:${b.primaryColor};">
                    <a href="${ctaUrl}"
                       style="display:inline-block; padding:14px 32px;
                       color:${b.buttonTextColor}; font-family:${b.fontStack};
                       font-size:16px; font-weight:600; text-decoration:none;">
                      ${ctaText}
                    </a>
                  </td>
                </tr>
              </table>
            </td>
          </tr>

          <!-- Footer -->
          <tr>
            <td style="padding:24px 40px; border-top:1px solid #e8e8e8;
                text-align:center; font-size:13px; color:#999999;
                font-family:${b.fontStack};">
              Sent by ${b.brandName}
            </td>
          </tr>

        </table>
      </td>
    </tr>
  </table>
</body>
</html>`;
}

Step 4: Send via SendGrid

async function sendBrandedEmail(
  to: string,
  subject: string,
  htmlContent: string
) {
  const res = await fetch("https://api.sendgrid.com/v3/mail/send", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SENDGRID_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      personalizations: [{ to: [{ email: to }] }],
      from: { email: "hello@yourapp.com" },
      subject,
      content: [{ type: "text/html", value: htmlContent }],
    }),
  });

  if (!res.ok) {
    throw new Error(`SendGrid error: ${res.status}`);
  }
}

Complete example

const brand = await getBrand("550e8400-e29b-41d4-a716-446655440000");
const emailBrand = extractEmailBrand(brand);

const html = generateBrandedEmail(emailBrand, {
  heading: "Your report is ready",
  body: "We've finished analyzing your Q4 performance. Click below to view the full breakdown.",
  ctaText: "View Report",
  ctaUrl: "https://yourapp.com/reports/q4",
});

await sendBrandedEmail("customer@example.com", "Your Q4 Report", html);

Tips

  • Email font support is limited -most email clients ignore @font-face. The font stack fallback (Arial, Helvetica, sans-serif) ensures readability everywhere. The brand font will render in Apple Mail, iOS Mail, and some Outlook versions.
  • Logo format matters -SVG logos may not render in all email clients. If you have a PNG/JPG variant, prefer that. Check the format field in the logo slot.
  • Inline all CSS -email clients strip <style> blocks. Every style must be inline. The template above already does this.
  • Test rendering -use Litmus or Email on Acid to preview across email clients.

Next steps

On this page