Brands
List, create, update, and extract brands. Every brand carries a kernel with logos for light and dark backgrounds, contrast-safe palettes, type, surfaces, voice, and imagery.
Base URL: https://heydecks.com
All endpoints require Authorization: Bearer hd_live_….
#The brand kernel
Every brand object includes a kernel: the single source of truth for how decks in that brand look and sound. The older top-level fields (colors, typography, logos, tone, style) are still returned and accepted, and they always agree with the kernel.
{
"version": 2,
"identity": { "name": "Acme", "website": "https://acme.com", "tagline": "Numbers people trust." },
"logos": {
"primary": {
"on_light": { "url": "https://heydecks.com/api/uploads/brands/brand_xyz/primary-on-light-3f2a9c1e0b7d4a55.svg", "format": "svg", "luminance": 0.01 },
"on_dark": { "url": "https://heydecks.com/api/uploads/brands/brand_xyz/primary-on-dark-9a8b7c6d5e4f3a2b.svg", "format": "svg", "luminance": 1 }
},
"mark": { "on_light": { "url": "…", "format": "png" } },
"placement": "top-right",
"size": "medium"
},
"palette": {
"accent": "#1b40f2",
"light": { "background": "#ffffff", "surface": "#eff3fd", "foreground": "#111622", "muted": "#6a6e77", "line": "#d9dee8", "accent_foreground": "#ffffff" },
"dark": { "background": "#111622", "surface": "#20242e", "foreground": "#ffffff", "muted": "#a0a2a8", "line": "#333843", "accent_foreground": "#ffffff" },
"series": ["#1b40f2", "#af5a00", "#8b1592", "#6a7f00", "#006566"],
"locked": []
},
"typography": { "heading": "Inter", "body": "Inter", "mono": "Geist Mono", "heading_weight": 500, "scale": "regular" },
"shape": { "radius": 12, "stroke": 1, "cards": "flat" },
"surfaces": { "allowed": ["light", "subtle", "dark", "accent"], "mode": "light", "texture": "none" },
"voice": { "tone": "Confident, plain, specific.", "audience": "Finance leaders", "avoid": ["synergy"] },
"imagery": { "style": "photographic", "mood": "Calm daylight" }
}What the fields do:
- Logos.
on_lightis the artwork for light backgrounds,on_darkfor dark ones. Slides pick the right one for each surface. If one is missing, the other is recolored to solid black or white, but only where it would not read as is.markis an optional compact symbol. - Palette. One
accentis enough: the light and dark palettes and the chartseriesare derived from it, and every text pair passes WCAG AA on every surface. Set a palette token yourself and add its id (for example"light.muted") tolockedto keep it when the accent changes. - Surfaces.
allowedlists the slide surfaces decks may use; a slide asking for a disabled one renders on the closest allowed one.mode: "dark"puts the dark palette on the canvas. - Voice and imagery. AI drafts follow
voice(and never write anything inavoid); image generation followsimagery.
Enumerations: placement is top-right, top-left, bottom-right, or none. size is small, medium, or large. scale is compact, regular, or expressive. heading_weight is 400 or 500. radius is 0 to 28. stroke is 1 or 1.5. cards is flat or outlined. texture is none, grid, or dots. imagery.style is photographic, illustration, 3d, or abstract.
#GET /v1/brands
List all brands in your workspace.
curl https://heydecks.com/v1/brands \
-H "Authorization: Bearer hd_live_…"200 Response: an array of brand objects.
[
{
"id": "brand_xyz",
"name": "Acme",
"is_active": true,
"colors": { "background": "#ffffff", "foreground": "#111622", "muted": "#6a6e77", "subtle": "#eff3fd", "accent": "#1b40f2", "line": "#d9dee8" },
"typography": { "heading_font": "Inter", "body_font": "Inter", "mono_font": "Geist Mono" },
"logos": { "wordmark": "https://heydecks.com/api/uploads/brands/brand_xyz/primary-on-light-3f2a9c1e0b7d4a55.svg", "mark": "A" },
"tone": "Confident, plain, specific.",
"style": { "radius": 12, "stroke_width": 1, "card_style": "flat", "display_scale": 1, "heading_weight": 500, "heading_tracking": -0.03, "heading_case": "none", "background": "flat" },
"kernel": { "version": 2, "…": "…" }
}
]The brand with is_active: true is the workspace default. It is applied automatically when brand_id is omitted from POST /v1/generate.
#GET /v1/brands/{id}
Fetch one brand. Same shape as a list item. 404 not_found when the brand is not in your workspace.
#POST /v1/brands
Create a brand. Anything you leave out is seeded from the workspace's active brand.
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Brand display name. |
kernel | object | No | A partial kernel (snake_case or camelCase). Merged over the seed; only the fields you send change. |
logo_on_light | string | No | Logo for light backgrounds: an https:// URL or a data:image/… URL. |
logo_on_dark | string | No | Logo for dark backgrounds. |
mark_on_light | string | No | Compact symbol for light backgrounds. |
mark_on_dark | string | No | Compact symbol for dark backgrounds. |
colors, typography, tone, style | object / string | No | The older fields, still accepted. Kernel fields win where they overlap. |
curl -X POST https://heydecks.com/v1/brands \
-H "Authorization: Bearer hd_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme",
"kernel": {
"palette": { "accent": "#E2572B" },
"typography": { "heading": "Fraunces", "body": "Inter" },
"voice": { "tone": "Warm and direct", "avoid": ["synergy"] }
},
"logo_on_light": "https://acme.com/logo.svg",
"logo_on_dark": "https://acme.com/logo-white.svg"
}'201 Response: the created brand object. Uploaded data URLs are stored and returned as hosted https://heydecks.com/api/uploads/brands/… URLs.
#PATCH /v1/brands/{id}
Update a brand. Send only what changes. The older fields apply first, then kernel fields on top. Set a logo field to null to remove that variant.
curl -X PATCH https://heydecks.com/v1/brands/brand_xyz \
-H "Authorization: Bearer hd_live_…" \
-H "Content-Type: application/json" \
-d '{
"kernel": { "palette": { "accent": "#00A36C" }, "surfaces": { "mode": "dark" } },
"logo_on_dark": "https://acme.com/logo-white.svg"
}'Changing only palette.accent re-derives every unlocked palette token and the chart series. 200 Response: the updated brand object.
#POST /v1/brands/extract
Read a public website and return a brand ready to review. The page is loaded twice (light and dark color scheme), its real CSS colors, fonts, and header logo are measured, and one vision model reconciles them with screenshots to fill in the name, tagline, tone, audience, and image style, with a confidence per field.
Costs 50 credits. Refunded on failure. Nothing is saved.
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Public https:// URL to analyse. |
curl -X POST https://heydecks.com/v1/brands/extract \
-H "Authorization: Bearer hd_live_…" \
-H "Content-Type: application/json" \
-d '{"url": "https://acme.com"}'200 Response: the same shape POST /v1/brands accepts (name, colors, typography, logos, tone, style, kernel), plus review:
{
"name": "Acme",
"kernel": { "version": 2, "…": "…" },
"review": {
"url": "https://acme.com/",
"confidence": { "name": 0.95, "logo": 0.85, "palette": 0.9, "fonts": 0.8, "tone": 0.6, "imagery": 0.4 },
"has_dark_theme": true,
"declared_fonts": ["Inter"]
}
}To save it, post the result straight back: POST /v1/brands with {"name": …, "kernel": …}.
#Brand limits by plan
| Plan | Brands |
|---|---|
| Solo | 3 |
| Pro | 15 |
| Team | Unlimited |
| Enterprise | Unlimited |
Exceeding the limit returns 402 brand_limit. Upgrade to add more brands.