TL;DR
Extract a complete visual identity from any website with a single API call using ScrapeGraphAI's branding endpoint.
- One API call — get colors, typography, logos, and design system data as structured JSON
- Framework detection — identifies Tailwind, Bootstrap, Material UI, and other CSS frameworks
- Brand personality — extracts tone, energy level, and target audience automatically
- Python and JavaScript — full SDK examples plus cURL for quick testing
- Competitive analysis — compare brand identities across multiple websites programmatically
You're redesigning your product. Or building a competitive analysis deck. Or onboarding a new client.
You need their brand colors, fonts, and logo. Right now.
So you open DevTools, dig through CSS variables, screenshot the logo, squint at hex codes, and copy font names from computed styles.
30 minutes later, you have a messy text file with half the data you need.
There's a better way. One API call. Structured JSON. Every brand element extracted automatically.
This tutorial shows you how to use ScrapeGraphAI's branding endpoint to extract a complete visual identity from any website — colors, typography, logos, design system, and even brand personality — in seconds.
What the Branding API Extracts
Before we write any code, here's exactly what you get back from a single API call:
| Category | Data Points |
|---|---|
| Colors | Primary, accent, background, text, and link colors |
| Typography | Primary font, heading font, monospace font (with fallbacks), and sizes (h1, h2, body) |
| Images | Logo URL, favicon URL, Open Graph image URL |
| Design System | Color scheme (light/dark), base spacing unit, border radius |
| Framework Hints | Detected CSS frameworks (Tailwind, Bootstrap, Material UI, Chakra UI, Ant Design) |
| Personality | Brand tone, energy level (high/medium/low), target audience |
| Metadata | Page title, description, language, theme color, Open Graph data |
| Confidence | A score indicating extraction reliability |
All of this comes from a single POST request with format: "branding".
Quick Start
Prerequisites
You need a ScrapeGraphAI API key. Sign up for free — 50 credits, no credit card required.
Python
import requests
response = requests.post(
"https://v2-api.scrapegraphai.com/api/scrape",
headers={
"SGAI-APIKEY": "YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"url": "https://stripe.com",
"format": "branding"
}
)
data = response.json()
branding = data["branding"]
print(f"Primary color: {branding['colors']['primary']}")
print(f"Heading font: {branding['typography']['heading']['family']}")
print(f"Logo: {branding['images']['logo']}")
print(f"Tone: {branding['personality']['tone']}")JavaScript / TypeScript
const response = await fetch("https://v2-api.scrapegraphai.com/api/scrape", {
method: "POST",
headers: {
"SGAI-APIKEY": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://stripe.com",
format: "branding",
}),
})
const data = await response.json()
const { branding } = data
console.log(`Primary color: ${branding.colors.primary}`)
console.log(`Heading font: ${branding.typography.heading.family}`)
console.log(`Logo: ${branding.images.logo}`)
console.log(`Tone: ${branding.personality.tone}`)cURL
curl -X POST https://v2-api.scrapegraphai.com/api/scrape \
-H "SGAI-APIKEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://stripe.com", "format": "branding"}'Understanding the Response
Here's what a full branding response looks like:
{
"format": "branding",
"branding": {
"colorScheme": "light",
"colors": {
"primary": "#635BFF",
"accent": "#0A2540",
"background": "#FFFFFF",
"textPrimary": "#0A2540",
"link": "#635BFF"
},
"typography": {
"primary": {
"family": "Söhne",
"fallback": "sans-serif"
},
"heading": {
"family": "Söhne",
"fallback": "sans-serif"
},
"mono": {
"family": "Söhne Mono",
"fallback": "monospace"
},
"sizes": {
"h1": "64px",
"h2": "40px",
"body": "17px"
}
},
"images": {
"logo": "https://stripe.com/img/v3/home/twitter.png",
"favicon": "https://stripe.com/favicon.ico",
"ogImage": "https://stripe.com/img/v3/home/twitter.png"
},
"spacing": {
"baseUnit": 4,
"borderRadius": "8px"
},
"frameworkHints": [],
"personality": {
"tone": "professional",
"energy": "medium",
"targetAudience": "developers and businesses"
},
"confidence": 0.85
},
"metadata": {
"provider": "direct",
"contentType": "text/html",
"branding": {
"title": "Stripe | Financial Infrastructure for the Internet",
"description": "Stripe powers online and in-person payment processing...",
"favicon": "https://stripe.com/favicon.ico",
"language": "en",
"themeColor": "#635BFF",
"ogTitle": "Stripe | Financial Infrastructure for the Internet",
"ogDescription": "Stripe powers online and in-person payment processing...",
"ogImage": "https://stripe.com/img/v3/home/twitter.png",
"ogUrl": "https://stripe.com"
}
}
}Let's break down each section.
Colors
{
"primary": "#635BFF",
"accent": "#0A2540",
"background": "#FFFFFF",
"textPrimary": "#0A2540",
"link": "#635BFF"
}The API extracts the primary brand color using a multi-signal consensus algorithm:
- Theme color meta tag — highest priority signal
- Declarative colors —
msapplication-TileColor, mask-icon colors - CSS variables — variables matching patterns like
--primary,--brand-color,--accent - CTA button colors — background colors on buttons and call-to-action elements
- CSS frequency analysis — the most-used saturated color in stylesheets
- Logo SVG colors — fill colors from inline SVG logos
- AI consensus — an LLM analyzes the page content and CSS classes to identify the brand color
These signals are clustered by visual similarity, and the final primary color is chosen by cross-referencing multiple independent sources. If the theme-color meta tag agrees with the CTA button color, that's a strong consensus.
The remaining colors (accent, background, text, link) are extracted by a separate design system model that analyzes the full page structure.
Typography
{
"primary": { "family": "Söhne", "fallback": "sans-serif" },
"heading": { "family": "Söhne", "fallback": "sans-serif" },
"mono": { "family": "Söhne Mono", "fallback": "monospace" },
"sizes": { "h1": "64px", "h2": "40px", "body": "17px" }
}Three font categories are extracted:
- Primary — the main body text font
- Heading — the font used for headings (often the same as primary)
- Mono — the monospace font used for code or system text
Each includes a fallback value. Font sizes are extracted for h1, h2, and body elements.
Images
{
"logo": "https://stripe.com/img/v3/home/twitter.png",
"favicon": "https://stripe.com/favicon.ico",
"ogImage": "https://stripe.com/img/v3/home/twitter.png"
}The API finds the logo by searching <header> and <nav> images, elements with logo in their class/ID/alt text. The favicon is resolved from <link> tags (preferring apple-touch-icon and high-resolution variants). The OG image comes from the og:image meta tag.
All URLs are returned as absolute paths — no relative URL resolution needed on your end.
Framework Detection
{
"frameworkHints": ["tailwind"]
}The API detects CSS frameworks by analyzing class naming patterns in the HTML:
| Framework | Detection Pattern |
|---|---|
| Tailwind CSS | sm:, md:, lg:, utility classes like flex, px-4, rounded |
| Bootstrap | col-, row-, btn-, container, navbar |
| Material UI | MuiButton, MuiCard, css- prefix |
| Chakra UI | chakra- prefix |
| Ant Design | ant- prefix |
This is useful for understanding how a competitor's site is built, or for matching your implementation approach to theirs.
Brand Personality
{
"tone": "professional",
"energy": "medium",
"targetAudience": "developers and businesses"
}An AI model analyzes the page content, layout, and visual design to assess:
- Tone — the overall voice (professional, playful, minimal, bold, etc.)
- Energy — visual intensity level (
high,medium, orlow) - Target audience — who the website is designed for
This is subjective by nature, but it's consistent enough to compare across competitors and track changes over time.
Confidence Score
{
"confidence": 0.85
}A number between 0 and 1 indicating how reliable the extraction is. Higher confidence means more signals agreed on the extracted values. A score below 0.3 suggests the site has minimal styling or non-standard CSS that made extraction harder.
Practical Use Cases
1. Competitive Brand Audit
Compare the visual identity of your top competitors in a single script:
import requests
import json
API_KEY = "YOUR_API_KEY"
competitors = {
"Stripe": "https://stripe.com",
"Square": "https://squareup.com",
"PayPal": "https://paypal.com",
"Adyen": "https://adyen.com",
}
results = {}
for name, url in competitors.items():
response = requests.post(
"https://v2-api.scrapegraphai.com/api/scrape",
headers={"SGAI-APIKEY": API_KEY, "Content-Type": "application/json"},
json={"url": url, "format": "branding"}
)
results[name] = response.json()["branding"]
# Compare primary colors
for name, brand in results.items():
colors = brand["colors"]
fonts = brand["typography"]["primary"]["family"]
tone = brand["personality"]["tone"]
print(f"{name}: {colors['primary']} | {fonts} | {tone}")Output:
Stripe: #635BFF | Söhne | professional
Square: #006AFF | Square | clean
PayPal: #003087 | PayPal Sans | trustworthy
Adyen: #0ABF53 | Inter | modern
In 10 lines of code, you have a competitive brand landscape.
2. Brand Consistency Checker
Verify that all your properties use the same brand identity:
properties = [
"https://yourbrand.com",
"https://app.yourbrand.com",
"https://docs.yourbrand.com",
"https://blog.yourbrand.com",
]
brands = {}
for url in properties:
response = requests.post(
"https://v2-api.scrapegraphai.com/api/scrape",
headers={"SGAI-APIKEY": API_KEY, "Content-Type": "application/json"},
json={"url": url, "format": "branding"}
)
brands[url] = response.json()["branding"]
# Check color consistency
reference = brands[properties[0]]["colors"]["primary"]
for url, brand in brands.items():
color = brand["colors"]["primary"]
match = "OK" if color == reference else "MISMATCH"
print(f"[{match}] {url}: {color}")Run this weekly to catch brand drift before it becomes a problem.
3. Client Onboarding for Agencies
When onboarding a new client, extract their brand kit automatically:
response = requests.post(
"https://v2-api.scrapegraphai.com/api/scrape",
headers={"SGAI-APIKEY": API_KEY, "Content-Type": "application/json"},
json={"url": "https://newclient.com", "format": "branding"}
)
brand = response.json()["branding"]
meta = response.json()["metadata"]["branding"]
print("=== BRAND KIT ===")
print(f"Company: {meta['title']}")
print(f"Description: {meta['description']}")
print(f"\nColor Scheme: {brand['colorScheme']}")
print(f"Primary: {brand['colors']['primary']}")
print(f"Accent: {brand['colors']['accent']}")
print(f"Background: {brand['colors']['background']}")
print(f"\nPrimary Font: {brand['typography']['primary']['family']}")
print(f"Heading Font: {brand['typography']['heading']['family']}")
print(f"\nLogo: {brand['images']['logo']}")
print(f"Favicon: {brand['images']['favicon']}")
print(f"OG Image: {brand['images']['ogImage']}")
print(f"\nTone: {brand['personality']['tone']}")
print(f"Energy: {brand['personality']['energy']}")
print(f"Target Audience: {brand['personality']['targetAudience']}")
print(f"\nFrameworks: {', '.join(brand['frameworkHints']) or 'None detected'}")
print(f"Confidence: {brand['confidence']}")No more asking clients for brand guidelines PDFs. Extract the data directly from their live website.
4. Design System Migration
Moving from one CSS framework to another? Extract the current design tokens first:
response = requests.post(
"https://v2-api.scrapegraphai.com/api/scrape",
headers={"SGAI-APIKEY": API_KEY, "Content-Type": "application/json"},
json={"url": "https://your-app.com", "format": "branding"}
)
brand = response.json()["branding"]
# Generate Tailwind CSS config from extracted values
tailwind_config = {
"theme": {
"extend": {
"colors": {
"primary": brand["colors"]["primary"],
"accent": brand["colors"]["accent"],
"background": brand["colors"]["background"],
},
"fontFamily": {
"sans": [brand["typography"]["primary"]["family"], brand["typography"]["primary"]["fallback"]],
"heading": [brand["typography"]["heading"]["family"], brand["typography"]["heading"]["fallback"]],
"mono": [brand["typography"]["mono"]["family"], brand["typography"]["mono"]["fallback"]],
},
"borderRadius": {
"DEFAULT": brand["spacing"]["borderRadius"],
}
}
}
}
import json
print(json.dumps(tailwind_config, indent=2))This generates a ready-to-use Tailwind config from any live website.
5. Brand Change Monitoring
Track when competitors update their visual identity:
import json
from datetime import datetime
def snapshot_brand(url):
response = requests.post(
"https://v2-api.scrapegraphai.com/api/scrape",
headers={"SGAI-APIKEY": API_KEY, "Content-Type": "application/json"},
json={"url": url, "format": "branding"}
)
return response.json()["branding"]
def compare_brands(old, new):
changes = []
if old["colors"]["primary"] != new["colors"]["primary"]:
changes.append(f"Primary color: {old['colors']['primary']} → {new['colors']['primary']}")
if old["typography"]["primary"]["family"] != new["typography"]["primary"]["family"]:
changes.append(f"Font: {old['typography']['primary']['family']} → {new['typography']['primary']['family']}")
if old["colorScheme"] != new["colorScheme"]:
changes.append(f"Color scheme: {old['colorScheme']} → {new['colorScheme']}")
return changes
# Run daily — compare against yesterday's snapshot
current = snapshot_brand("https://competitor.com")
# Load previous snapshot (from file, database, etc.)
with open("competitor_brand.json", "r") as f:
previous = json.load(f)
changes = compare_brands(previous, current)
if changes:
print(f"Brand changes detected on {datetime.now().date()}:")
for change in changes:
print(f" - {change}")
# Save current snapshot
with open("competitor_brand.json", "w") as f:
json.dump(current, f)Schedule this daily with cron, GitHub Actions, or any job runner. Get notified the moment a competitor rebrands.
How the Branding Extraction Works Under the Hood
The branding endpoint isn't just reading meta tags. It runs a multi-layer extraction pipeline:
Layer 1: HTML Parsing
The raw HTML is parsed to extract structured signals:
- Meta tags —
theme-color,og:image,og:title, favicons - Images — logo detection from
<header>,<nav>, and elements withlogoclass/alt - Framework detection — CSS class pattern matching
Layer 2: Color Extraction (Consensus Algorithm)
This is the most sophisticated part. The API doesn't just pick the first color it finds. It gathers nominations from 7 independent sources:
- Theme-color meta tag
- Declarative meta colors (msapplication-TileColor, mask-icon)
- CSS custom properties matching brand patterns (
--primary,--brand-color) - CTA button background colors
- Most frequent saturated colors in CSS
- SVG logo fill colors
- AI model analysis of the page
Each nomination is clustered by visual similarity (Euclidean distance in RGB space). Colors that are near-white, near-black, or desaturated are filtered out. The winning cluster is chosen by:
- Category diversity — a color appearing in CSS vars AND CTA buttons AND the logo is more likely to be the brand color
- Nomination count — more independent sources = higher confidence
- Saturation — tiebreaker favoring more vibrant colors
If the theme-color meta tag exists and matches other signals, it wins immediately. Otherwise, the consensus algorithm resolves the best candidate.
Layer 3: Design System Extraction (AI Models)
A trimmed version of the HTML (stripped of scripts, iframes, and non-essential attributes) is sent to AI models that extract:
- Typography (font families, sizes)
- Spacing (base unit, border radius)
- Color scheme (light vs dark)
- Brand personality (tone, energy, audience)
The API uses multiple LLM providers for redundancy and runs the primary color extraction and design system extraction in parallel for speed.
Tips for Best Results
High confidence results:
- Websites with
theme-colormeta tags get the most accurate primary color extraction - Sites using CSS custom properties (variables) provide clean typography and color data
- Well-structured HTML with semantic elements (
<header>,<nav>,<main>) improves logo detection
Lower confidence results:
- Single-page apps with minimal server-rendered HTML
- Websites that load all styles dynamically via JavaScript
- Sites with no semantic HTML structure
Improving accuracy:
- If the confidence score is below 0.3, the site likely has non-standard CSS or minimal styling
- Cross-reference the extracted primary color with the
metadata.branding.themeColorfield — if both agree, the result is very reliable - For SPAs, the API still fetches the fully rendered page (JavaScript execution included)
API Reference
Request
POST https://v2-api.scrapegraphai.com/api/scrape
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | The URL to extract branding from |
format |
string | Yes | Must be "branding" |
Response
| Field | Type | Description |
|---|---|---|
format |
"branding" |
Always "branding" |
branding.colorScheme |
"light" | "dark" |
Detected color scheme |
branding.colors.primary |
string | Primary brand color (hex) |
branding.colors.accent |
string | Accent color (hex) |
branding.colors.background |
string | Background color (hex) |
branding.colors.textPrimary |
string | Primary text color (hex) |
branding.colors.link |
string | Link color (hex) |
branding.typography.primary |
object | { family, fallback } |
branding.typography.heading |
object | { family, fallback } |
branding.typography.mono |
object | { family, fallback } |
branding.typography.sizes |
object | { h1, h2, body } in px |
branding.images.logo |
string | Logo URL |
branding.images.favicon |
string | Favicon URL |
branding.images.ogImage |
string | Open Graph image URL |
branding.spacing.baseUnit |
number | Base spacing unit in px |
branding.spacing.borderRadius |
string | Default border radius |
branding.frameworkHints |
string[] | Detected CSS frameworks |
branding.personality.tone |
string | Brand tone |
branding.personality.energy |
"high" | "medium" | "low" |
Visual energy level |
branding.personality.targetAudience |
string | Detected target audience |
branding.confidence |
number | Extraction confidence (0-1) |
metadata.branding.title |
string | Page title |
metadata.branding.description |
string | Meta description |
metadata.branding.language |
string | Page language |
metadata.branding.themeColor |
string | Theme color meta tag |
metadata.branding.ogTitle |
string | Open Graph title |
metadata.branding.ogDescription |
string | Open Graph description |
metadata.branding.ogImage |
string | Open Graph image |
metadata.branding.ogUrl |
string | Open Graph URL |
Pricing
The branding endpoint uses the same credit system as all ScrapeGraphAI endpoints:
| Plan | Price | Credits/month |
|---|---|---|
| Free | $0 | 50 |
| Starter | $20/month | 5,000 |
| Growth | $100/month | 40,000 |
| Pro | $500/month | 250,000 |
| Enterprise | Custom | Custom |
Each branding extraction costs 1 credit. That means even the free tier lets you extract 50 brand identities per month.
The Bottom Line
Extracting branding data manually is slow, inconsistent, and doesn't scale.
The ScrapeGraphAI branding endpoint automates the entire process. One API call gives you colors, typography, logos, design system data, framework detection, and brand personality — all as structured JSON.
Whether you're running competitive audits, onboarding agency clients, monitoring brand consistency, or migrating design systems, this endpoint replaces hours of manual work with seconds of API time.
Get started for free — 50 credits, no credit card required.
FAQ
How accurate is the color extraction?
The API uses a multi-signal consensus algorithm that cross-references 7 independent sources (meta tags, CSS variables, CTA buttons, logo SVGs, AI analysis, and more). When multiple sources agree, accuracy is very high. The confidence score in the response tells you how reliable the extraction was.
Does it work on single-page apps (SPAs)?
Yes. The API renders JavaScript before extracting, so it sees the fully rendered page — not just the initial HTML. However, SPAs with minimal server-rendered content may produce lower confidence scores.
Can I extract branding from password-protected pages?
The branding endpoint works on publicly accessible URLs. For pages behind authentication, you would need to use the standard scrape endpoint with session cookies or authentication headers.
How is this different from the extract endpoint?
The format: "branding" option on the scrape endpoint is purpose-built for visual identity extraction. It runs specialized algorithms (color consensus, design system analysis, logo detection) that the generic extract endpoint doesn't have. The extract endpoint is better for custom, free-form data extraction using natural language prompts.
What CSS frameworks can it detect?
Currently: Tailwind CSS, Bootstrap, Material UI, Chakra UI, and Ant Design. Detection is based on CSS class naming patterns in the rendered HTML.
Can I use this for brand monitoring at scale?
Yes. Combine the branding endpoint with a scheduler (cron, GitHub Actions, Airflow) to snapshot brand identities daily or weekly. Store the JSON responses and diff them to detect changes automatically.