---
title: "Extract brand tokens from a website URL"
method: POST
path: "/v1/brand-kits/extract"
tags: ["brand-kits"]
---

# Extract brand tokens from a website URL

`POST /v1/brand-kits/extract`

## Request

- Base URL: `https://api.cueframe.ai`
- URL: `https://api.cueframe.ai/v1/brand-kits/extract`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.cueframe.ai/api/auth/mcp/authorize`, token URL `https://api.cueframe.ai/api/auth/mcp/token`, scopes: `projects:write`)
  - API key in header `PAYMENT-SIGNATURE`

Queue brand-token extraction from a website URL — ASYNC: returns a 202 job receipt; poll GET /v1/jobs/{jobId} (or MCP wait_job kind=brand_kit_extract) for the tokens (colors, fonts, title, description) on the succeeded result. The service inspects the site under a 20-second limit and does NOT persist a kit (pass the result to POST /brand-kits). A blocked (private-network), non-2xx, non-HTML, or slow URL degrades to EMPTY token arrays on a SUCCEEDED terminal rather than erroring; succeeded extractions are reused for 5 minutes per URL.

## Request body

- ExtractBrandKitRequest: POST /brand-kits/extract body — the website URL to extract brand tokens from.
  - `url` string, uri, required

## Response `202`

Extraction job queued.

- JobEnqueueResponse
  - `jobId` string, required: Poll GET /v1/jobs/{jobId} / wait_job until terminal.
  - `jobKey` string, required: Deterministic identity of the work (content hash of every input the result depends on). Re-enqueueing the same key returns the same job while it runs; a failed key revives as a fresh attempt.
  - `kind` string, required: Job family, e.g. `verify` | `preview` | `brand_kit_extract`.
  - `status` 'running' | 'succeeded' | 'cancelled', required: running on a fresh/deduped enqueue; succeeded when an identical request already completed. Cancelled is part of the shared status vocabulary; identical cancelled work revives to running.

## Other responses

- `400`: Bad request — validation_error / invalid_cursor / invalid_query.
- `401`: Missing or invalid Authorization header.
- `402`: Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).
- `403`: Forbidden — permission insufficient.
- `422`: Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.
- `429`: Rate limited. Retry-After header present.
- `500`: Internal error.

---

[API](https://skmtc.dev/cueframe/apis/cueframe-api.md) · [All operations](https://skmtc.dev/cueframe/apis/cueframe-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cueframe/apis/cueframe-api/revisions/8f9bfe362b4a?raw)
