This website requires JavaScript to run properly.

CDN Asset Endpoint

Real-time brand asset delivery with automatic fallbacks and discovery.

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.

Why Use the CDN Endpoint?

Unlike the authenticated REST API, the CDN endpoint is optimized for:

  • Client-side rendering - No API key needed, embed directly in <img> tags
  • Global edge caching - Sub-50ms response times worldwide
  • Smart fallbacks - Never show broken images with lettermark generation
  • On-demand discovery - Automatically fetch and persist new brand assets
  • Format transformation - Request any format (WebP, PNG, JPG) on the fly
  • Dynamic resizing - Scale images to exact dimensions without preprocessing

Base URL

https://cdn.yoku.app/

URL Structure

The CDN endpoint uses a path-based parameter system for maximum cacheability:

https://cdn.yoku.app/{identifierType}/{identifier}/{param}/{value}/{param}/{value}...

Basic Examples

<!-- 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" />

Identifier Types

The CDN supports multiple identifier types to resolve brands:

TypeFormatExampleUse Case
domainDomain namestripe.comWeb companies, SaaS platforms
tickerStock ticker symbolAAPLFinancial applications
isinISIN codeUS0378331005International securities
company_nameCompany legal nameSalesforceGeneric company lookup
idYoku internal brand IDbrand_abc123Direct brand reference

Identifier Type Resolution

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" />

Parameters

All parameters are optional and follow the /{param}/{value} pattern in the URL path.

Asset Selection

type - Asset Type

Controls which type of brand asset to return.

ValueDescriptionUse Case
iconSquare favicon-style icons (default)Lists, avatars, small icons
logoFull horizontal logos with textHeaders, hero sections
symbolBrand 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 Theme

Request light or dark mode optimized assets.

ValueDescription
lightOptimized for light backgrounds (default)
darkOptimized 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" />

Image Transformation

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 Format

Convert image to specific format. Specified via file extension.

FormatExtensionUse Case
webp.webpModern browsers, best compression
png.pngTransparency support, lossless
jpg.jpgMaximum compatibility
jpeg.jpegAlias 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 Behavior

Controls what to return when no asset is found.

ValueBehaviorCache TTL
lettermarkGenerate colored badge with first letter (default)5 minutes
transparentReturn transparent 50x50 PNG5 minutes
404HTTP 404 Not Found5 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" />

Lettermark Fallbacks

When fallback=lettermark (default), Yoku generates a deterministic, visually-appealing letter badge instead of showing broken images.

How Lettermarks Work

  1. Extract Display Name
    • If brand exists → use brand title
    • If domain → prettify domain (stripe.com → "Stripe")
    • If ticker → use uppercase ticker
    • If company name → use provided name
  2. Generate First Letter
    • Extract first character, uppercase: "S" for Stripe
  3. Deterministic Color
    • Hash the seed (domain/identifier)
    • Generate stable HSL color: same seed = same color
    • Theme-aware saturation/lightness
  4. Render SVG Badge
    • 128x128 PNG with rounded corners
    • White bold letter, centered
    • Colored background from hash

Lettermark Examples

<!-- 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:

  • No broken images in production
  • Visual consistency in lists/grids
  • Deterministic colors (same domain = same color)
  • Professional appearance
  • Works with all transformations (resize, format)

Cache Strategy: Lettermarks are cached for 5 minutes (not forever) so that when real assets are discovered later, they replace the lettermark quickly.


Combining Parameters

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" />

Caching Strategy

The CDN uses multi-tier caching for optimal performance:

Asset Cache (Found)

When assets exist in the database:

Cache-Control: public, max-age=86400, stale-while-revalidate=604800
CDN-Cache-Control: public, max-age=31536000
  • Browser cache: 24 hours
  • CDN edge cache: 1 year
  • Stale-while-revalidate: 7 days

Fallback Cache (Not Found)

When returning fallbacks (lettermark, transparent, 404):

Cache-Control: public, max-age=300, stale-while-revalidate=600
CDN-Cache-Control: public, max-age=300
  • Browser cache: 5 minutes
  • CDN edge cache: 5 minutes
  • Stale-while-revalidate: 10 minutes

Why short-lived? If asset discovery or enrichment finds real assets later, the fallback is replaced quickly.

ETags for Efficiency

Assets include SHA-256 based ETags for conditional requests:

ETag: "abc123def456..."

Subsequent requests with If-None-Match return 304 Not Modified for bandwidth savings.


Common Use Cases

1. Transaction Lists (Fintech)

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"
/>

2. Company Directories (CRM/SaaS)

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>

3. Financial Dashboards

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" />

4. User Onboarding

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:

  1. Yoku fetches their favicon/logo
  2. Persists to database
  3. Returns asset or lettermark
  4. Future requests get cached asset

5. Dark Mode Support

Automatically serve theme-appropriate assets:

// React example
const Logo = ({ domain, darkMode }) => (
  <img
    src={`https://cdn.yoku.app/${domain}/theme/${darkMode ? "dark" : "light"}/w/200`}
  />
);

6. Responsive Images

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>

Best Practices

1. Always Specify Dimensions

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" />

2. Use WebP for Modern Browsers

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>

3. Use Lettermark Fallback for Production

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" />

4. Enable Fetch for User-Generated Domains

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"
  />
);

5. Lazy Load Off-Screen Images

Use native lazy loading for performance:

<img src="https://cdn.yoku.app/stripe.com/w/128" loading="lazy" alt="Stripe" />

6. Provide Alt Text for Accessibility

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" />

Migration from Other Services

From Clearbit Logo API

- https://logo.clearbit.com/stripe.com
+ https://cdn.yoku.app/stripe.com

From Brandfetch

- https://cdn.brandfetch.io/stripe.com/w/400
+ https://cdn.yoku.app/stripe.com/w/400

From Google Favicon Service

- https://www.google.com/s2/favicons?domain=stripe.com
+ https://cdn.yoku.app/stripe.com/type/icon

Advanced Examples

Dynamic Color Extraction

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>;

Batch Loading with Promises

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)),
  ),
);

SSR with Next.js Image

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"
    />
  );
}

Troubleshooting

Asset Not Found

Problem: Receiving lettermark when you expect a real logo

Solutions:

  1. Check if brand is in database via API: GET /v1/brand?domain=example.com
  2. Wait 5 minutes for background enrichment to complete
  3. Contact support if brand should exist

Wrong Asset Returned

Problem: Getting icon when you want logo

Solution: Specify asset type: /stripe.com/type/logo

Image Quality Issues

Problem: Image looks pixelated or blurry

Solutions:

  1. Request larger source: /stripe.com/w/512 instead of /w/64
  2. Use SVG if available (automatic for vector logos)
  3. Avoid upscaling: don't request larger than original

Slow First Load

Problem: Initial request takes 2+ seconds

Explanation: Brand not in database, discovery running

Solutions:

  1. Pre-warm cache via API
  2. Accept lettermark fallback for instant response
  3. Subsequent requests will be fast (<50ms)

FAQ

Is the CDN endpoint free?

Yes, the public CDN endpoint is included with all Yoku plans. Rate limits apply based on your plan tier.

Can I use this in production?

Absolutely. The CDN is designed for production use with global edge caching.

Do assets ever change URLs?

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).

Can I disable lettermark fallbacks?

Yes, use fallback=404 or fallback=transparent to disable lettermark generation.

How often are assets updated?

  • High-traffic brands: Daily
  • Medium-traffic brands: Weekly
  • On-demand: Via fetch=true or API enrichment