# Brand extraction

Given any URL, the brand endpoint returns the brand's logos, dominant colors, backdrop images, and brand name extracted from the registered domain. Use it to pre-fill intro templates, pick a background that matches the target product's palette, or surface brand metadata in an agent UI before a recording starts.

This endpoint is read-only. It does not store anything against the caller's account.

## When to use it

- Pre-fill the [intro template](/docs/customizing-video/intro-templates) with the target product's logo and brand color.
- Choose a [background](/docs/customizing-video/background) gradient that matches the target's palette.
- Show brand assets in an agent UI when confirming a recording request.
- Build a launch landing page or comparison page that needs brand assets from any domain.

## Endpoint

- `POST /v1/agent/brand`
  - Body: `{ "url": "https://..." }`
  - Response: HTTP `200` with the `BrandExtractionResult` envelope on every call. Extraction failures are reported inside the body, not via HTTP status.
  - Auth: API key, or an MCP-issued OAuth access token if you call this through the MCP server.

## Response shape

Success:

```json
{
  "ok": true,
  "source_url": "https://stripe.com/",
  "data": {
    "brand_name": "Stripe",
    "logos": [
      { "url": "...", "format": "svg", "kind": "wordmark" }
    ],
    "colors": [
      { "hex": "#635BFF", "role": "primary" }
    ],
    "backdrop_images": [
      { "url": "..." }
    ]
  }
}
```

Failure:

```json
{
  "ok": false,
  "source_url": "https://stripe.com/",
  "error": {
    "code": "ACCESS_BLOCKED",
    "message": "Brand site blocked the brand-extraction fetch.",
    "status": 403
  }
}
```

`status` on the error object is set when the underlying fetch returned an HTTP status worth surfacing.

## Domain normalization

The endpoint always fetches the registered domain (eTLD+1), not the exact URL you sent.

- `https://help.stripe.com/articles/123` → `stripe.com`
- `https://www.stripe.com/pricing` → `stripe.com`
- `https://stripe.com/` → `stripe.com`

This keeps brand results stable regardless of which page on the site you asked about.

## Error codes

`error.code` is one of:

- `INVALID_URL`: The URL is malformed or unsupported.
- `ACCESS_BLOCKED`: The target site refused the request.
- `NOT_FOUND`: The fetch reached the site but no brand content was found.
- `SERVER_ERROR`: The site returned a server-side failure.
- `NETWORK_ERROR`: Transport-level failure.
- `EMPTY_CONTENT`: The fetch succeeded but the response was empty.

HTTP-level errors are reserved for client-side problems:

- `400` when the request body is missing `url` or is malformed.
- `401` when auth is missing or invalid.

## Example

```bash
curl -X POST https://api.slideshot.ai/v1/agent/brand \
  -H "x-api-key: $SLIDESHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://stripe.com" }'
```

The CLI exposes the same behavior with `slideshot brand fetch https://stripe.com`.

## Related

- [Intro templates](/docs/customizing-video/intro-templates): use brand logos and colors in title cards.
- [Background](/docs/customizing-video/background): match the brand palette behind the recorded UI.
- [API overview](/docs/api/overview): authentication, errors, and request shape.
