> ## Documentation Index
> Fetch the complete documentation index at: https://docs.context.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Brand Data

> Turn a domain, name, work email, ticker, ISIN, transaction descriptor, or direct URL into a full brand profile with logos, colors, socials, and industry.

Context.dev's Brand API turns any of the following identifiers into a full **brand profile** with logos, colors, slogans, description, social media handles, address, industry, and website page links:

* Brand domain (e.g., stripe.com)
* Company name (e.g., "Stripe Inc")
* A work email (e.g., [patrick@stripe.com](mailto:patrick@stripe.com))
* A stock ticker (e.g., AAPL)
* An ISIN (e.g., US0378331005)

<Prompt description="Integrate Context.dev's Brand resolution endpoints" icon="sparkles" actions={["copy", "cursor"]}>
  I'm integrating Context.dev's Brand Intelligence endpoints into my app. Help me:

  1. Install the official SDK for my language (`context.dev` on npm / PyPI / RubyGems, `context-dev/context-dev-php` on Packagist, `github.com/context-dot-dev/context-go-sdk` for Go).
  2. Read the API key from the `CONTEXT_DEV_API_KEY` environment variable. Never hardcode it.
  3. Call `POST /brand/retrieve` with the identifier I have (domain, name, email, ticker, transaction descriptor, or a direct URL). Send the value plus a `type` discriminator (`by_domain`, `by_name`, `by_email`, `by_ticker`, `by_transaction`, or `by_direct_url`) in the JSON body. For ISIN, use the separate `GET /brand/retrieve-by-isin`.
  4. Parse the shared envelope (`status`, `code`, `brand`) and extract `brand.title`, `brand.colors[0].hex`, `brand.logos[0].url`, socials, industry, and links.
  5. Treat HTTP 400 with `error_code: "NOT_FOUND"` (no brand) as a normal outcome, not an error. Cache misses for at least 24 hours.
  6. Retry HTTP 429 with exponential backoff.

  Docs: [https://docs.context.dev/guides/get-brand-data](https://docs.context.dev/guides/get-brand-data)
</Prompt>

## Prerequisites

* **A Context.dev API key.** Sign up at [context.dev/signup](https://context.dev/signup), copy the key from the [dashboard](https://context.dev/dashboard) (prefix `ctxt_secret_`), and export it:

  ```bash theme={null}
  export CONTEXT_DEV_API_KEY="ctxt_secret_..."
  ```

* **An SDK (optional).** Install for your language, or skip the install and call directly with `curl`:

  <CodeGroup>
    ```bash TypeScript theme={null}
    npm install context.dev
    ```

    ```bash Python theme={null}
    pip install context.dev
    ```

    ```bash Ruby theme={null}
    gem install context.dev
    ```

    ```bash Go theme={null}
    go get github.com/context-dot-dev/context-go-sdk
    ```

    ```bash PHP theme={null}
    composer require context-dev/context-dev-php
    ```
  </CodeGroup>

## One endpoint, six identifiers

`POST /brand/retrieve` is the unified lookup for domains, company names, work emails, stock tickers, card transaction descriptors, and direct URLs. Pass exactly one identifier in the body along with a `type` discriminator that tells the API which lookup to run.

| Identifier | `type` value     | Field to send              |
| ---------- | ---------------- | -------------------------- |
| Domain     | `by_domain`      | `domain`                   |
| Name       | `by_name`        | `name` (3–30 characters)   |
| Email      | `by_email`       | `email`                    |
| Ticker     | `by_ticker`      | `ticker`                   |
| Card txn   | `by_transaction` | `transaction_info`         |
| Direct URL | `by_direct_url`  | `direct_url` (http(s) URL) |

The response envelope is the same for every lookup, so downstream code only branches on the input, not the output.

<Note>
  `by_direct_url` fetches brand data **only from the URL you provide** — no domain resolution, database lookup, or cross-source enrichment runs. See [Look up by direct URL](#look-up-by-direct-url) for when to use it.
</Note>

<Note>
  ISINs still have a dedicated endpoint: [`GET /brand/retrieve-by-isin`](#look-up-by-isin).
</Note>

## Get a brand by domain

Send `POST /brand/retrieve` with `type: "by_domain"` and a `domain` field. The response is a full brand profile: logos, colors, description, socials, industry, address, and links.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.context.dev/v1/brand/retrieve \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "by_domain",
      "domain": "stripe.com"
    }'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieve({
    type: "by_domain",
    domain: "stripe.com",
  });

  console.log(response.brand.title);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve(type="by_domain", domain="stripe.com")

  print(response.brand.title)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve(
    body: { type: :by_domain, domain: "stripe.com" }
  )

  puts response.brand.title
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.Get(context.TODO(), contextdev.BrandGetParams{
          OfByDomain: &contextdev.BrandGetParamsBodyByDomain{
              Domain: "stripe.com",
          },
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(response.Brand.Title)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieve(
      type: 'by_domain',
      domain: 'stripe.com',
  );

  echo $response->brand->title, PHP_EOL;
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

The connection stays open while the lookup runs, so there's no need to poll. Repeated lookups for the same domain within `maxAgeMs` return the cached record.

### Request Parameters

| Parameter        | Type    | Default            | Description                                                                                                                             |
| ---------------- | ------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `type`           | string  | —                  | **Required.** Lookup discriminator. Use `by_domain` here. See the [identifier table](#one-endpoint-five-identifiers) for the full list. |
| `domain`         | string  | —                  | **Required.** Domain to retrieve brand data for (e.g. `stripe.com`). Provide exactly one identifier field per request.                  |
| `force_language` | string  | —                  | Force the language of the retrieved brand data. Accepts a [SupportedLanguage](https://docs.context.dev/api-reference) code.             |
| `maxSpeed`       | boolean | `false`            | Skip time-consuming operations for a faster response, at the cost of less comprehensive data.                                           |
| `maxAgeMs`       | integer | `7776000000` (90d) | Max cache age before a hard refresh. Clamped to `[86400000, 31536000000]` (1 day – 1 year).                                             |
| `timeoutMS`      | integer | —                  | Abort the request with a 408 if it exceeds this many milliseconds. Max `300000` (5 min).                                                |

### Response

```json expandable theme={null}
{
  "status": "ok",
  "code": 200,
  "brand": {
    "domain": "stripe.com",
    "title": "Stripe",
    "description": "Stripe is a global financial-infrastructure platform that helps businesses accept payments, manage subscriptions, issue cards, and build custom revenue models…",
    "slogan": "Financial infrastructure to grow your revenue.",
    "colors": [
      { "hex": "#543cfb", "name": "Meteor Shower" },
      { "hex": "#a498ec", "name": "Dull Lavender" }
    ],
    "logos": [
      {
        "url": "https://media.brand.dev/5d83eab0-8041-4c39-a30d-84e6a0c5c461.jpg",
        "mode": "has_opaque_background",
        "type": "icon",
        "colors": [{ "hex": "#543cfb", "name": "Meteor Shower" }],
        "resolution": { "width": 512, "height": 512, "aspect_ratio": 1 }
      }
    ],
    "backdrops": [
      {
        "url": "https://media.brand.dev/a0a5ce89-982c-4e3d-9def-8db3e19c6294.jpg",
        "colors": [
          { "hex": "#f57b2d", "name": "Iceland Poppy" },
          { "hex": "#f4bc8c", "name": "Brandy Butter" }
        ],
        "resolution": { "width": 1000, "height": 169, "aspect_ratio": 5.92 }
      }
    ],
    "socials": [
      { "type": "x", "url": "https://x.com/stripe" },
      { "type": "github", "url": "https://github.com/stripe" },
      { "type": "facebook", "url": "https://facebook.com/StripeHQ" },
      { "type": "linkedin", "url": "https://linkedin.com/company/stripe" },
      { "type": "youtube", "url": "https://youtube.com/stripe" }
    ],
    "address": {
      "street": "354 Oyster Point Blvd",
      "city": "South San Francisco",
      "state_province": "California",
      "state_code": "CA",
      "country": "United States",
      "country_code": "US",
      "postal_code": "94080"
    },
    "industries": {
      "eic": [
        { "industry": "Finance", "subindustry": "Payments & Money Movement" },
        {
          "industry": "Finance",
          "subindustry": "Financial Infrastructure & APIs"
        }
      ]
    },
    "links": {
      "blog": "https://stripe.com/blog",
      "login": null,
      "signup": null,
      "careers": "https://stripe.com/jobs",
      "contact": "https://stripe.com/contact/sales",
      "privacy": "https://stripe.com/privacy",
      "terms": "https://stripe.com/legal",
      "pricing": "https://stripe.com/pricing"
    },
    "primary_language": "english",
    "is_nsfw": false
  }
}
```

| Field                    | Type    | Description                                                                                                                                                                                                                  |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`                 | string  | `"ok"` on success, `"error"` on a non-2xx.                                                                                                                                                                                   |
| `code`                   | integer | HTTP status code, echoed in the body for convenience.                                                                                                                                                                        |
| `brand.domain`           | string  | The brand's canonical domain.                                                                                                                                                                                                |
| `brand.title`            | string  | Company name.                                                                                                                                                                                                                |
| `brand.description`      | string  | One-paragraph company description.                                                                                                                                                                                           |
| `brand.slogan`           | string  | Marketing tagline, if available.                                                                                                                                                                                             |
| `brand.colors[]`         | array   | Brand colors ordered by visual prominence. Each has `hex` and a human-readable `name`. Index 0 is the primary.                                                                                                               |
| `brand.logos[]`          | array   | Logo variants. Each has `url`, `mode` (`light`, `dark`, `has_opaque_background`), `type` (`logo` or `icon`), `colors`, and `resolution.{width, height, aspect_ratio}`.                                                       |
| `brand.backdrops[]`      | array   | Hero / backdrop imagery. Same color and resolution structure as logos.                                                                                                                                                       |
| `brand.socials[]`        | array   | Social profile URLs. `type` is one of `x`, `facebook`, `instagram`, `linkedin`, `youtube`, `tiktok`, `github`, and 20+ more.                                                                                                 |
| `brand.address`          | object  | HQ address: `street`, `city`, `state_province`, `state_code`, `country`, `country_code`, `postal_code`.                                                                                                                      |
| `brand.stock`            | object  | `ticker` and `exchange`. `null` for private companies.                                                                                                                                                                       |
| `brand.industries.eic[]` | array   | EIC industry tags with `industry` and `subindustry`. For NAICS or SIC codes, call `/web/naics` or `/web/sic`.                                                                                                                |
| `brand.links`            | object  | Non-social URLs the resolver was able to discover. Common keys include `blog`, `pricing`, `careers`, `contact`, `privacy`, `terms`, `login`, `signup`. Values are `null` when the resolver couldn't find a URL for that key. |
| `brand.email`            | string  | Public contact email, when discoverable.                                                                                                                                                                                     |
| `brand.phone`            | string  | Public contact phone, when discoverable.                                                                                                                                                                                     |
| `brand.primary_language` | string  | Detected language of the brand's website (e.g. `english`, `spanish`).                                                                                                                                                        |
| `brand.is_nsfw`          | boolean | Safe-content flag.                                                                                                                                                                                                           |

<Note>
  The `colors` returned by this API are extracted from the brand's logos. To get
  pixel-perfect colors as they appear on a website, use the [Styleguide
  API](/guides/extract-design-system-from-website#extract-the-full-styleguide) instead.
</Note>

<Accordion title="Get a lighter response">
  If you need only `domain`, `title`, `colors`, `logos`, and `backdrops`, you can use
  `GET /brand/retrieve-simplified`.

  <CodeGroup>
    ```bash cURL theme={null}
    curl -G https://api.context.dev/v1/brand/retrieve-simplified \
      -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
      --data-urlencode "domain=stripe.com"
    ```

    ```typescript TypeScript theme={null}
    import ContextDev from "context.dev";

    const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

    const response = await client.brand.retrieveSimplified({
      domain: "stripe.com",
    });

    console.log(response.brand.logos[0].url);
    ```

    ```python Python theme={null}
    import os
    from context.dev import ContextDev

    client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

    response = client.brand.retrieve_simplified(domain="stripe.com")

    print(response.brand.logos[0].url)
    ```

    ```ruby Ruby theme={null}
    require "context_dev"

    client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

    response = client.brand.retrieve_simplified(domain: "stripe.com")

    puts response.brand.logos.first.url
    ```

    ```go Go theme={null}
    package main

    import (
        "context"
        "fmt"
        "os"

        contextdev "github.com/context-dot-dev/context-go-sdk"
        "github.com/context-dot-dev/context-go-sdk/option"
    )

    func main() {
        client := contextdev.NewClient(
            option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
        )

        response, err := client.Brand.GetSimplified(context.TODO(), contextdev.BrandGetSimplifiedParams{
            Domain: "stripe.com",
        })
        if err != nil {
            panic(err)
        }

        fmt.Println(response.Brand.Logos[0].URL)
    }
    ```

    ```php PHP theme={null}
    <?php

    use ContextDev\Client;

    $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

    $response = $client->brand->retrieveSimplified(domain: 'stripe.com');

    if ($response->brand->logos) {
        echo $response->brand->logos[0]->url, PHP_EOL;
    }
    ```
  </CodeGroup>

  <Badge color="blue" icon="coins">
    10 credits per successful call
  </Badge>

  **Request Parameters**

  | Parameter   | Type    | Default      | Description                                                                      |
  | ----------- | ------- | ------------ | -------------------------------------------------------------------------------- |
  | `domain`    | string  | —            | **Required.** Domain to retrieve simplified brand data for.                      |
  | `maxAgeMs`  | integer | `7776000000` | Max cache age before a hard refresh. Clamped to `[86400000, 31536000000]`.       |
  | `timeoutMS` | integer | —            | Abort the request with a 408 if it exceeds this many milliseconds. Max `300000`. |

  **Response**

  ```json expandable theme={null}
  {
    "status": "ok",
    "brand": {
      "domain": "stripe.com",
      "title": "Stripe",
      "colors": [
        { "hex": "#543cfb", "name": "Meteor Shower" },
        { "hex": "#a498ec", "name": "Dull Lavender" }
      ],
      "logos": [
        {
          "url": "https://media.brand.dev/5d83eab0-8041-4c39-a30d-84e6a0c5c461.jpg",
          "mode": "has_opaque_background",
          "type": "icon",
          "resolution": { "width": 512, "height": 512, "aspect_ratio": 1 }
        }
      ],
      "backdrops": [
        {
          "url": "https://media.brand.dev/a0a5ce89-982c-4e3d-9def-8db3e19c6294.jpg",
          "resolution": { "width": 1024, "height": 768, "aspect_ratio": 1.33 }
        }
      ]
    }
  }
  ```
</Accordion>

## Look up by company name

Send `POST /brand/retrieve` with `type: "by_name"` and a `name` (3–30 characters). Pass `country_gl` to bias the match toward a specific country when the name is ambiguous across markets.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.context.dev/v1/brand/retrieve \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "by_name",
      "name": "Airbnb"
    }'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieve({
    type: "by_name",
    name: "Airbnb",
  });

  console.log(response.brand.domain);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve(type="by_name", name="Airbnb")

  print(response.brand.domain)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve(
    body: { type: :by_name, name: "Airbnb" }
  )

  puts response.brand.domain
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.Get(context.TODO(), contextdev.BrandGetParams{
          OfByName: &contextdev.BrandGetParamsBodyByName{
              Name: "Airbnb",
          },
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(response.Brand.Domain)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieve(
      type: 'by_name',
      name: 'Airbnb',
  );

  echo $response->brand->domain, PHP_EOL;
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

Name must be 3–30 characters. Pass `country_gl` as a lowercase ISO 3166-1 alpha-2 code to narrow the match when the name could resolve to multiple brands across markets.

### Request Parameters

| Parameter        | Type                                   | Default      | Description                                                                   |
| ---------------- | -------------------------------------- | ------------ | ----------------------------------------------------------------------------- |
| `type`           | string                                 | —            | **Required.** Lookup discriminator. Use `by_name` here.                       |
| `name`           | string (3–30 chars)                    | —            | **Required.** Company name (e.g. `Apple Inc`, `Microsoft Corporation`).       |
| `country_gl`     | string (ISO 3166-1 alpha-2, lowercase) | —            | Two-letter country code to bias the match toward (e.g. `us`, `gb`, `de`).     |
| `maxSpeed`       | boolean                                | `false`      | Skip time-consuming operations for a faster, less complete response.          |
| `force_language` | string                                 | —            | Force the language of the retrieved brand data.                               |
| `maxAgeMs`       | integer                                | `7776000000` | Max cache age before a hard refresh.                                          |
| `timeoutMS`      | integer                                | —            | Abort with a 408 if the request exceeds this many milliseconds. Max `300000`. |

### Response

Returns the same envelope as [`POST /brand/retrieve`](#get-a-brand-by-domain); see [the response field table above](#response).

```json expandable theme={null}
{
  "status": "ok",
  "code": 200,
  "brand": {
    "domain": "airbnb.com",
    "title": "Airbnb",
    "description": "Airbnb is a global online community marketplace that connects hosts with guests, offering unique stays and experiences…",
    "slogan": "Belong Anywhere",
    "colors": [
      { "hex": "#fc3c5c", "name": "Radical Red" },
      { "hex": "#fc9cb4", "name": "Saira Red" },
      { "hex": "#fb5c74", "name": "Ponceau" }
    ],
    "logos": [
      {
        "url": "https://media.brand.dev/4ae9a10b-ffde-45c8-b5c1-c1e7cef5b716.png",
        "mode": "light",
        "type": "icon",
        "colors": [{ "hex": "#fc3c5c", "name": "Radical Red" }],
        "resolution": { "width": 250, "height": 250, "aspect_ratio": 1 }
      }
    ],
    "stock": { "ticker": "ABNB", "exchange": "NASDAQ" },
    "industries": {
      "eic": [
        {
          "industry": "Hospitality & Tourism",
          "subindustry": "Vacation Rentals & Short-Term Stays"
        },
        {
          "industry": "Technology",
          "subindustry": "eCommerce & Marketplace Platforms"
        }
      ]
    }
  }
}
```

## Look up by work email

Send `POST /brand/retrieve` with `type: "by_email"` and an `email` field. The API extracts the domain, rejects personal-email providers (gmail, outlook, proton, etc.), then runs the same resolver as a domain lookup.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.context.dev/v1/brand/retrieve \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "by_email",
      "email": "founders@stripe.com"
    }'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieve({
    type: "by_email",
    email: "founders@stripe.com",
  });

  console.log(response.brand.domain);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve(
      type="by_email",
      email="founders@stripe.com",
  )

  print(response.brand.domain)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve(
    body: { type: :by_email, email: "founders@stripe.com" }
  )

  puts response.brand.domain
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.Get(context.TODO(), contextdev.BrandGetParams{
          OfByEmail: &contextdev.BrandGetParamsBodyByEmail{
              Email: "founders@stripe.com",
          },
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(response.Brand.Domain)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieve(
      type: 'by_email',
      email: 'founders@stripe.com',
  );

  echo $response->brand->domain, PHP_EOL;
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

Personal-email addresses on common consumer providers (`*@gmail.com`, `*@outlook.com`, `*@proton.me`, and others) return a 422 with `error_code: "FREE_EMAIL_DETECTED"`, which is useful for onboarding flows that should only enrich on a work email.

### Request Parameters

| Parameter        | Type    | Default      | Description                                                                   |
| ---------------- | ------- | ------------ | ----------------------------------------------------------------------------- |
| `type`           | string  | —            | **Required.** Lookup discriminator. Use `by_email` here.                      |
| `email`          | string  | —            | **Required.** Email address (e.g. `alex@stripe.com`).                         |
| `maxSpeed`       | boolean | `false`      | Skip time-consuming operations for a faster, less complete response.          |
| `force_language` | string  | —            | Force the language of the retrieved brand data.                               |
| `maxAgeMs`       | integer | `7776000000` | Max cache age before a hard refresh.                                          |
| `timeoutMS`      | integer | —            | Abort with a 408 if the request exceeds this many milliseconds. Max `300000`. |

### Response

Returns the same envelope as [`POST /brand/retrieve`](#get-a-brand-by-domain); see [the response field table above](#response).

```json expandable theme={null}
{
  "status": "ok",
  "code": 200,
  "brand": {
    "domain": "stripe.com",
    "title": "Stripe",
    "slogan": "Financial infrastructure to grow your revenue.",
    "colors": [
      { "hex": "#543cfb", "name": "Meteor Shower" },
      { "hex": "#a498ec", "name": "Dull Lavender" }
    ],
    "logos": [
      {
        "url": "https://media.brand.dev/5d83eab0-8041-4c39-a30d-84e6a0c5c461.jpg",
        "mode": "has_opaque_background",
        "type": "icon",
        "colors": [{ "hex": "#543cfb", "name": "Meteor Shower" }],
        "resolution": { "width": 512, "height": 512, "aspect_ratio": 1 }
      }
    ],
    "industries": {
      "eic": [
        { "industry": "Finance", "subindustry": "Payments & Money Movement" },
        {
          "industry": "Finance",
          "subindustry": "Financial Infrastructure & APIs"
        }
      ]
    }
  }
}
```

## Look up by stock ticker

Send `POST /brand/retrieve` with `type: "by_ticker"` and a `ticker` field. The response populates the `stock` object with `ticker` and `exchange`.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.context.dev/v1/brand/retrieve \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "by_ticker",
      "ticker": "AAPL"
    }'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieve({
    type: "by_ticker",
    ticker: "AAPL",
  });

  console.log(response.brand.stock);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve(type="by_ticker", ticker="AAPL")

  print(response.brand.stock)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve(
    body: { type: :by_ticker, ticker: "AAPL" }
  )

  puts response.brand.stock.to_h
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.Get(context.TODO(), contextdev.BrandGetParams{
          OfByTicker: &contextdev.BrandGetParamsBodyByTicker{
              Ticker: "AAPL",
          },
      })
      if err != nil {
          panic(err)
      }

      fmt.Printf("%+v\n", response.Brand.Stock)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieve(
      type: 'by_ticker',
      ticker: 'AAPL',
  );

  print_r($response->brand->stock);
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

Pass `ticker_exchange` to constrain the lookup to a specific exchange (`NASDAQ`, `NYSE`, `LON`, `XETR`, `TYO`, and 60+ others) when the bare symbol is ambiguous.

### Request Parameters

| Parameter         | Type          | Default      | Description                                                                             |
| ----------------- | ------------- | ------------ | --------------------------------------------------------------------------------------- |
| `type`            | string        | —            | **Required.** Lookup discriminator. Use `by_ticker` here.                               |
| `ticker`          | string        | —            | **Required.** Stock ticker symbol (e.g. `AAPL`, `MSFT`).                                |
| `ticker_exchange` | string (enum) | —            | Exchange code to disambiguate (`NASDAQ`, `NYSE`, `LON`, `XETR`, `TYO`, and 60+ others). |
| `maxSpeed`        | boolean       | `false`      | Skip time-consuming operations for a faster, less complete response.                    |
| `force_language`  | string        | —            | Force the language of the retrieved brand data.                                         |
| `maxAgeMs`        | integer       | `7776000000` | Max cache age before a hard refresh.                                                    |
| `timeoutMS`       | integer       | —            | Abort with a 408 if the request exceeds this many milliseconds. Max `300000`.           |

### Response

Returns the same envelope as [`POST /brand/retrieve`](#get-a-brand-by-domain); see [the response field table above](#response). The `stock` object is populated for ticker lookups.

```json expandable theme={null}
{
  "status": "ok",
  "code": 200,
  "brand": {
    "domain": "apple.com",
    "title": "Apple",
    "slogan": "Think Different",
    "stock": { "ticker": "AAPL", "exchange": "NASDAQ" },
    "colors": [
      { "hex": "#7c7c7c", "name": "Namara Grey" },
      { "hex": "#656565", "name": "Hard Coal" }
    ],
    "logos": [
      {
        "url": "https://media.brand.dev/08f7d41a-ef7b-4d83-aff6-e7f67408b85d.png",
        "mode": "has_opaque_background",
        "type": "icon",
        "colors": [{ "hex": "#656565", "name": "Hard Coal" }],
        "resolution": { "width": 302, "height": 302, "aspect_ratio": 1 }
      }
    ],
    "industries": {
      "eic": [
        {
          "industry": "Technology",
          "subindustry": "Hardware & Semiconductors"
        },
        { "industry": "Technology", "subindustry": "Software (B2C)" }
      ]
    }
  }
}
```

## Look up by direct URL

Send `POST /brand/retrieve` with `type: "by_direct_url"` and a full http(s) `direct_url`. The API fetches brand fields (title, description, logos, socials, contact info, links) **only from that URL** — no domain resolution, database lookup, or cross-source enrichment runs.

Use this when you want to point the API at a specific page — a subpath, a preview environment, a landing page, or a domain the API doesn't yet have in its database — and get whatever that page exposes. Results are limited to what the single page contains, so expect fewer fields than a `by_domain` lookup.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.context.dev/v1/brand/retrieve \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "by_direct_url",
      "direct_url": "https://stripe.com/enterprise"
    }'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieve({
    type: "by_direct_url",
    direct_url: "https://stripe.com/enterprise",
  });

  console.log(response.brand.title, response.brand.logos[0]?.url);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve(
      type="by_direct_url",
      direct_url="https://stripe.com/enterprise",
  )

  print(response.brand.title)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve(
    body: {
      type: :by_direct_url,
      direct_url: "https://stripe.com/enterprise",
    }
  )

  puts response.brand.title
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.Get(context.TODO(), contextdev.BrandGetParams{
          OfByDirectURL: &contextdev.BrandGetParamsBodyByDirectURL{
              DirectURL: "https://stripe.com/enterprise",
          },
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(response.Brand.Title)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieve(
      type: 'by_direct_url',
      directUrl: 'https://stripe.com/enterprise',
  );

  echo $response->brand->title, PHP_EOL;
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

<Warning>
  `by_direct_url` rejects `maxSpeed`, `force_language`, and `maxAgeMs` — the single-page scrape flow would ignore them. Only `timeoutMS` is accepted alongside `direct_url`.
</Warning>

### Request Parameters

| Parameter    | Type    | Default | Description                                                                     |
| ------------ | ------- | ------- | ------------------------------------------------------------------------------- |
| `type`       | string  | —       | **Required.** Lookup discriminator. Use `by_direct_url` here.                   |
| `direct_url` | string  | —       | **Required.** Full http(s) URL to fetch (e.g. `https://stripe.com/enterprise`). |
| `timeoutMS`  | integer | —       | Abort with a 408 if the request exceeds this many milliseconds. Max `300000`.   |

### Response

Returns the same envelope as [`POST /brand/retrieve`](#get-a-brand-by-domain), but the `brand` object only contains fields that could be extracted from the provided URL: `domain`, `title`, `description`, `logos`, `socials`, `email`, `phone`, and `links`. Fields backed by database enrichment — `colors`, `backdrops`, `industries`, `stock`, `address` — are not returned.

If the URL can't be fetched, the API responds with `400` and `error_code: "WEBSITE_ACCESS_ERROR"`.

## Look up by ISIN

`GET /brand/retrieve-by-isin` resolves an International Securities Identification Number (ISIN), the 12-character identifier used in financial data feeds, to a brand and populates the `stock` object.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G https://api.context.dev/v1/brand/retrieve-by-isin \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    --data-urlencode "isin=US0378331005"
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieveByIsin({ isin: "US0378331005" });

  console.log(response.brand.domain, response.brand.stock);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve_by_isin(isin="US0378331005")

  print(response.brand.domain, response.brand.stock)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve_by_isin(isin: "US0378331005")

  puts "#{response.brand.domain} #{response.brand.stock.to_h}"
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.GetByIsin(context.TODO(), contextdev.BrandGetByIsinParams{
          Isin: "US0378331005",
      })
      if err != nil {
          panic(err)
      }

      fmt.Printf("%s %+v\n", response.Brand.Domain, response.Brand.Stock)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieveByIsin(isin: 'US0378331005');

  echo $response->brand->domain, ' ';
  print_r($response->brand->stock);
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

Use this when you're working with financial data feeds keyed by ISIN. Malformed ISINs return a 400.

### Request Parameters

| Parameter        | Type    | Default      | Description                                                                   |
| ---------------- | ------- | ------------ | ----------------------------------------------------------------------------- |
| `isin`           | string  | —            | **Required.** 12-character ISIN (e.g. `US0378331005` for Apple Inc.).         |
| `maxSpeed`       | boolean | `false`      | Skip time-consuming operations for a faster, less complete response.          |
| `force_language` | string  | —            | Force the language of the retrieved brand data.                               |
| `maxAgeMs`       | integer | `7776000000` | Max cache age before a hard refresh.                                          |
| `timeoutMS`      | integer | —            | Abort with a 408 if the request exceeds this many milliseconds. Max `300000`. |

### Response

Returns the same envelope as [`POST /brand/retrieve`](#get-a-brand-by-domain); see [the response field table above](#response). The `stock` object is populated with the resolved ticker.

```json expandable theme={null}
{
  "status": "ok",
  "code": 200,
  "brand": {
    "domain": "apple.com",
    "title": "Apple",
    "stock": { "ticker": "AAPL", "exchange": "NASDAQ" },
    "colors": [{ "hex": "#7c7c7c", "name": "Namara Grey" }],
    "logos": [
      {
        "url": "https://media.brand.dev/08f7d41a-ef7b-4d83-aff6-e7f67408b85d.png",
        "mode": "has_opaque_background",
        "type": "icon",
        "resolution": { "width": 302, "height": 302, "aspect_ratio": 1 }
      }
    ]
  }
}
```

## Identify a card transaction

Send `POST /brand/retrieve` with `type: "by_transaction"` and a raw descriptor in `transaction_info`. Pass `mcc`, `city`, `country_gl`, or `phone` hints when you have them to improve accuracy on ambiguous descriptors.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.context.dev/v1/brand/retrieve \
    -X POST \
    -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "by_transaction",
      "transaction_info": "STARBUCKS STORE 12345",
      "country_gl": "us",
      "mcc": "5814"
    }'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  const response = await client.brand.retrieve({
    type: "by_transaction",
    transaction_info: "STARBUCKS STORE 12345",
    country_gl: "us",
    mcc: "5814",
  });

  console.log(response.brand.domain);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  response = client.brand.retrieve(
      type="by_transaction",
      transaction_info="STARBUCKS STORE 12345",
      country_gl="us",
      mcc="5814",
  )

  print(response.brand.domain)
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  response = client.brand.retrieve(
    body: {
      type: :by_transaction,
      transaction_info: "STARBUCKS STORE 12345",
      country_gl: :us,
      mcc: "5814",
    }
  )

  puts response.brand.domain
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk"
      "github.com/context-dot-dev/context-go-sdk/option"
      "github.com/context-dot-dev/context-go-sdk/packages/param"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      response, err := client.Brand.Retrieve(context.TODO(), contextdev.BrandRetrieveParams{
          TransactionInfo: "STARBUCKS STORE 12345",
          CountryGl:       contextdev.BrandRetrieveParamsCountryGlUs,
          Mcc:             param.NewOpt("5814"),
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(response.Brand.Domain)
  }
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $response = $client->brand->retrieve(
      transactionInfo: 'STARBUCKS STORE 12345',
      mcc: '5814',
      countryGl: 'us',
  );

  echo $response->brand->domain, ' ', $response->brand->title, PHP_EOL;
  ```
</CodeGroup>

<Badge color="blue" icon="coins">
  10 credits per successful call
</Badge>

Descriptors the API can't match with confidence return a 400 with `error_code: "NOT_FOUND"`. Setting `high_confidence_only: true` makes the API return that 400 instead of a low-confidence match.

### Request Parameters

| Parameter              | Type                                  | Default | Description                                                                    |
| ---------------------- | ------------------------------------- | ------- | ------------------------------------------------------------------------------ |
| `type`                 | string                                | —       | **Required.** Lookup discriminator. Use `by_transaction` here.                 |
| `transaction_info`     | string                                | —       | **Required.** Raw transaction descriptor (e.g. `STARBUCKS STORE 12345`).       |
| `country_gl`           | string (lowercase ISO 3166-1 alpha-2) | —       | Country hint (e.g. `us`, `gb`).                                                |
| `city`                 | string                                | —       | City hint (e.g. `San Francisco`).                                              |
| `mcc`                  | string                                | —       | Merchant Category Code (e.g. `5814`).                                          |
| `phone`                | number                                | —       | Merchant phone hint, when present on the descriptor.                           |
| `high_confidence_only` | boolean                               | `false` | Return a 400 with `error_code: "NOT_FOUND"` instead of a low-confidence match. |
| `maxSpeed`             | boolean                               | `false` | Skip time-consuming operations for a faster, less complete response.           |
| `force_language`       | string                                | —       | Force the language of the retrieved brand data.                                |
| `timeoutMS`            | integer                               | —       | Abort with a 408 if the request exceeds this many milliseconds. Max `300000`.  |

### Response

Returns the same envelope as the rest of `POST /brand/retrieve`; see [the response field table above](#response).

```json expandable theme={null}
{
  "status": "ok",
  "code": 200,
  "brand": {
    "domain": "starbucks.com",
    "title": "Starbucks",
    "slogan": "Inspiring and nurturing the human spirit — one person, one cup",
    "stock": { "ticker": "SBUX", "exchange": "NASDAQ" },
    "colors": [
      { "hex": "#0bac66", "name": "Secret Garden" },
      { "hex": "#7cd4b4", "name": "Seafoam Blue" }
    ],
    "logos": [
      {
        "url": "https://media.brand.dev/67dc7846-2ca2-4a7b-9877-6bb5a5e2c0e0.png",
        "mode": "has_opaque_background",
        "type": "icon",
        "colors": [{ "hex": "#0bac66", "name": "Secret Garden" }],
        "resolution": { "width": 180, "height": 180, "aspect_ratio": 1 }
      }
    ],
    "industries": {
      "eic": [
        {
          "industry": "Retail & E-commerce",
          "subindustry": "Omnichannel & In-Store Retail"
        }
      ]
    }
  }
}
```

## Handle errors

Not every input resolves. The API returns a non-2xx response with a `message`, `status: "error"`, and an `error_code`:

```json theme={null}
{
  "message": "Transaction could not be identified.",
  "status": "error",
  "error_code": "NOT_FOUND"
}
```

Common cases:

| Status | `error_code`             | When                                                            |
| ------ | ------------------------ | --------------------------------------------------------------- |
| 400    | `WEBSITE_ACCESS_ERROR`   | Domain can't be resolved or fetched (DNS failure, hostile WAF). |
| 400    | `INPUT_VALIDATION_ERROR` | Required parameter missing or malformed.                        |
| 400    | `NOT_FOUND`              | Lookup ran but no brand was matched.                            |
| 408    | `REQUEST_TIMEOUT`        | Request exceeded `timeoutMS` or the platform max.               |
| 422    | `FREE_EMAIL_DETECTED`    | Personal-email provider on a `by_email` lookup.                 |
| 429    | `RATE_LIMITED`           | Rate limit hit.                                                 |

Treat `NOT_FOUND` responses as a normal outcome, not an error. For high-volume pipelines, cache misses for at least 24 hours so you don't re-resolve the same dead identifier on every retry.

Rate limits surface as HTTP 429. Back off exponentially:

<CodeGroup>
  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });

  async function retrieveWithRetry(domain: string, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
      try {
        return await client.brand.retrieve({ type: "by_domain", domain });
      } catch (err: any) {
        if (err.status === 429 && i < maxRetries - 1) {
          await new Promise((r) => setTimeout(r, 2 ** i * 1000));
          continue;
        }
        throw err;
      }
    }
  }
  ```

  ```python Python theme={null}
  import os
  import time
  from context.dev import ContextDev, APIError

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  def retrieve_with_retry(domain, max_retries=3):
      for i in range(max_retries):
          try:
              return client.brand.retrieve(type="by_domain", domain=domain)
          except APIError as e:
              if e.status_code == 429 and i < max_retries - 1:
                  time.sleep(2 ** i)
                  continue
              raise
  ```

  ```ruby Ruby theme={null}
  require "context_dev"

  def retrieve_with_retry(domain, max_retries: 3)
    client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
    max_retries.times do |i|
      return client.brand.retrieve(body: { type: :by_domain, domain: domain })
    rescue ContextDev::Errors::APIError => e
      raise unless e.status == 429 && i < max_retries - 1
      sleep(2 ** i)
    end
  end
  ```

  ```php PHP theme={null}
  <?php

  use ContextDev\Client;
  use ContextDev\Core\Exceptions\APIStatusException;

  function retrieveWithRetry(string $domain, int $maxRetries = 3) {
      $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

      for ($i = 0; $i < $maxRetries; $i++) {
          try {
              return $client->brand->retrieve(type: 'by_domain', domain: $domain);
          } catch (APIStatusException $e) {
              if ($e->status === 429 && $i < $maxRetries - 1) {
                  usleep((2 ** $i) * 1_000_000);
                  continue;
              }
              throw $e;
          }
      }
  }
  ```
</CodeGroup>

For the full catalog of error codes, see [Troubleshooting](/optimization/troubleshooting).

## Use cases

* Pre-fill onboarding forms with logo, name, and colors when a user signs up with a work email.
* Enrich CRM leads with industry, socials, address, and logos for outbound playbooks.
* Resolve card transaction descriptors to canonical merchant brands for spend analytics.
* Power "trusted by" logo strips and customer-wall sections with live brand data.
* Pull public-company profiles from a ticker or ISIN for investor-facing dashboards.

## Next steps

<CardGroup cols={2}>
  <Card title="Prefetch for Faster Response" icon="bolt" href="/optimization/prefetching">
    Hide cold-hit latency from your users.
  </Card>

  <Card title="Handle Rate Limits" icon="gauge-high" href="/optimization/rate-limits">
    Backoff strategies, client cache, and prefetch fallbacks.
  </Card>

  <Card title="Best Practices" icon="list-check" href="/optimization/best-practices">
    Caching, error handling, and key hygiene.
  </Card>

  <Card title="Troubleshooting" icon="bug" href="/optimization/troubleshooting">
    Status codes, retry patterns, and common errors.
  </Card>
</CardGroup>
