The Yoku CDN endpoint provides direct, cacheable access to brand assets (logos, icons, symbols) without requiring authentication. It's designed for high-performance, client-side rendering with intelligent fallbacks and on-demand asset discovery.
Unlike the authenticated REST API, the CDN endpoint is optimized for:
<img> tagshttps://cdn.yoku.app/
The CDN endpoint uses a path-based parameter system for maximum cacheability:
https://cdn.yoku.app/{identifierType}/{identifier}/{param}/{value}/{param}/{value}...
<!-- Simplest form: just the domain -->
<img src="https://cdn.yoku.app/stripe.com" />
<!-- Explicit identifier type -->
<img src="https://cdn.yoku.app/domain/stripe.com" />
<!-- Stock ticker -->
<img src="https://cdn.yoku.app/ticker/AAPL" />
<!-- Company name -->
<img src="https://cdn.yoku.app/company_name/Salesforce" />
The CDN supports multiple identifier types to resolve brands:
| Type | Format | Example | Use Case |
|---|---|---|---|
domain | Domain name | stripe.com | Web companies, SaaS platforms |
ticker | Stock ticker symbol | AAPL | Financial applications |
isin | ISIN code | US0378331005 | International securities |
company_name | Company legal name | Salesforce | Generic company lookup |
id | Yoku internal brand ID | brand_abc123 | Direct brand reference |
If you omit the identifier type, Yoku defaults to domain resolution:
<!-- These are equivalent -->
<img src="https://cdn.yoku.app/stripe.com" />
<img src="https://cdn.yoku.app/domain/stripe.com" />
All parameters are optional and follow the /{param}/{value} pattern in the URL path.
type - Asset TypeControls which type of brand asset to return.
| Value | Description | Use Case |
|---|---|---|
icon | Square favicon-style icons (default) | Lists, avatars, small icons |
logo | Full horizontal logos with text | Headers, hero sections |
symbol | Brand mark without text (e.g., Nike swoosh) | Compact spaces |
<!-- Icon (default) -->
<img src="https://cdn.yoku.app/stripe.com/type/icon" />
<!-- Logo -->
<img src="https://cdn.yoku.app/stripe.com/type/logo" />
<!-- Symbol -->
<img src="https://cdn.yoku.app/stripe.com/type/symbol" />
theme - Visual ThemeRequest light or dark mode optimized assets.
| Value | Description |
|---|---|
light | Optimized for light backgrounds (default) |
dark | Optimized for dark backgrounds |
<!-- Dark mode logo -->
<img src="https://cdn.yoku.app/stripe.com/theme/dark" />
<!-- Light mode logo -->
<img src="https://cdn.yoku.app/stripe.com/theme/light" />
w - Width (pixels)Maximum width constraint. Image maintains aspect ratio.
<!-- Scale to 128px wide -->
<img src="https://cdn.yoku.app/stripe.com/w/128" />
h - Height (pixels)Maximum height constraint. Image maintains aspect ratio.
<!-- Scale to 64px tall -->
<img src="https://cdn.yoku.app/stripe.com/h/64" />
format - Output FormatConvert image to specific format. Specified via file extension.
| Format | Extension | Use Case |
|---|---|---|
webp | .webp | Modern browsers, best compression |
png | .png | Transparency support, lossless |
jpg | .jpg | Maximum compatibility |
jpeg | .jpeg | Alias for JPG |
<!-- Request as WebP -->
<img src="https://cdn.yoku.app/stripe.com/w/128.webp" />
<!-- Request as PNG -->
<img src="https://cdn.yoku.app/stripe.com/w/128.png" />
fallback - Fallback BehaviorControls what to return when no asset is found.
| Value | Behavior | Cache TTL |
|---|---|---|
lettermark | Generate colored badge with first letter (default) | 5 minutes |
transparent | Return transparent 50x50 PNG | 5 minutes |
404 | HTTP 404 Not Found | 5 minutes |
<!-- Return 404 if not found -->
<img src="https://cdn.yoku.app/unknowncompany.com/fallback/404" />
<!-- Return transparent pixel -->
<img src="https://cdn.yoku.app/unknowncompany.com/fallback/transparent" />
<!-- Generate lettermark (default) -->
<img src="https://cdn.yoku.app/unknowncompany.com/fallback/lettermark" />
When fallback=lettermark (default), Yoku generates a deterministic, visually-appealing letter badge instead of showing broken images.
stripe.com → "Stripe")<!-- Stripe → "S" on purple background -->
<img src="https://cdn.yoku.app/stripe.com/fallback/lettermark" />
<!-- GitHub → "G" on orange background -->
<img src="https://cdn.yoku.app/github.com/fallback/lettermark" />
<!-- Dark theme lettermark -->
<img src="https://cdn.yoku.app/newcompany.com/theme/dark/fallback/lettermark" />
Benefits:
Cache Strategy: Lettermarks are cached for 5 minutes (not forever) so that when real assets are discovered later, they replace the lettermark quickly.
Parameters can be combined freely in any order:
<!-- Complex example: ticker, resized, WebP, dark mode, with fetch -->
<img
src="https://cdn.yoku.app/ticker/NVDA/w/256/h/256/theme/dark/format/webp"
/>
<!-- Logo, light theme, PNG format, lettermark fallback -->
<img
src="https://cdn.yoku.app/domain/salesforce.com/type/logo/theme/light/fallback/lettermark.png"
/>
<!-- 404 fallback (no lettermark) -->
<img src="https://cdn.yoku.app/newstartup.io/fallback/404" />
The CDN uses multi-tier caching for optimal performance:
When assets exist in the database:
Cache-Control: public, max-age=86400, stale-while-revalidate=604800
CDN-Cache-Control: public, max-age=31536000
When returning fallbacks (lettermark, transparent, 404):
Cache-Control: public, max-age=300, stale-while-revalidate=600
CDN-Cache-Control: public, max-age=300
Why short-lived? If asset discovery or enrichment finds real assets later, the fallback is replaced quickly.
Assets include SHA-256 based ETags for conditional requests:
ETag: "abc123def456..."
Subsequent requests with If-None-Match return 304 Not Modified for bandwidth savings.
Show recognizable brands instead of cryptic merchant codes:
<!-- Before: "AMZN*MKTP AMAZON.COM" -->
<!-- After: Amazon logo -->
<img
src="https://cdn.yoku.app/domain/amazon.com/w/32/h/32/type/icon.webp"
alt="Amazon"
/>
Display consistent brand assets across your platform:
<div class="company-grid">
<img src="https://cdn.yoku.app/stripe.com/w/64" />
<img src="https://cdn.yoku.app/salesforce.com/w/64" />
<img src="https://cdn.yoku.app/shopify.com/w/64" />
</div>
Show stock portfolio with logos:
<!-- AAPL -->
<img src="https://cdn.yoku.app/ticker/AAPL/w/48/type/icon" />
<!-- MSFT -->
<img src="https://cdn.yoku.app/ticker/MSFT/w/48/type/icon" />
<!-- GOOGL -->
<img src="https://cdn.yoku.app/ticker/GOOGL/w/48/type/icon" />
Automatically fetch company assets during signup:
<!-- User enters "acme.com" as their company domain -->
<img src="https://cdn.yoku.app/acme.com/w/128/fallback/lettermark" />
If Acme Corp is unknown:
Automatically serve theme-appropriate assets:
// React example
const Logo = ({ domain, darkMode }) => (
<img
src={`https://cdn.yoku.app/${domain}/theme/${darkMode ? "dark" : "light"}/w/200`}
/>
);
Serve optimized sizes for different viewports:
<picture>
<source
media="(min-width: 1200px)"
srcset="https://cdn.yoku.app/stripe.com/w/256.webp"
/>
<source
media="(min-width: 768px)"
srcset="https://cdn.yoku.app/stripe.com/w/128.webp"
/>
<img src="https://cdn.yoku.app/stripe.com/w/64.webp" alt="Stripe" />
</picture>
Prevent layout shift by specifying w or h:
<!-- ✅ Good: Dimensions specified -->
<img src="https://cdn.yoku.app/stripe.com/w/64/h/64" width="64" height="64" />
<!-- ❌ Bad: No dimensions, causes layout shift -->
<img src="https://cdn.yoku.app/stripe.com" />
WebP provides 25-35% better compression than PNG/JPG:
<picture>
<source
type="image/webp"
srcset="https://cdn.yoku.app/stripe.com/w/128.webp"
/>
<img src="https://cdn.yoku.app/stripe.com/w/128.png" alt="Stripe" />
</picture>
Never show broken images in production:
<!-- ✅ Always shows something -->
<img src="https://cdn.yoku.app/anycompany.com/fallback/lettermark" />
<!-- ❌ May show broken image icon -->
<img src="https://cdn.yoku.app/anycompany.com/fallback/404" />
When users provide domains, enable discovery:
// React example: User company signup
const CompanyLogo = ({ userProvidedDomain }) => (
<img
src={`https://cdn.yoku.app/domain/${userProvidedDomain}/w/128`}
alt="Company logo"
/>
);
Use native lazy loading for performance:
<img src="https://cdn.yoku.app/stripe.com/w/128" loading="lazy" alt="Stripe" />
Always include descriptive alt text:
<!-- ✅ Good: Descriptive alt text -->
<img src="https://cdn.yoku.app/stripe.com" alt="Stripe company logo" />
<!-- ❌ Bad: Missing alt text -->
<img src="https://cdn.yoku.app/stripe.com" />
- https://logo.clearbit.com/stripe.com
+ https://cdn.yoku.app/stripe.com
- https://cdn.brandfetch.io/stripe.com/w/400
+ https://cdn.yoku.app/stripe.com/w/400
- https://www.google.com/s2/favicons?domain=stripe.com
+ https://cdn.yoku.app/stripe.com/type/icon
Combine with authenticated API for theming:
// 1. Get brand data via API
const brand = await fetch("https://api.yoku.app/v1/brand?domain=stripe.com", {
headers: { Authorization: "Bearer YOUR_KEY" },
}).then((r) => r.json());
// 2. Use CDN for assets
const logo = `https://cdn.yoku.app/stripe.com/theme/dark`;
// 3. Apply brand colors
<div style={{ backgroundColor: brand.colors.primary }}>
<img src={logo} />
</div>;
Load multiple logos efficiently:
const domains = ["stripe.com", "github.com", "salesforce.com"];
const logos = await Promise.all(
domains.map((domain) =>
fetch(`https://cdn.yoku.app/${domain}/w/128.webp`)
.then((r) => r.blob())
.then((blob) => URL.createObjectURL(blob)),
),
);
import Image from "next/image";
export default function CompanyLogo({ domain }) {
return (
<Image
src={`https://cdn.yoku.app/${domain}/w/256`}
alt={`${domain} logo`}
width={256}
height={256}
loading="lazy"
/>
);
}
Problem: Receiving lettermark when you expect a real logo
Solutions:
GET /v1/brand?domain=example.comProblem: Getting icon when you want logo
Solution: Specify asset type: /stripe.com/type/logo
Problem: Image looks pixelated or blurry
Solutions:
/stripe.com/w/512 instead of /w/64Problem: Initial request takes 2+ seconds
Explanation: Brand not in database, discovery running
Solutions:
Yes, the public CDN endpoint is included with all Yoku plans. Rate limits apply based on your plan tier.
Absolutely. The CDN is designed for production use with global edge caching.
No. Asset URLs are stable and permanent. If a brand updates their logo, the same CDN URL will return the new asset (cache TTL respects updates).
Yes, use fallback=404 or fallback=transparent to disable lettermark generation.
fetch=true or API enrichment