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
- Display branded content -theme your UI with the colors and fonts you just extracted
- Generate branded emails -build email templates using brand data
- API Reference -full endpoint documentation