Brandohue API Documentation
Extract logos, favicons, color palettes, and brand metadata from any website with a single API call. Designed for developers who value speed and simplicity.
Authentication
All API requests require authentication via an API key. Include your key in the x-api-key header of every request.
How to get an API key
- Create an account on Brandohue.
- Navigate to the API Keys page in your dashboard.
- Click "Create API Key" and give it a name.
- Copy your key and store it securely — it won't be shown again.
x-api-key: br_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Extract Endpoint
/api/v1/extractThe extract endpoint analyzes a website and returns structured brand data including logos, favicons, color palettes, Open Graph metadata, and more. Colors are extracted from multiple sources (HTML, CSS, JavaScript, logo images, and screenshots) and grouped by color family with named identifiers. Each request costs 1 credit.
https://api.brandohue.comRequest Parameters
The request body must be application/json.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| url | string | Yes | — | The URL of the website to extract brand data from. Must include http:// or https://. |
| useCache | boolean | No | false | When true, returns cached results if available (within 24 hours). Cached responses cost 0 credits. |
| extractLogoColors | boolean | No | true | Extract dominant colors from the site's logo image. |
| logoColorsLimit | number | No | 6 | Maximum number of logo colors to extract. Must be between 2 and 12. |
| extractScreenshotColors | boolean | No | true | Extract colors from a full-page screenshot of the website. |
| screenshotColorsLimit | number | No | 12 | Maximum number of screenshot colors to extract. Must be between 2 and 12. |
| extractHtmlColors | boolean | No | true | Extract colors directly from the HTML markup (inline styles, attributes). |
| extractCssColors | boolean | No | true | Extract colors from CSS stylesheets and style tags. |
| extractJsColors | boolean | No | false | Extract colors from JavaScript files and inline scripts. |
| hexColor | boolean | No | false | When true, force hex color format in the response. |
Success Response
A successful extraction returns the brand data along with billing information. The response includes detailed color analysis grouped by source and color family.
data
The extracted brand information:
- siteName — Domain name of the analyzed site
- logoUrl — URL of the detected logo (SVG prioritized)
- faviconUrl — URL of the favicon
- colors — Array of extracted brand colors (hex)
- title — Page title or Open Graph title
- description — Meta or Open Graph description
- nearestColors — Colors grouped by name (e.g. black, dodgerblue, crimson) with identifiers
- visualPalette — Colors organized by source: Logo, Homepage, HTML, CSS, and JavaScript
- screenshot — Base64-encoded screenshot of the page (null if disabled)
billing
- cost — Credits consumed (1 per extraction)
- newBalance — Remaining credits after deduction
- message — Human-readable billing summary
{
"data": {
"siteName": "Instagram",
"logoUrl": null,
"faviconUrl": "https://static.cdninstagram.com/rsrc.php/yr/r/rzWiSjZRxk5.webp",
"colors": ["#000000", "#060606", "#080809", "#0B0B0B", "#001912", ...],
"title": "Instagram",
"description": null,
"nearestColors": {
"black": [
{ "color": "#000000", "group": "black", "name": "black-100" },
{ "color": "#060606", "group": "black", "name": "black-200" }
],
"dodgerblue": [
{ "color": "#0095F6", "group": "dodgerblue", "name": "dodgerblue-1000" },
{ "color": "#1877F2", "group": "dodgerblue", "name": "dodgerblue-1300" }
],
...
},
"visualPalette": {
"Logo Colors": [],
"Homepage Colors": [],
"HTML Colors": [
{ "color": "#000000", "name": "black" },
{ "color": "#0095F6", "name": "dodgerblue" },
...
],
"CSS Colors": [
{ "color": "#0095F6", "name": "dodgerblue" },
...
],
"JavaScript Colors": []
},
"screenshot": null
},
"billing": {
"cost": 1,
"newBalance": 44,
"message": "Successful call! 1 credit(s) charged."
}
}Cached Response
When useCache: true is set and a cached result exists within the last 24 hours, the API returns the cached data without deducting any credits. The billing response includes a cached: true flag.
{
"data": {
"siteName": "Instagram",
"logoUrl": null,
"faviconUrl": "https://static.cdninstagram.com/rsrc.php/yr/r/rzWiSjZRxk5.webp",
"colors": ["#000000", "#060606", "#080809", ...],
"title": "Instagram",
"description": null,
"nearestColors": { ... },
"visualPalette": { ... },
"screenshot": null
},
"billing": {
"cost": 0,
"newBalance": 100,
"message": "Data retrieved from cache. No credits were deducted.",
"cached": true
}
}Cache entries expire after 24 hours. The same URL extracted within that window with useCache: true will return a free cached result.
Error Responses
All error responses follow the same structure, with an error message and an optional detail field.
The URL field is missing, the provided URL is invalid, or the limit parameters are out of range.
{
"error": "The \"url\" field is required."
}
// or
{
"error": "Invalid URL. Provide a URL with http or https protocol."
}
// or
{
"error": "logoColorsLimit and screenshotColorsLimit must be between 2 and 12."
}Your account doesn't have enough credits to complete the request. You'll receive an email notification.
{
"error": "Payment Required. Insufficient credits.",
"details": "Your current balance is 0 credits. This call costs 1 credit."
}The extraction took too long. This usually happens when the target website blocks the request or is unreachable.
{
"error": "Could not extract data from the provided URL.",
"detail": "Timeout exceeded"
}The extraction failed due to the website being inaccessible or returning unexpected content.
{
"error": "Could not extract data from the provided URL.",
"detail": "Failed to fetch page content"
}Status Codes
| Status | Meaning | Description |
|---|---|---|
| 200 | OK | Extraction completed successfully. Data returned with billing info. |
| 400 | Bad Request | Missing or invalid url parameter, or limit values out of range. |
| 402 | Payment Required | Insufficient credits. Purchase more in the billing page. |
| 408 | Timeout | Extraction exceeded the time limit. Target website may be unreachable. |
| 422 | Unprocessable | Extraction failed. The website might block requests or return invalid content. |
Code Examples
Ready-to-use examples for common languages and HTTP clients. Replace YOUR_API_KEY with your actual API key.
cURL
curl -X POST https://api.brandohue.com/api/v1/extract \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://stripe.com"}'
# With caching enabled
curl -X POST https://api.brandohue.com/api/v1/extract \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://stripe.com", "useCache": true}'
# Custom color extraction options
curl -X POST https://api.brandohue.com/api/v1/extract \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://stripe.com",
"extractLogoColors": true,
"logoColorsLimit": 8,
"extractScreenshotColors": true,
"screenshotColorsLimit": 10,
"extractHtmlColors": true,
"extractCssColors": true,
"extractJsColors": false,
"hexColor": false
}'JavaScript (fetch)
const response = await fetch(
'https://api.brandohue.com/api/v1/extract',
{
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://stripe.com',
useCache: false,
extractLogoColors: true,
logoColorsLimit: 6,
extractScreenshotColors: true,
screenshotColorsLimit: 12,
extractHtmlColors: true,
extractCssColors: true,
extractJsColors: false,
hexColor: false,
}),
}
);
const result = await response.json();
if (response.ok) {
console.log('Logo:', result.data.logoUrl);
console.log('Colors:', result.data.colors);
console.log('Nearest colors:', result.data.nearestColors);
console.log('Visual palette:', result.data.visualPalette);
console.log('Credits left:', result.billing.newBalance);
} else {
console.error('Error:', result.error);
}Python (requests)
import requests
response = requests.post(
'https://api.brandohue.com/api/v1/extract',
headers={
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
json={
'url': 'https://stripe.com',
'useCache': False,
'extractLogoColors': True,
'logoColorsLimit': 6,
'extractScreenshotColors': True,
'screenshotColorsLimit': 12,
'extractHtmlColors': True,
'extractCssColors': True,
'extractJsColors': False,
'hexColor': False,
},
)
data = response.json()
if response.status_code == 200:
print(f"Logo: {data['data']['logoUrl']}")
print(f"Colors: {data['data']['colors']}")
print(f"Nearest colors: {data['data']['nearestColors']}")
print(f"Visual palette: {data['data']['visualPalette']}")
print(f"Credits left: {data['billing']['newBalance']}")
else:
print(f"Error: {data['error']}")Node.js (axios)
const axios = require('axios');
async function extractBrand(url) {
try {
const { data } = await axios.post(
'https://api.brandohue.com/api/v1/extract',
{
url,
extractLogoColors: true,
logoColorsLimit: 6,
extractScreenshotColors: true,
screenshotColorsLimit: 12,
extractHtmlColors: true,
extractCssColors: true,
extractJsColors: false,
},
{
headers: {
'x-api-key': process.env.BRANDOHUE_API_KEY,
'Content-Type': 'application/json',
},
}
);
console.log(data.data.colors);
console.log(data.data.nearestColors);
console.log(data.data.visualPalette);
return data;
} catch (error) {
if (error.response?.status === 402) {
console.error('Insufficient credits');
}
throw error;
}
}
extractBrand('https://stripe.com');