BrandparserInvite Only

1. Onboard a Customer and Grab Their Brand

Parse a website URL and extract colors, fonts, logos, and tone for your app

Parse a customer's website and pull out the brand data you need -colors, fonts, logos, and voice -in under a minute.

What you'll build

A TypeScript function that takes a URL, submits it for brand analysis, and returns structured brand data you can store alongside a customer record.

Step 1: Parse the URL

Submit a URL to the parse endpoint. The API returns immediately with a brand_id while analysis runs in the background.

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

const res = await fetch(`${BASE_URL}/v1/api/parse`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://stripe.com" }),
});

const { data } = await res.json();
console.log(data.brand_id); // "550e8400-e29b-41d4-a716-446655440000"
console.log(data.status);   // "queued"

Step 2: Poll for completion

Analysis takes 1–3 minutes. Poll the brand endpoint until analysis_status is "complete".

async function waitForBrand(brandId: string) {
  while (true) {
    const res = await fetch(`${BASE_URL}/v1/api/brands/${brandId}`, {
      headers: { Authorization: `Bearer ${API_KEY}` },
    });

    const { data } = await res.json();

    if (data.analysis_status === "complete") return data;
    if (data.analysis_status === "failed") throw new Error("Analysis failed");

    await new Promise((r) => setTimeout(r, 5000));
  }
}

Step 3: Extract what you need

Once complete, the analysis object contains all brand sections. Here's how to pull out the most commonly needed data:

const brand = await waitForBrand(brandId);
const { analysis } = brand;

// Colors -primary palette with hex, rgba, hsl, and usage info
const primaryColors = analysis.colors.primary_palette;
// [{ name: "Electric Indigo", hex: "#6366F1", usage: "Primary brand color, CTAs, links", ... }]

// Fonts -families with Google Fonts URLs when available
const fonts = analysis.typography.font_families;
// [{ name: "Inter", usage: "Headings and body text", availability: { google_fonts_css_url: "..." } }]

// Logos -slots for different variants (mark, wordmark, combo, icon, etc.)
const logos = analysis.logos.slots;
// { mark_light: { source_url: "https://...", format: "svg", ... }, ... }

// Tone -voice summary and LLM-ready prompts
const voice = analysis.tone.voice_summary;
// "Confident, warm, and refreshingly direct."
const systemPrompt = analysis.tone.llm_prompts.system_prompt;
// "You are a copywriter for Acme Design Co."

See the full response schemas: Colors | Typography | Logos | Tone

Step 4: Store alongside your customer

Map the parsed brand data to your customer record:

type CustomerBrand = {
  customerId: string;
  brandparserBrandId: string;
  primaryColor: string;
  accentColor: string | null;
  fontFamily: string;
  fontCssUrl: string | null;
  logoUrl: string | null;
  voiceSummary: string;
};

function extractCustomerBrand(
  customerId: string,
  brand: any
): CustomerBrand {
  const colors = brand.analysis.colors.primary_palette;
  const fonts = brand.analysis.typography.font_families;
  const logos = brand.analysis.logos.slots;

  const primary = colors[0];
  const accent = colors.length > 1 ? colors[1] : null;
  const mainFont = fonts[0];

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

  return {
    customerId,
    brandparserBrandId: brand.id,
    primaryColor: primary.hex,
    accentColor: accent?.hex ?? null,
    fontFamily: mainFont.name,
    fontCssUrl: mainFont.availability?.google_fonts_css_url ?? null,
    logoUrl: logoSlot?.source_url ?? null,
    voiceSummary: brand.analysis.tone.voice_summary,
  };
}

Complete example

Putting it all together:

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

async function onboardCustomerBrand(customerId: string, websiteUrl: string) {
  // 1. Submit for parsing
  const parseRes = await fetch(`${BASE_URL}/v1/api/parse`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ url: websiteUrl }),
  });
  const { data: parseData } = await parseRes.json();

  // 2. Wait for completion
  let brand;
  while (true) {
    const res = await fetch(
      `${BASE_URL}/v1/api/brands/${parseData.brand_id}`,
      { headers: { Authorization: `Bearer ${API_KEY}` } }
    );
    const { data } = await res.json();

    if (data.analysis_status === "complete") {
      brand = data;
      break;
    }
    if (data.analysis_status === "failed") {
      throw new Error("Brand analysis failed");
    }
    await new Promise((r) => setTimeout(r, 5000));
  }

  // 3. Extract and return brand data
  const colors = brand.analysis.colors.primary_palette;
  const fonts = brand.analysis.typography.font_families;
  const logos = brand.analysis.logos.slots;
  const logoSlot = Object.values(logos).find(
    (slot): slot is { source_url: string } =>
      slot !== null && "source_url" in slot
  );

  return {
    customerId,
    brandId: brand.id,
    primaryColor: colors[0]?.hex,
    fontFamily: fonts[0]?.name,
    fontCssUrl: fonts[0]?.availability?.google_fonts_css_url ?? null,
    logoUrl: logoSlot?.source_url ?? null,
    voiceSummary: brand.analysis.tone.voice_summary,
  };
}

// Usage
const customerBrand = await onboardCustomerBrand(
  "cust_123",
  "https://stripe.com"
);
console.log(customerBrand);

Next steps

On this page