BrandAttach docs
Three ways to attach a brand: JavaScript, CSS, or REST.
Quickstart
- Create an account and scan a domain.
- Copy your
ba_live_…token from the brand page. - Drop the JavaScript snippet, the CSS link, or call the REST endpoint.
JavaScript snippet
One line. Attaches CSS variables, replaces logos and brand names, exposes window.BrandAttach.
<script src="https://brandattach.com/attach.js" data-brand="ba_live_xxx"></script>
<img data-ba-logo="navbar" alt="Company logo">
<span data-ba-name></span>
<button class="ba-button">Continue</button>The script never stretches images: it sets object-fit: contain; max-width: 100%; height: auto;.
CSS-only integration
For server-rendered apps, link the theme stylesheet and use the CSS variables / utility classes.
<link rel="stylesheet" href="https://brandattach.com/api/brand/ba_live_xxx/theme.css">
<button class="ba-button">Continue</button>
<p style="color: var(--ba-color-primary)">Brand colour</p>Available variables:
--ba-brand-name--ba-color-primary,--ba-color-accent,--ba-color-background,--ba-color-text--ba-font-primary--ba-logo-primary,--ba-logo-login
Helper classes:
.ba-button,.ba-text-primary,.ba-bg-primary.ba-logo-navbar,.ba-logo-footer,.ba-logo-login,.ba-logo-avatar
REST API
GET https://brandattach.com/api/brand/ba_live_xxx
200 OK
{
"id": "brand_...",
"name": "Acme",
"domain": "acme.com",
"logos": {
"logo_horizontal": "https://...",
"logo_icon": "https://..."
},
"colors": {
"primary": "#0057FF",
"accent": "#FFB000",
"background": "#FFFFFF",
"text": "#101828"
},
"fonts": {
"primary": "Inter",
"fallback": "system-ui, sans-serif"
},
"placements": {
"navbar": { "url": "https://...", "fit": "contain", "theme": "auto" },
"login": { "url": "https://...", "fit": "contain", "theme": "auto" },
"avatar": { "url": "https://...", "fit": "contain", "theme": "auto" }
},
"css": "https://brandattach.com/api/brand/ba_live_xxx/theme.css"
}All endpoints accept the token as a path parameter and return CORS-friendly responses.
| Method | Path | What it does |
|---|---|---|
| GET | /api/brand/<token> | JSON brand profile |
| GET | /api/brand/<token>/theme.css | CSS variables + helpers |
| GET | /api/brand/<token>/logo?slot=… | Best logo for a slot |
| GET | /attach.js | Drop-in JS snippet |
Logo slots
BrandAttach classifies every logo by shape and serves the right one for each UI slot — aspect ratio is always preserved.
| Slot | Ideal shape | Used in |
|---|---|---|
| navbar | horizontal | Site header, app top bar |
| footer | horizontal | Page footer |
| login | horizontal or square | Login / signup cards |
| avatar | icon / square | Profile chip, badge |
| favicon | icon | Browser tab |
| horizontal | Transactional email header | |
| app_icon | icon / square | PWA, mobile shortcut |
| card | horizontal or square | Marketing cards, hero |
<img data-ba-logo="navbar" alt="Company logo">
<img data-ba-logo="avatar" alt="Company icon">GET https://brandattach.com/api/brand/ba_live_xxx/logo?slot=navbar&theme=auto
→ 302 Redirect to the processed image URL (or original SVG)If the ideal shape isn't available, BrandAttach falls back to the closest match and flags it as a fallback in the dashboard.
React example
// React (placeholder pattern — fetch and render)
import { useEffect, useState } from "react";
export function useBrand(token: string) {
const [brand, setBrand] = useState<any>(null);
useEffect(() => {
fetch(`https://brandattach.com/api/brand/${token}`).then(r => r.json()).then(setBrand);
}, [token]);
return brand;
}Token security
- Tokens are public — they grant read-only access to the brand profile and are intended to be embedded in frontends.
- Raw tokens are shown only once at creation time. We store a SHA-256 hash; we cannot recover lost tokens.
- Revoke any token at any time from the dashboard.
- Token format:
ba_live_+ random base64url (32 characters total).
Domain scanning
- Scans are SSRF-safe: private IPs, loopback, link-local, and non-HTTP(S) URLs are blocked.
- Requests are bounded by timeout (≤9s), response size (≤2MB), and a small redirect cap.
- If a scan fails or detection is poor, fill in the brand manually — every field is editable.