# Coverage and quality Source: https://docs.brandfetch.com/accuracy/coverage-and-quality ## Methodology Measuring accuracy in open-web brand data has real theoretical and practical limits. We want to be explicit about how the numbers in this document should be interpreted. A defining property of our dataset is that it must work across the full range of domains on the open internet. Input quality varies materially, and output quality is a direct function of it. When a site is slow, broken, or content-thin, the resulting data footprint is thinner, which reduces coverage. We do not compensate for this. A thin footprint is itself a strong indicator of low brand maturity or weak digital footprint. For practical purposes, this evaluation is sample-based. Our goal is to construct samples that are random enough to avoid gaming, but representative enough to reflect real production usage. We therefore built two datasets: 1. **Core distribution.** A baseline sample across public and private brands, primarily in the US and EU. 2. **Long-tail distribution.** An uncurated global sample of micro-businesses and local service providers. The results should be read with three principles in mind: 1. **First-party sources.** We rely primarily on first-party surfaces, the brand's own website and managed social profiles, and cross-check across them when possible to increase accuracy. 2. **Long-tail coverage.** We deliver strong performance on the long tail, showing that the pipeline works beyond curated cases. 3. **Non-padding.** When we return `null`, it reflects weak, missing, or ambiguous public signals. In open-web data, missing information often correlates with low brand maturity or weak digital presence. The attributes reported here are the primary inputs used to compute both production and evaluation signals in the Signal Catalog. ## Core distribution Coverage was measured on an expanded sample of 542 brands built from existing financial-industry customer datasets. The sample is 30–40% public and 60–70% private (startups and SMBs). It is mostly US and EU, with extra weight on SMBs, local businesses, and long-tail domains to stress test performance outside large enterprise brands. ### Core attributes Core attributes used to identify and resolve merchant entities. | Datapoint | Coverage | | ------------ | -------- | | Logo (Any) | 95% | | Logo (Dark) | 87.5% | | Icon (Any) | 83.8% | | Logo (Light) | 58.3% | | Symbols | 33.4% | | Colors | 97% | | Banner | 84% | **Key takeaway:** Core identity coverage remains above 95%. This indicates the system is driven by algorithmic discovery and resolution. Lower coverage for symbols and specific variants provides an organic signal of a merchant's digital and brand operation. ### Firmographic and financial data Data density supporting KYB and compliance workflows. | Datapoint | Coverage | | --------------- | -------- | | Description | 94.1% | | longDescription | 95% | | Social Links | 86.5% | | Country | 77.1% | | City | 76% | | Kind | 71% | | Founded year | 66.8% | | Employees Count | 79.3% | | ISIN | 32.1% | | Stock | 31.7% | **Key takeaway:** Coverage drops in a predictable way as fields rely more on formal disclosure and public-company status. This is expected in a mixed enterprise and long-tail sample. Financial identifiers remain limited to public companies. ## Long-tail distribution Coverage was measured on a global sample of 397 micro-businesses. These entities were randomly selected from Google Maps across a diverse set of cities and regions (without filtering for brand maturity, technical sophistication, or even the presence of a working domain). The sample spans 16 cities worldwide, including Europe, North America, Latin America, Africa, the Middle East, and Asia (e.g., Lausanne, Rotterdam, London, Barcelona, Tashkent, Dubai, Hanoi, Fukuoka, Dallas, New York, Nagpur, Accra, Lima, Cali, Durban). This dataset is designed to test performance at the extreme long tail: local, non-tech, offline-first businesses that may lack a formal brand, a maintained website, or any structured public footprint. It represents a lower bound on expected coverage. ### Core attributes Core attributes used to identify and resolve merchant entities. | Datapoint | Coverage | | ------------ | -------- | | Logo (Any) | 85.9% | | Logo (Dark) | 65.7% | | Icon (Any) | 58.4% | | Logo (Light) | 20.4% | | Symbols | 0.76% | | Colors | 79.6% | | Banner | 36.3% | **Key takeaway:** Even at the extreme long tail, 70–82% of merchants still expose at least one core identity signal. When coverage is lower (for example, for symbols), this reflects a weak or immature public footprint, which is itself a meaningful signal. ### Firmographic and financial data Data density supporting KYB and compliance workflows. | Datapoint | Coverage | | --------------- | -------- | | Description | 80.6% | | longDescription | 88.9% | | Social Links | 70.0% | | Country | 35.8% | | City | 34.5% | | Kind | 34.0% | | Founded year | 27.7% | | Employees Count | 36.5% | **Key takeaway:** Given that these are random micro-businesses with very little formal data, this level of coverage is strong. With \~70–80% descriptive and social signals, most businesses still expose enough digital surface to allow identity resolution, even when traditional firmographics are missing. # Brand API Source: https://docs.brandfetch.com/brand-api/overview The brand layer for modern products [Brand API](https://brandfetch.com/developers/brand-api) provides programmatic access to any company's brand assets through a single API call. This includes their latest logos, color schemes, fonts, images, and other firmographic information. Brand API works in real-time, if a brand is not part of our dataset, it will index the information live ensuring **global coverage** for businesses of all sizes, geography and industries. ## Implementation guide You’ll need to create an account on our [Developer Portal](https://developers.brandfetch.com/register). Creating an account is quick and easy, and will give you access to your dashboard where you’ll find your API key. The Brand API supports multiple identifier types (domain, email address, Stock or ETF ticker, ISIN, Crypto symbol). Authentication is done by passing your API key as a [Bearer Authentication](https://swagger.io/docs/specification/authentication/bearer-authentication/). ```curl Domain theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/domain/nike.com \ --header 'Authorization: Bearer ' ``` ```curl Ticker theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/ticker/NKE \ --header 'Authorization: Bearer ' ``` ```curl ISIN theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/isin/US6541061031 \ --header 'Authorization: Bearer ' ``` ```curl Crypto theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/crypto/BTC \ --header 'Authorization: Bearer ' ``` ```curl Email theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/john@example.brandfetch.com \ --header 'Authorization: Bearer ' ``` ```curl Auto-detection (legacy) theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/nike.com \ --header 'Authorization: Bearer ' ``` The shorthand route `/v2/brands/{identifier}` (without a type prefix) is still supported and auto-detects the identifier type (in the order: domain → ticker → ISIN → crypto), but explicit type routes are recommended to avoid naming collisions. The API reads an identifier that contains `@` as an email address and resolves it to its registrable domain. `john@example.brandfetch.com` returns the same response as `brandfetch.com`. The API does not store the address. Your request logs show only the resolved domain. Email addresses work on the shorthand route only. If you only have company names, use the [Brand Search API](/brand-search-api/overview) to match brand names to the most likely URLs. All requests for the domain brandfetch.com are free and will not count towards your usage/quotas. You can make as many requests to the Brandfetch’s brand as you need while you iterate on and test your integration. Once you are ready to go live, replace brandfetch.com with the domain name, email address, Stock/ETF ticker, ISIN, or Crypto symbol you want to look up. If you have custom requirements, or any questions [contact us](https://brandfetch.com/developers/contact/sales). ## Prefetching brands Brand API works in real time: the first request for a brand nobody has asked for before crawls it live, which may take a moment. When you know ahead of time which brand you will need — a user has just signed up, and their brand screen is a few steps away — ask for it in advance with a `HEAD` request on the same route: ```curl Prefetch at signup theme={null} curl --head \ --url https://api.brandfetch.io/v2/brands/jane@example.brandfetch.com \ --header 'Authorization: Bearer ' ``` The response carries no body. The status code is the answer: | Status | Meaning | | ------ | ------------------------------------------------------------------------------------------------------- | | `200` | We hold the brand. A `GET` is answered from our store. | | `202` | We do not hold it yet, and a crawl has been queued. Make the `GET` when you need the data. | | `404` | Nothing can be fetched for the identifier: an unknown ticker or ISIN, or a brand that has been removed. | | `403` | Prefetching is available on paid plans. The `x-bf-error` header reads `paid_plan_required`. | | `503` | The crawl could not be queued. Retry later; the `x-bf-error` header reads `temporarily_unavailable`. | `HEAD` accepts every identifier the `GET` does — a domain, an email address, a brand ID, a ticker, an ISIN or a crypto symbol. Prefetch requests never count towards your quota. Prefetch requests may be throttled to prevent abuse and ensure quality of service. See the [reference](/reference/brand-api-prefetch) for the full contract. ## Quotas and usage When you sign up for a free developer account, you get 100 free requests. `HEAD` requests (see [Prefetching brands](#prefetching-brands)) are not counted. If you need to make more requests, please upgrade to a paid plan. When upgrading, you can confirm your quota by looking at the `x-api-key-quota` response header. To see your current month's usage, look for the `x-api-key-approximate-usage` response header. We will also send you an email warning you upon reaching 80% of your quota. The API will return an HTTP status code 429 when the quota has been reached. In addition to a usage quota we also apply a request throughput limit to protect our service from abuse. By default, throughput is limited to a sustained 100 requests/second with some flexibility to accommodate bursts (30,000 requests / rolling 5 minute hard limit). You'll receive an HTTP status code 429 when you exceed this limit. If your use-case requires higher throughput limits, [contact us](https://brandfetch.com/developers/contact/sales). ## Overage billing When you purchase a subscription plan, you are allotted a quota depending on the payment plan. When you make more API requests than your quota allows, rather than blocking requests which are over your quota, we apply overage billing. This means that you'll never have any unexpected downtime. Requests over your quota are charged at an overage-fee rate. To set a spending limit, head to the [Developer Dashboard](https://developers.brandfetch.com/dashboard/billing) and set a hard spending limit. Set this to \$0 if you want to disable overage. Overage billing is not available on the free plan. To start using overage, please upgrade first to one of the paid plans. ## API Reference For more details, refer to our [API Reference](/reference/brand-api). # Brand Context API Source: https://docs.brandfetch.com/brand-context-api/overview Brand context built for AI agents [Brand Context API](https://brandfetch.com/developers/brand-context-api) returns a structured, narrative-rich profile of a brand for a given domain. The kind of context useful for grounding LLMs, generating on-brand content, and powering personalized experiences. For each domain, the API returns: * **Identity**: tagline, mission, description, and tags. * **Positioning**: value proposition, target audience segments, and products & services. * **Brand**: a summary of the brand's voice and visual style, with descriptive attributes. Brand Context API works in real-time. If a brand is not part of our dataset, it will be resolved live, ensuring **global coverage** for businesses of all sizes, geographies, and industries. ## Implementation guide You’ll need to create an account on our [Developer Portal](https://developers.brandfetch.com/register). Creating an account is quick and easy, and will give you access to your dashboard where you’ll find your API key. Implement or run the code below to make your first API request. ```curl curl theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/context/{domain} \ --header 'Authorization: Bearer ' \ --header 'Accept: application/json' ``` Authentication is done by passing your API key as a [Bearer Authentication](https://swagger.io/docs/specification/authentication/bearer-authentication/), the same way as the [Brand API](/brand-api/overview). All requests for the domain brandfetch.com are free and will not count towards your usage/quotas. You can make as many requests to Brandfetch’s own brand as you need while you iterate on and test your integration. Once you are ready to go live, simply replace brandfetch.com with the domain name you want to look up. If you have custom requirements, or any questions [contact us](https://brandfetch.com/developers/contact/sales). ## Query by domain You query the Brand Context API by a domain name, or by an email address on the domain: ```curl Domain theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/context/brandfetch.com \ --header 'Authorization: Bearer ' \ --header 'Accept: application/json' ``` ```curl Email theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/context/john@example.brandfetch.com \ --header 'Authorization: Bearer ' \ --header 'Accept: application/json' ``` The API resolves an email address to its registrable domain before the lookup. `john@example.brandfetch.com` returns the same context as `brandfetch.com`. The API does not store the address. Your request logs show only the domain. If you only have company names, use the [Brand Search API](/brand-search-api/overview) to match brand names to the most likely domains first. ## Content negotiation The Brand Context API supports content negotiation. Use the `Accept` request header to choose the format of the response: * `application/json` (default): returns the structured JSON object described below. * `text/markdown`: returns the brand context as a Markdown document, ready to drop directly into an LLM prompt or a Markdown-aware surface. ```curl JSON theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/context/brandfetch.com \ --header 'Authorization: Bearer ' \ --header 'Accept: application/json' ``` ```curl Markdown theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/context/brandfetch.com \ --header 'Authorization: Bearer ' \ --header 'Accept: text/markdown' ``` ## Skip crawling (cached only) By default, if a domain is not yet part of our dataset the Brand Context API resolves it live. This guarantees global coverage, but a live resolution can take several seconds. For latency-sensitive use cases, such as powering an interactive frontend, you can set the `cachedOnly` query parameter to `true`. When enabled, the API returns a brand context **only if one is already cached**, responding instantly and **without crawling** the domain: * If a cached context exists, it is returned immediately (`200`), exactly as a normal request would. * If nothing is cached, the API responds with `204 No Content` instead of resolving the domain live. ```curl Cached only theme={null} curl --request GET \ --url 'https://api.brandfetch.io/v2/context/brandfetch.com?cachedOnly=true' \ --header 'Authorization: Bearer ' \ --header 'Accept: application/json' ``` To populate the cache, make a standard request (without `cachedOnly`) for the domain. Once it has been resolved, subsequent `cachedOnly=true` requests will return it instantly. ## Response shape When requesting `text/markdown`, the response is a Markdown document covering the same information. When requesting `application/json`, the response is grouped into a few top-level objects: | Key | Type | Contains | | ------------- | ------ | -------------------------------------------------------------------------------------------- | | `meta` | object | The resolved domain, the brand's canonical name, and when the context was resolved. | | `identity` | object | Tagline, mission, description, and tags. | | `positioning` | object | Value proposition, target audience segments, and products & services. | | `brand` | object | The brand's voice and visual style, each as a narrative summary with descriptive attributes. | All four objects are present on a `200` response, and array fields come back empty rather than `null` when there is nothing to report. Unlike the rest of the Brandfetch API, which uses camelCase, the Brand Context API returns field names in `snake_case` (for example `canonical_name`, `value_proposition`, `products_and_services`) to align with conventions commonly used by the LLM tooling that consumes this data. | Field | Type | Description | | ---------------- | ------ | --------------------------------------------------------------------- | | `domain` | string | The domain the context was resolved for. | | `canonical_name` | string | The brand's canonical, human-readable name, for example `Brandfetch`. | | `resolved_at` | string | ISO 8601 timestamp, in UTC, of when the context was resolved. | On a cached response, `resolved_at` is when the context was originally resolved, not when you made the request. | Field | Type | Description | | ------------- | ---------------- | --------------------------------------------------------------------------------- | | `tagline` | string | A short tagline for the brand. | | `mission` | string | The brand's mission, in one sentence. | | `description` | string | A short paragraph on what the brand sells, who it serves, and what sets it apart. | | `tags` | array of strings | Category and market phrases that characterize the brand. | | Field | Type | Description | | ----------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ | | `value_proposition` | string | What the brand offers, who it is for, and what differentiates it. | | `target_audience` | array of objects | Buyer and user segments. Each entry has a `segment` label and a `description` of what that segment needs from the brand. | | `products_and_services` | array of objects | The brand's offerings. Each entry has a `name`, a `type` (`product` or `service`), and a `description`. | | Field | Type | Description | | ------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ | | `voice` | object | How the brand communicates: a `summary`, an `attributes` array of short adjectives, and an `avoid` array of tones the brand would not use. | | `style` | object | The brand's visual identity: a `summary` and an `attributes` array of short adjectives. | `style` describes the visual identity in prose. For logo files, color values, and font names, use the [Brand API](/brand-api/overview). Every field, with its type, is listed in the [API Reference](/reference/brand-context-api). The Markdown representation is served as `text/markdown; charset=utf-8`. It opens with the brand's canonical name as a heading, followed by the domain and the resolution timestamp, and then covers the same sections in the same order: identity, positioning (value proposition, target audience, products & services), and brand voice and style. Fields with no value are omitted rather than rendered empty. A `cachedOnly=true` request that finds nothing cached returns `204 No Content` with an empty body, whichever format you asked for, so check the status code before parsing the response. ## Quotas and usage When you sign up for a free developer account, you get 100 free requests. If you need to make more requests, please upgrade to a paid plan. When upgrading, you can confirm your quota by looking at the `x-api-key-quota` response header. To see your current month's usage, look for the `x-api-key-approximate-usage` response header. We will also send you an email warning you upon reaching 80% of your quota. The API will return an HTTP status code 429 when the quota has been reached. In addition to a usage quota we also apply a request throughput limit to protect our service from abuse. By default, throughput is limited to a sustained 100 requests/second with some flexibility to accommodate bursts (30,000 requests / rolling 5 minute hard limit). You'll receive an HTTP status code 429 when you exceed this limit. If your use-case requires higher throughput limits, [contact us](https://brandfetch.com/developers/contact/sales). ## Overage billing When you purchase a subscription plan, you are allotted a quota depending on the payment plan. When you make more API requests than your quota allows, rather than blocking requests which are over your quota, we apply overage billing. This means that you'll never have any unexpected downtime. Requests over your quota are charged at an overage-fee rate. To set a spending limit, head to the [Developer Dashboard](https://developers.brandfetch.com/dashboard/billing) and set a hard spending limit. Set this to \$0 if you want to disable overage. Overage billing is not available on the free plan. To start using overage, please upgrade first to one of the paid plans. ## API Reference For more details, refer to our [API Reference](/reference/brand-context-api). # Brand Search API Source: https://docs.brandfetch.com/brand-search-api/overview Match brand names to their domain and logo [Brand Search API](https://brandfetch.com/developers/brand-search-api) provides fast querying of brands. It lets you search by brand names and match them to their corresponding URLs, enabling you to create rich autocomplete experiences. The Brand Search API is designed to work in tandem with our other services. Once a user selects a brand, you can use its unique identifier to retrieve detailed data using our other APIs. ## Implementation guide You’ll need to create an account on our [Developer Portal](https://developers.brandfetch.com/register). Creating an account is quick and easy, and will give you access to your dashboard where you’ll find your client ID. Brand Search API is free to use and we don't ask for any attribution. Implement or run the code below to make your first API request. ```curl curl theme={null} curl --request GET \ --url "https://api.brandfetch.io/v2/search/:name?c=BRANDFETCH_CLIENT_ID" ``` Authentication is done by passing your client ID as a query parameter. The Brand Search API is a free product. Before you deploy your application to a live environment, be sure to consult our [rate limits](#rate-limits) and review our [usage guidelines](#usage-guidelines) to ensure a smooth launch. ## Usage guidelines **To use Brand Search API, you must include your client ID with every request.** Adding your client ID provides reliable access, supports fair usage, and keeps consistent performance across all requests. [Create a free account](https://developers.brandfetch.com/register) and access your client ID from the Developer Portal. To use Brand Search API, include your client ID with every request as shown below: ```curl curl theme={null} curl --request GET \ --url "https://api.brandfetch.io/v2/search/:name?c=BRANDFETCH_CLIENT_ID" ``` **We require Brand Search API to be directly embedded in your user-facing applications.** The API should be used directly as is, with all data fetched live and not altered or persisted. Your users should make requests to the API directly from their browsers. The logo image URLs provided by the Brand Search API must be hotlinked. Other data, such as brand names, should not be cached and should be used exclusively for building an autocomplete experience. Image URLs expire after 24 hours and must be refetched. For more information on the API’s availability, see our [uptime status](https://status.brandfetch.io/). We can provide custom SLAs for enterprise customers. If your use case requires more flexibility, please [contact us](https://brandfetch.com/developers/contact/sales) for a custom setup. **You cannot replicate the core user experience of Brandfetch.** The best way to ensure that your application doesn’t violate this guideline is by integrating Brandfetch into an existing app that offers more value than just the Brandfetch integration. Some examples: * ✅ The [Pitch integration](https://brandfetch.com/developers/customers/pitch) helps their users autocomplete brand names to streamline logo search within Pitch’s editor. Without this integration, the app still has a lot of value to its users. * 🚫 An unofficial Brand Search API that allows users to autocomplete brands. Without the API, the app has no content and no value to users. If you're unsure about your use case, please [contact us](https://brandfetch.com/developers/contact). ## Rate limits We offer a fair use base rate limit of 500,000 requests per month, with 200 requests per 5 minutes per IP address, which is designed to cover most small to medium applications. The rate limit should allow for roughly 30 search-sessions in a 5-minute period and is intended to discourage abuse. Use a [debounce strategy](https://developer.mozilla.org/en-US/docs/Glossary/Debounce) inbetween keystrokes to avoid hitting the rate limit. If your usage approaches the monthly limit, we may reach out to discuss an upgrade to a paid, unlimited tier. For enterprises, we provide custom solutions, including SLA agreements, custom terms, and flexible caching options to ensure optimal performance at scale. These plans are tailored to meet the needs of high-volume users. Feel free to [contact us](https://brandfetch.com/developers/contact/sales) to discuss the right plan for your use case. ## API Reference For more details, refer to our [API Reference](/reference/brand-search-api). # Changelog Source: https://docs.brandfetch.com/changelog/overview Follow along with updates across Brandfetch’s API. ## **An interactive brand card in Claude** `get_brand` now renders a full brand profile directly in the conversation on MCP Apps hosts — claude.ai and Claude Desktop. Ask Claude about a brand and the answer arrives as an interactive card instead of a wall of text: * **Six tabs.** About (description, company facts, social links), Logos, Colors, Fonts, Images, and Brand voice — the same profile the [Developer Playground](https://brandfetch.com/developers/playground) shows, adapted to chat. * **Assets you can use immediately.** Pick any logo variant, switch between its available formats, and download the file or copy a ready-to-use URL. Each asset shows its format, file size, and dimensions. * **Search without leaving the card.** Look up another brand from inside the card, and the conversation follows: the card keeps Claude's context pointed at the brand on screen, so "add that logo to the deck" always means the brand you're looking at. * **Opens on the right tab.** Ask for a specific aspect — "Okta's brand voice", "Nike's colors" — and the card opens directly on that tab. * **Native to Claude.** The card follows Claude's light and dark themes, typography, and spacing, so it reads as part of the conversation rather than an embedded web page. Text-only MCP clients are unaffected: `get_brand` returns the same brand data everywhere, and the card is a layer on top for hosts that support it. Also in this release: `send_feedback` now recognizes credit and quota errors as account state rather than product defects, and points to the [usage dashboard](https://developers.brandfetch.com) instead of filing a bug report. Connect the server at `https://mcp.brandfetch.io/mcp` — already connected clients pick up the new capabilities after removing and re-adding the connector, since hosts cache a server's tool list. See the [MCP documentation](/mcp/overview). ## **Prefetch a brand before you need it** The [Brand API](/brand-api/overview) now answers `HEAD` requests on `/v2/brands/{identifier}`. A `HEAD` tells you whether we already hold the brand — `200` — and, when we do not, queues a crawl and answers `202`, so the `GET` you make later is served from our store instead of waiting on a live crawl. The typical use is warming a brand at signup with the new user's email address, so their brand screen renders instantly. ```bash theme={null} curl --head https://api.brandfetch.io/v2/brands/jane@example.brandfetch.com \ --header 'Authorization: Bearer ' ``` `HEAD` accepts every identifier the `GET` does, never counts towards your quota, and is available on paid plans — a free plan receives `403` with `x-bf-error: paid_plan_required`. Prefetch requests may be throttled to prevent abuse and ensure quality of service. See [Prefetching brands](/brand-api/overview#prefetching-brands) and the [reference](/reference/brand-api-prefetch). ## **Bigger Logo API allowances on every plan** Every plan's monthly Logo API volume just went up, at the same price: | Plan | Before | Now | | ----------- | ------------------- | ------------------------- | | Free | 500,000 requests/mo | **1,000,000 requests/mo** | | Growth | 1M requests/mo | **5M requests/mo** | | Growth Plus | 2M requests/mo | **10M requests/mo** | | Growth Pro | 3M requests/mo | **15M requests/mo** | | Growth Max | 5M requests/mo | **20M requests/mo** | The new allowances are already live for every account — existing and new — with nothing to change on your side. Usage warnings and the request allowance introduced last month track the new volumes automatically, so if you were nearing your old limit you now have room to grow instead of a reason to worry. Brand Search API allowances are unchanged. See [rate limits](/logo-api/overview#rate-limits) and the [pricing page](https://brandfetch.com/developers/pricing). ## **Email addresses as API input** The [Brand API](/brand-api/overview) and [Brand Context API](/brand-context-api/overview) now accept an email address wherever they accept a domain. The API resolves an identifier that contains `@` (or the percent-encoded `%40`) to its registrable domain. `john@example.brandfetch.com` returns the same response as `brandfetch.com`. You do not have to parse addresses before you enrich a signup or a CRM contact. * A mailbox provider's address resolves like any other address: a gmail.com address returns the brand of gmail.com. The API does not tell you whether the domain is the contact's company. * A malformed address returns `400`, and the API does not bill the request. Refused lookups do not count against your quota. * The API does not store the address. Your request logs show only the resolved domain. Email addresses work on the shorthand `/v2/brands/{identifier}` route and on `/v2/context/{domain}`. The explicit type routes do not accept email addresses. ## **Zero data retention** Some customers — banks and other regulated businesses among them — must be able to show that their vendors keep no record of what their systems look up. For them, we can now enable zero data retention on their organization: queried domains and brand identifiers, IP addresses, user agents, referers, and query parameters stay out of every retained request record, while the usage records that billing and quota enforcement need survive. In your Usage History, identifying fields on redacted rows are empty or show the placeholder `redacted.invalid`. Zero data retention is an enterprise feature — [contact sales](https://brandfetch.com/developers/contact/sales) to have it enabled. See [zero data retention](/support/zero-data-retention) for exactly what is excluded, what is retained, and which APIs it covers. ## **Webhooks on every paid plan** Webhooks are no longer Enterprise-only. Any paid plan can now register webhook endpoints and subscribe to brands, with no contract and no sales call. Alongside opening them up, we've made them easier to run: * **Subscribe by domain.** `addWebhookSubscriptions` accepts a `domains` argument, so you no longer need to look a brand up just to get its URN. Subdomains resolve to their registrable domain, so subscribing to `blog.example.com` watches `example.com`, and a single call can name up to 1,000 brands. * **Edit and pause.** `updateWebhook` now applies your changes instead of only validating them, so you can move a webhook to a new endpoint URL, change the header we send with it, adjust which events it listens for, or rename it. Set `enabled` to `false` to stop deliveries while the endpoint and all of its subscriptions stay in place, and set it back to `true` to resume. * **Retries that span a week.** A failed delivery is now retried up to 15 times on an exponential backoff covering roughly a week, so an endpoint that's down over a weekend catches up instead of missing events. We email your organization's contacts when we give up on an event, and if an endpoint goes 14 days without accepting a single delivery we switch the webhook off and let you know. * **Filterable delivery history.** `Webhook.deliveries` takes a `filter` with `from` and `to` bounds, and cursor paging now works properly: every edge carries a resumable cursor and `hasNextPage` is accurate. Note that `first` is now enforced, defaulting to 100 and capped at 100, so a query that used to read your entire retained history in one call needs to follow the cursor. Pricing is one API credit per brand subscription when you create it, and one credit per month for every subscription you still hold. Registering an endpoint and receiving deliveries are free, however many events your brands generate, and subscriptions to `brandfetch.com` are free too, so you can wire up an endpoint and test it end to end without spending anything. Get started in the [webhooks documentation](/delivery-methods/webhooks/overview). ## **Brand Search API improvements** Results now rank by how closely they match what you typed. Popularity and our human verification still count, but only on top of relevance, so a well-known brand no longer outranks an exact match on your query. * A brand's other domains and its stock ticker now find it, so `google.fr` returns Google. Tickers are matched exactly, so a two-letter ticker can't be hijacked by an unrelated brand starting with the same letters. * Punctuation no longer gets in the way: `sainsburys` finds Sainsbury's, and `bosch home` finds Bosch-Home. * A single brand's many country domains no longer crowd out everything else. Each brand takes one slot, plus a second for a country site that's verified or claimed on Brandfetch, or for the runner-up when a brand has no generic domain. A query like `google` or `ikea` returns a full page of suggestions again. * Common prefixes no longer drop brands, so searching `brand` returns brandfetch.com. Short one and two character queries lead with the brands you'd expect, and two identical requests come back in the same order, so autocomplete suggestions stay stable. Across a benchmark of around 2,700 brand-name queries, the right brand now leads the results about a third more often, and queries that used to come back empty dropped by more than 90%. See the [Brand Search API documentation](/brand-search-api/overview). ## **Clearer Logo API errors** When the Logo CDN refuses a request, it now tells you why. Every refusal carries an `x-bf-error` header naming the exact reason, so you can read it in your browser's network panel even when the URL lives inside an `` tag and no response body ever reaches the page. `403` responses also return a JSON body with a plain-language message and a link to the docs. Previously an invalid client ID, a disabled client ID, and an unavailable region all came back as the same bare `403`. The most common one, a mistyped client ID, now says so explicitly and tells you which characters to check. Redirects to our usage guidelines and rate-limited responses carry a code too, so you can tell a hotlink block from a missing `User-Agent`. See [Errors](/logo-api/overview#errors) for the full list of codes. ## **Logo CDN request allowance is now enforced** Traffic that runs far beyond your plan's Logo CDN volume is now refused with an HTTP `429` and `x-bf-error: quota_exceeded`, and we email your billing contacts when it happens. Traffic below that threshold is unaffected, and you get heads-up emails at 80% and 100% of your allowance long before it matters. A block lifts on its own when your next billing period starts, and raising your allowance clears it within seconds, so an upgrade takes effect immediately instead of leaving you with broken images. See [rate limits](/logo-api/overview#rate-limits). ## **Transaction API improvements** The Transaction API resolves more raw descriptors to the right merchant, and more of the merchants it returns are correct. It has also stopped guessing: when a descriptor is too ambiguous to identify a merchant with confidence, the request comes back unresolved rather than returning a merchant we aren't sure about. Expect slightly more unresolved responses for genuinely ambiguous descriptors, and fewer cases where the wrong brand reaches your customer. Responses are faster and more consistent, and you can now tell a temporary failure from a descriptor we can't resolve. A `503` means we were briefly unable to process the request, so retry it. A `400` with `Failed to enrich transaction` means we couldn't confidently identify a merchant for that descriptor, so a retry won't change the answer and you should fall back to showing the raw descriptor. Previously both came back as `400` with no way to tell them apart, and a `503` never costs you a credit. Existing integrations pick up the improvements automatically. The request and response formats are unchanged. See the [Transaction API documentation](/transaction-api/overview). ## **Usage History in the developer dashboard** The [developer dashboard](https://developers.brandfetch.com) has a new Usage History screen showing your organization's individual requests, newest first, over the last 24 hours, 7 days, or 30 days. One tab covers your API traffic and the other covers Logo CDN traffic, and you can filter either by credential or by status class, so you can find failing logo requests without scanning everything by eye. API rows show the product, method, path, and status, the key that made the call, and the caller's IP and user agent. Logo CDN rows show the asset requested, whether it was served from cache, the response size, and the viewer's country. Revoked credentials still appear, so traffic from a key you rotated doesn't turn into unattributed usage. ## **Usage and credits you can trust** Requests we couldn't answer no longer cost you anything. A Brand API request counts when it returns a brand, or when it definitively reports that no brand exists for an identifier. A malformed request, a rejected key, or a failure on our side does not, so an incident on our end can no longer eat into your usage. Logo CDN usage now counts only requests that were validly signed and actually served. Every credit figure in the dashboard now reflects what your organization can actually spend: your recurring plan allowance, any paid overage, and any one-time credits you hold, rather than the recurring allowance alone. If you're on the free plan you'll no longer see an overage warning or an estimated overage charge for usage that is never billed, and the Brand API, Brand Context API, and Transaction API cards on Plans & Billing each show a real position. Organizations on unlimited plans are shown as unlimited, and any overage estimate respects the spend limit you've set. Your reported usage may read slightly lower than before as a result. ## **Ambiguous tickers and country domains now resolve** Identifiers like `BHP.AX` are genuinely ambiguous, because most two-letter exchange suffixes are also country domain endings, so a ticker can look exactly like a website and vice versa. Brand API now tries the other reading when the first one comes back empty, and an explicit `/v2/brands/ticker/{ticker}` request is always treated as a ticker. Exchange-suffixed tickers, and country domains such as `interia.pl`, that previously returned a permanent `404` now resolve. For ambiguous identifiers we still recommend the [explicit type routes](/brand-api/overview). ## **No-code integrations: Zapier, Make & n8n** Brandfetch is now available on [Zapier](https://zapier.com/apps/brandfetch/integrations), [Make](https://apps.make.com/brandfetch), and [n8n](https://n8n.io/integrations/brandfetch/). Add Brandfetch as a step in any workflow to look up a brand by domain, stock/ETF ticker, crypto symbol, or ISIN, then map its logos, colors, fonts, and company details straight into the tools you already use. Paste in your API key once and every automation on your account can reuse it: auto-enrich new CRM leads in Airtable or HubSpot, post lead alerts to Slack with the company's logo inline, or generate branded decks and outreach on the fly. Each integration is configured with clicks and takes a few minutes to set up. Get started in the [No-code integrations documentation](/integrations/overview). ## **Viewer API** The new [Viewer API](/reference/viewer-api) (`GET /v2/viewer`) tells you who a credential belongs to: the key's name and id, the organization it's attached to, and its credit usage and quota for the current period. Use it to verify an API key during integration setup, on a health check, or to show your users which Brandfetch account they're connected as. Calling it is free. It never consumes credits, it keeps validating even when your quota is exhausted, and it never returns credential material. ## **Faster Brand Context API** Brand Context API is faster and a little sharper. Domains resolve around 25% quicker, and the profiles we return score higher for accuracy and usefulness in our own evaluations. Lookups are also more forgiving: when we can't finish reading the rest of a brand's site inside our time budget, you now get a brand context built from what we did read instead of an error. The response shape is unchanged, so your existing integration picks all of this up with no work on your end. ## **SVG logos now report width and height** Logo formats delivered as SVG now report their intrinsic `width` and `height` instead of `null`, so you can size, scale, or lay out a logo without rendering it first. The values come from the SVG's own dimensions or its viewBox, rounded to whole pixels, and stay `null` when the file declares nothing usable. Newly crawled and re-crawled brands carry them, and existing brands fill in over time. See the [API Reference](/reference/brand-api). ## **MCP server updates** * **Listed and open source.** The Brandfetch MCP server is now in the official [Model Context Protocol registry](https://registry.modelcontextprotocol.io), so you can find and add it from the places you already install MCP servers. Its source is published at [github.com/Brandfetch/brandfetch-mcp-server](https://github.com/Brandfetch/brandfetch-mcp-server) under the MIT license. * **Brand assets as resources.** `get_brand` now returns logos, icons, and symbols as MCP resource links, so your assistant can read the image bytes on demand instead of carrying them through the conversation. This is the reliable route for sandboxed or network-restricted environments. * **Choose your credentials.** When you connect a client and sign in, the consent screen now lets you pick which API key and client ID the session should use, instead of always taking the most recently used one. The Keys and MCP section of the dashboard offers the same choice when you generate an MCP token. * **Send feedback from your assistant.** A new `send_feedback` tool lets you report a bug, a data-quality issue, or a feature request without leaving the conversation. See the [MCP documentation](/mcp/overview). ## **Usage warning emails** We now warn you before your Logo CDN allowance runs out. Your billing contacts get an email at 80% and again at 100% of your monthly Logo CDN request volume, at most once per billing period. Free plans get them too. Credit and overage warnings follow the same rule. Each warning in the sequence now reaches you at most once per billing period, instead of arriving again every day you keep making requests past your allowance. ## **Brand Context API updates** Four additions since the launch in May: * **Markdown output.** Send `Accept: text/markdown` and you get the full brand profile, covering identity, positioning, voice, and visual style, as a Markdown document you can drop straight into an LLM prompt. `application/json` stays the default, so existing clients are unaffected. * **Skip crawling.** Add `cachedOnly=true` to get an answer instantly, without triggering a live crawl. A cached context comes straight back, and if nothing is cached you get a `204 No Content` rather than waiting several seconds. Useful when you're populating an interactive UI and can't block on a slow request. * **Better grounded.** Brand contexts are now built entirely from what a brand publishes on its own site, so everything you get back traces to the brand's own content. Value propositions read as finished brand copy, product lists stick to real offerings, and voice descriptions no longer pick up cookie-banner or navigation text. * **Unsuccessful requests are free.** Only successful lookups are metered, and requests for `brandfetch.com` are always free, so you can build, test, and retry hard-to-reach domains without spending quota on responses you can't use. See the [Brand Context API documentation](/brand-context-api/overview). ## **Sign in to the MCP server with your Brandfetch account** Connecting the Brandfetch MCP server now uses OAuth. Your client opens a browser window, you sign in to Brandfetch and approve the connection, and the client gets its own token, with no copying keys into config files. The approval screen names the client that's asking. If your client doesn't support OAuth, or you're running somewhere non-interactive like CI, generate an MCP token in the Keys and MCP section of the [developer dashboard](https://developers.brandfetch.com/dashboard/keys) and send it as a bearer token. Get started in the [MCP documentation](/mcp/overview). ## **The Logo CDN always returns an image** A logo URL the Logo CDN can't make sense of now returns an image instead of an error. A malformed domain or identifier serves your configured fallback rather than an HTTP `400` with a JSON error body, so a bad URL in an `` tag degrades to a placeholder instead of a broken image. This also fixes a set of malformed logo URLs, such as an unusable width or height, that previously failed outright and returned nothing. You still get a real HTTP `404` whenever you ask for one with `fallback/404`. See [Logo API parameters](/logo-api/parameters). ## **Plan changes now update every allowance** When your plan changes, all of your allowances change with it. Your Logo CDN and Autocomplete request volumes are now provisioned from the plan you're on as soon as it takes effect, so an upgrade raises them immediately instead of leaving you on your previous volume. ## **Organization and account management** You can now create an additional organization from the dashboard and delete one you no longer need, alongside a new option to permanently delete your account. Both live in a dedicated Danger zone behind a confirmation. Deleting an organization permanently removes everything attached to it: API keys, client IDs, webhooks, members, invitations, and billing records. Deletion is blocked while an organization is on a paid plan or still has other members, and we tell you why before anything changes. Leaving an organization while you still belong to others now switches you to the next one instead of signing you out. If you're on a custom or enterprise plan, the dashboard now shows **View billing** instead of pointing you at sales. It opens a portal limited to your invoice history, so you can pull past invoices yourself with no risk of changing the plan your agreement is built on. ## **Brand Context API** The new [Brand Context API](/brand-context-api/overview) returns a structured, narrative-rich brand profile for a domain, covering identity, positioning, voice, and visual style. It's designed for grounding LLMs, generating on-brand content, and powering personalized experiences. ## **MCP Server** The Brandfetch MCP server is now available. It lets AI assistants (Claude, Cursor, Windsurf, and others) access brand data directly: searching brands, retrieving logos and assets, and firmographics data, all without any code on your end. Get started in the [MCP Server documentation](/mcp/overview). ## **Keys & MCP in the dashboard** The "Your keys" section of the [developer dashboard](https://developers.brandfetch.com/dashboard/keys) is now "Keys & MCP". It shows a ready to use MCP server URL for your organization with your API key and client ID already filled in, so you can copy it straight into Claude, Cursor, or another MCP client instead of assembling it yourself. See the [MCP documentation](/mcp/overview). ## **Curated brands keep their data** Brands that have been claimed by their owner, or verified by our team, are no longer refreshed by our automatic re-crawls. The logos, colors, and company details on a curated brand now stay as they were curated, instead of being replaced by whatever the next crawl of the site finds. If you maintain a brand on Brandfetch, your corrections stick. Nothing changes in how you query a brand. ## **llms.txt for the developer site** There is now a single plain text summary of Brandfetch for machines at [brandfetch.com/llms.txt](https://brandfetch.com/llms.txt). It covers what each API returns, which credential it uses, the identifier types it accepts, free and paid limits, and links to every developer page. Point an AI assistant at it when you want it to work with our APIs. ## **Brand pictures in the Brand API** The `images` array can now include a new kind of entry, `type: "picture"`: photography published on the brand's own site, alongside the banner and other images you already get. Use them for richer cards, previews, and generated content where a logo alone is too thin. Every picture carries a `pictureMetadata` object so you can choose between them without fetching the files first: the image's natural width and height, its alt text, a `sourceUrl` for the image itself, and a score and rank for how representative we think it is. A picture can arrive with an empty `formats` array, in which case `sourceUrl` is how you reach the image. Pictures are replaced whenever we re-crawl a brand, so they follow the brand's current site rather than going stale. See the [API Reference](/reference/brand-api). ## **Industries endpoint** A new endpoint returns just a brand's industry classifications: ```curl Industries theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/domain/stripe.com/company/industries \ --header 'Authorization: Bearer ' ``` It works with the explicit type routes too, so `/v2/brands/ticker/NKE/company/industries` is valid. The response is a single `industries` array with the same entries you already get inside `company`, each with its id, name, slug, emoji, parent category, and score. It reads what we already hold: a brand we do not have comes back as a `404` rather than triggering a live lookup, which makes it a good fit for classification, routing, and screening passes over domains you have already enriched. ## **The free sandbox now covers every Brand API route** Requests for `brandfetch.com` are free on every Brand API route, not just the original one. The sandbox matched `/v2/brands/brandfetch.com` alone, so the explicit type routes introduced in December, such as `/v2/brands/domain/brandfetch.com`, quietly counted against your quota. Both forms are free now, so you can iterate on an integration without spending anything. ## **Explore any brand in the playground** The [playground](https://brandfetch.com/developers/playground) lets you look up any brand and inspect what our APIs return, with no key and no sign up. Search by domain, stock or ETF ticker, ISIN, or crypto symbol, with autocomplete on brand names, then read the result as brand visuals, meaning logos, colors, fonts and images, alongside company details. ## **Manage your plan yourself** Cancelling a plan no longer means waiting on us. After you tell us why you are leaving, the dashboard takes you to your billing portal to complete the cancellation yourself, instead of showing a message saying our team will follow up. While a cancellation is pending, the dashboard shows the date your plan lapses. The dashboard also surfaces where your billing stands: when your usage passes your plan's credit allowance, an alert on the dashboard and keys pages tells you that further requests are billed at the overage rate. ## **Billing accuracy improvements** Removing someone from your organization now removes their address from your billing notification list at the same time, so a former teammate stops receiving your usage and payment emails. Free plan organizations no longer receive API credit warning emails either, since a free plan cannot run into overage. Overage is also counted within the billing period it belongs to, so the figure behind your invoice lines up with the usage you ran in that period. ## **Contact support without signing in** The support form at [brandfetch.com/contact/support](https://brandfetch.com/contact/support) is now open to everyone, so you can reach us before you have an account, or when you cannot get into the one you have. It also has a category for legal and privacy requests, which routes them to the right team. ## **Sign in with a one time code** Signing in to the [developer dashboard](https://developers.brandfetch.com) and to brandfetch.com now uses a short code we email you, instead of a magic link. Enter your email, then type the code back into the tab you started in. That removes the most common failure of link based sign in, where the link opens in a different browser than the one you started in, or gets followed by a mail scanner before you ever see it. ## **Filter adult content with allowNsfw** Brand API accepts a new `allowNsfw` query parameter. Send `allowNsfw=false` and a brand we have classified as adult content comes back as a `404` instead of a brand object, so you can keep it out of your product without checking a field on every response. Leave the parameter off and behavior is unchanged. ```curl Filter adult content theme={null} curl --request GET \ --url 'https://api.brandfetch.io/v2/brands/domain/example.com?allowNsfw=false' \ --header 'Authorization: Bearer ' ``` The `isNsfw` flag is also more accurate. It now reflects our adult content classification as well as a brand's industry categories, so a brand that reads as adult content without carrying an adult industry label is flagged correctly. `isNsfw` stays the broader of the two signals, so keep reading it if you also want to exclude brands flagged only by their industry. ## **Webhook retries carry the event data** A retried webhook delivery now carries the same event data as the first attempt. Previously a retry arrived with `data` set to `null`, so an endpoint that missed the first attempt received a delivery it could not act on and had to fetch the object itself. Retry timing, signing, and headers are unchanged. See [Delivery behaviors](/delivery-methods/webhooks/delivery-behaviors). ## **Unknown tickers and ISINs now resolve** Look up a stock ticker or an ISIN we have not indexed yet and Brand API now returns a brand instead of a `404`. We identify the listed company behind the identifier, index its brand from its own website on the spot, and attach both the ticker and the ISIN to that brand, so the same lookup is instant next time and `company.financialIdentifiers` comes back filled in with both. Expect the first request for an identifier we have never seen to take a few seconds while that happens. This closes the gap between our pre-indexed identifier lists and the wider listed universe: coverage for financial identifiers now works the way coverage for domains already did. Identifiers we cannot match to a company website still return a `404`, and ambiguous inputs resolve more reliably through the [explicit type routes](/brand-api/overview). ## **Guided quickstart in the developer dashboard** New accounts now land on a three step quickstart on the [dashboard](https://developers.brandfetch.com) home. Look up any brand by domain, ticker, ISIN, or crypto symbol and see what comes back, reveal your API key, then copy a snippet that already has your key and the brand you just searched in it, so your first working call takes a few clicks. ## **No more tiny images in brand assets** Images smaller than 16 pixels on either side are no longer stored as brand assets, so spacer graphics, tracking pixels, and stray icon fragments stop turning up among a brand's logos and images. This applies both the first time we index a brand and on every refresh after that, so existing brands clean up as they are re-crawled. ## **ETF ticker in Brand API & Logo API** We've added support for the top 10,000 ETFs provided by more than 300 US and European providers. Querying with an ETF ticker will return the logo of its provider. ```html ETF ticker theme={null} Invesco logo provided by Brandfetch ``` ## **Cryptocurrency support in Brand API & Logo API** We've added support for the top 2000 cryptocurrency symbol (e.g., `BTC`, `ETH`) to both Brand API and Logo API. You can now query Logos using crypto symbols alongside domains, stock or ETF tickers, and ISINs. ```html Crypto symbol theme={null} Bitcoin logo by Brandfetch ``` ## **Explicit Type Routes** To prevent naming collisions between identifier types, we've also introduced explicit type routes with the pattern `{type}/{identifier}` where `type` can be `domain`, `ticker`, `isin`, or `crypto`. While the original routes still work with auto-detection, **we recommend using explicit type routes** for accurate results. **Examples:** ```curl Domain theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/domain/nike.com \ --header 'Authorization: Bearer ' ``` ```curl Ticker theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/ticker/NKE \ --header 'Authorization: Bearer ' ``` ```curl ISIN theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/isin/US6541061031 \ --header 'Authorization: Bearer ' ``` ```curl Crypto theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/crypto/BTC \ --header 'Authorization: Bearer ' ``` ```curl Auto-detection (legacy) theme={null} curl --request GET \ --url https://api.brandfetch.io/v2/brands/nike.com \ --header 'Authorization: Bearer ' ``` Get started by reviewing the [Brand API documentation](/brand-api/overview) and [Logo API documentation](/logo-api/overview). ## **Query by ISIN & Stock ticker: Now available in Brand API & Logo API** We've expanded the capabilities of our Brand API and Logo API endpoints. You can now query brand data directly using financial identifiers such as ISIN (e.g., `US6541061031`) or Stock tickers (e.g., `NKE`). Previously, website URLs or Brand IDs were the primary ways to access brand information. With this update, simply input an ISIN or Stock ticker to easily retrieve brand details and logos, further streamlining integrations for financial and investment platforms. Get started by reviewing the [documentation](/brand-api/overview). ## **Transaction API: Turn payment transactions into merchant data** We've released a new endpoint called the Transaction API, enabling you to convert messy payment transactions into merchant data (e.g., logos, name, location, industry, etc.). The primary input for querying the Transaction API is a raw transaction descriptor (the line-item text on a bank or credit card statement). You provide this as the `transactionLabel` in the request body, along with a `countryCode` to narrow down the merchant’s locale. For example, a transaction label like `STARBUCKS 1523 OMAHA NE` with country code `US` can be resolved to `starbucks.com`. Get started by reading the [documentation](/transaction-api/overview). ## **404 Fallback for Logo API** We have introduced a new fallback option to the Logo API, enabling you to choose whether you want to receive a 404 response if no logo is found. This complements our existing fallback options: `transparent`, `lettermark`, and `brandfetch`. You can access the 404 fallback in the same way as the other fallback options by specifying `404` in the link: [`https://cdn.brandfetch.io/randomInvalidDomain.com/fallback/404/icon`](https://cdn.brandfetch.io/randomInvalidDomain.com/fallback/404/icon) ## Logo API Logo API is a simple CDN link that gives you access to any brand’s latest logos. Logos by Brandfetch `https://cdn.brandfetch.io/brandfetch.com?c={your-client-id-here}` It’s customizable with powerful transformation capabilities and is meant to be directly embedded in your HTML tags so the logo always remains up-to-date. **Key features:** * **Rich taxonomy:** Access not just logo icons, but also brand symbols and main horizontal logos. * **Theme support:** Access dark or light logos so you can display them on any background. * **Customizable sizing:** Adjust the logo’s height and width to fit your needs. * **Smart fallbacks:** Even when a logo isn’t available, you’ll get fallbacks. * **Stay on-brand:** Logos automatically updates to the latest brand logo, so you’re always on-brand. Best of all? [It’s free without attribution](/logo-api/overview#usage-guidelines). Get started by trying the [query builder](https://brandfetch.com/developers/logo-api) and reading the [documentation](/logo-api/overview). ## Brand Quality Score We now score brands on quality and make the score available via the Brands API. The quality score is a float between 0-1 which indicates the quality of the data for the given brand. The score is useful for when you don't want to show lower quality brands to your users. Each brand now has a new `qualityScore` attribute with it's respective score: ```json theme={null} { "name": "Brandfetch", "domain": "brandfetch.com", "qualityScore": 0.7599741515319993, ... } ``` The score is engineered to divide into thirds: Lower 3rd is poor quality, middle 3rd is OK quality, upper 3rd is high quality. Lower scores indicate that a brand is less likely to be a "real" brand. For example, where google.com will score high, my-random-blog.com will score between 0.3-0.4. The score factors in things like data-recency, whether the brand has been claimed, if it has been manually verified by our team, the brand's domain ranking on the web, as well as other factors. The score can be used to sort multiple brands in a list to determine which brand may be the best option to show to a user. The way we calculate this score may change over time such that a score for a given brand may change, but will remain aligned such that it divides quality into thirds: low, medium, high. ## Brand Firmographics We've added a few firmographic attributes to brands on the Brands API. The new attributes: number of employees, year founded, industry categorization, company kind, and geographic information about the brand's company headquarters. ```json theme={null} { "name": "Stripe", "domain": "stripe.com", "company": { "employees": 1001, "foundedYear": 2010, "industries": [ { "score": 1, "id": "37", "name": "Programming and Developer Software", "emoji": "🖥", "parent": { "emoji": "🖥", "id": "28", "name": "Computers Electronics and Technology", "slug": "computers-electronics-and-technology" }, "slug": "programming-and-developer-software" }, { "score": 1, "id": "28", "name": "Computers Electronics and Technology", "emoji": "🖥", "parent": null, "slug": "computers-electronics-and-technology" } ], "kind": "PRIVATELY_HELD", "location": { "city": "South San Francisco", "country": "United States", "countryCode": "US", "region": "Americas", "state": "California", "subregion": "Northern America" }, }, ... } ``` More details on the available attributes can be found in the API documentation [here](/reference/brand-api). ## Brand is NSFW? We've added a `isNsfw` convenience attribute to the root of the brand object on the Brands API response. When the value of `isNsfw` is `true`, we're indicating that we believe the brand to be, contain, or relate to adult content such as pornography (both photographic and animated) as well as adult-related like online sex shops. ```json theme={null} { "name": "Example", "domain": "adult-content.xxx", "isNsfw": true, ... } ``` ## Brand industry classifications We now classify brands into one or more industry categories and make this data available through the Brands API. The industry is returned on brands' company attribute: ```json theme={null} { "name":"Stripe", "domain": "stripe.com", "company": { "industries": [ { "score": 1, "id": "37", "name": "Programming and Developer Software", "emoji": "🖥", "parent": { "emoji": "🖥", "id": "28", "name": "Computers Electronics and Technology", "slug": "computers-electronics-and-technology" }, "slug": "programming-and-developer-software" }, { "score": 1, "id": "28", "name": "Computers Electronics and Technology", "emoji": "🖥", "parent": null, "slug": "computers-electronics-and-technology" } ], ... }, ... } ``` More details on the available attributes can be found in the [API Reference](/reference/brand-api). In the coming weeks we will release a free Taxonomy API for retrieving our industry taxonomy. In the meantime view the complete industry list [here](https://docs.google.com/spreadsheets/d/1N44nMfVtPCFM4ebTcmRlqbyxjFtDAGVuqd0mh0dcOU0/edit?usp=sharing). ## Refreshed Developer Dashboard We've rolled out an updated developer dashboard. The new dashboard better communicates your API usage and makes it easier to monitor your API requests. Here’s what we've added: * **Overage Budget Limit Control**: You can now set your own overage budget limit. Don't want to spend more than you planned? Set it up right in the dashboard. * **API Usage**: Keep an eye on your API usage. Simple and clear to help you track what you're using. * **Usage History**: See your usage over the past months. ## Overage billing budget hard limit controls In November we released overage billing for paid customers which let's customers make requests beyond their plan quotas. Via the developer dashboard, customers can now also set a spending hard limit to better control costs of overage fees. This makes it possible to go over quota, but not go being a certain dollar amount. The default monthly budget is set at \$100 USD. ## Pseudo-Sandbox All requests for the brand `brandfetch.com` are now free and will not count towards your usage quota. For example, if you fetch the brandfetch.com brand via `GET` `https://api.brandfetch.com/v2/brands/brandfetch.com`, your request will not count towards your quota. You can make as many requests for the brandfetch.com brand as you need while you iterate on and test your integration. ## "photographic" and "portrait" asset tags for logos and icons To give you more insight into the assets you work with, we've introduced a powerful new tagging feature. Now, assets such as Logos and Icons come with descriptive tags that provide a quick understanding of their characteristics. For instance, you might see the "photographic" tag associated with an asset, indicating that the image has realistic elements, which might differ from the standard vector logos typically used by brands. Similarly, the "portrait" tag suggests that the asset includes a portrait-like image, offering a personal touch often used by sole proprietors or small brands. These tags are designed to streamline your search and selection process, allowing you to quickly identify the type of asset you need and want to use with your customers. Check our our [API documentation](/reference/brand-api) for further details. ## Overage Billing We are thrilled to announce a frequently requested update to our subscription payment plans that will provide you with greater flexibility over your usage. Starting this month, we're saying goodbye to the hard limits on API requests that could disrupt your business. No more interruptions. Instead, we understand that your demand may sometimes exceed your quota, and we want to support your growth every step of the way. Here’s what’s changing: * **No more hard stops**: Once you hit your usage quota, you won't face immediate cutoffs anymore. Our system will continue to seamlessly fulfill your API requests. * **Transparent overage fees**: Each additional request over your quota will now be billed at a \$0.1 per request. Upgrade your billing plan at any time to take advantage of bucket discounts. * **End-of-month overage billing**: Any overages will be billed at the end of the month, allowing you to manage your budget without any mid-month surprises. To disable or limit your overage fees, log into your [developer dashboard](https://developers.brandfetch.com) and set a spending limit. Set the limit to \$0 to completely disable overage. Overage billing is not available on the Free plan. To start using overage, please upgrade first to one of the paid plans. ## longDescription property on brands Introducing `longDescription`: in-depth brand narratives We've heard your feedback! Alongside our flexible API request limits, we're excited to introduce an enhancement to our Brand API that will enrich the data you receive about each brand. While our description field provided a short blurb for brands, there was a growing need for more comprehensive descriptions, including for use with generative AI products to create content such as videos and other media. Here’s what’s new: * **`longDescription` property**: Dive deeper with `longDescription`, a new property in the Brand API's response that offers an extensive description about each brand. * **Richer brand stories**: These longer descriptions encapsulate the essence of a brand, giving you more context and content to engage with your audience. By weaving in the brand's history, industry standing, and product range, `longDescription` gives you the data to generate answers to question from your users and provides the context to derive further actions. * **Seamless integration**: The new property is available right now. You can start fetching more detailed brand narratives without any changes to your current setup. `longDescription` is already being returned in in your requests today. ## The Brand Search API We are pleased to announce that we've released the Brand Search API 🎉 The Brand Search API is a powerful tool designed to help users find a brand based on its name. Whether you're looking to build a brand autocomplete feature or simply want to search for a specific brand, this API has you covered. Feel free to check out [our documentation](/brand-search-api/overview) to learn more about it! ## Usage & Quota Notification 1. Every user of the Brand API will now be notified via email if their usage goes beyond 80% of the allocated limit. 2. Users can view their quota by checking `x-api-key-quota`, and can also keep track of their usage for the current month by referring to `x-api-key-approximate-usage`. 3. The API will return an HTTP status code 429 when the quota has been reached. ## Dark & Light Logos You can now retrieve both the dark and light versions of the logo, the symbol and the icon (see example below). 🌗 ```JSON theme={null} "logos": [ { "type": "logo", "theme": "light", "formats": [ { "src": "https://asset.brandfetch.io/idL0iThUh6/id9WE9j86h.svg", "background": "transparent", "format": "svg", "size": 15555 } ] }, { "type": "logo", "theme": "dark", "formats": [ { "src": "https://asset.brandfetch.io/idL0iThUh6/idWbsK1VCy.png", "background": "transparent", "format": "png", "height": 215, "width": 800, "size": 33937 }, { "src": "https://asset.brandfetch.io/idL0iThUh6/idtCMfbWO0.svg", "background": "transparent", "format": "svg", "height": null, "width": null, "size": 15567 } ] }, { "type": "symbol", "theme": null, "formats": [ { "src": "https://asset.brandfetch.io/idL0iThUh6/iddCQ52AR5.svg", "background": "transparent", "format": "svg", "size": 2215 } ] }, { "type": "icon", "theme": "dark", "formats": [ { "src": "https://asset.brandfetch.io/idL0iThUh6/idls3LaPPQ.png", "background": null, "format": "png", "height": 400, "width": 400, "size": 2565 } ] }, { "type": "other", "theme": null, "formats": [ { "src": "https://asset.brandfetch.io/idL0iThUh6/idXGq6SIu2.svg", "background": "transparent", "format": "svg", "size": 2215 } ] } ] ``` # Clearbit Logo API Source: https://docs.brandfetch.com/comparisons/clearbit How Brandfetch's Logo API compares to Clearbit's discontinued Logo API Clearbit's Logo API shut down in December 2025 and no longer serves logos. If `logo.clearbit.com` is still in your codebase, see the [migration guide](/guides/migrate-from-clearbit-logo-api) to switch over. For nearly a decade, Clearbit's Logo API was the default way to drop a company logo into an app with a single request to `https://logo.clearbit.com/{domain}`. It shut down in December 2025 as part of Clearbit's wind-down under HubSpot, so any integration still pointed at it is now broken. Here's how Brandfetch compares to what Clearbit's Logo API used to offer. ## Brand quality & time to value Clearbit's Logo API pulled from a fixed dataset collected from public web sources. It didn't index new domains on the fly, so a domain that wasn't already in the dataset simply returned a 404. Brandfetch resolves brands live, if a domain isn't indexed yet, it's discovered on the spot, which is how the dataset holds [95% logo coverage in its core distribution and 86% even at the extreme long tail](/accuracy/coverage-and-quality) of small, non-tech businesses. Time to first logo is the same shape for both (a single request), but what happens when a logo can't be found differs. Clearbit returned a plain 404 with no fallback options. Brandfetch lets you choose a lettermark, its own mark, a transparent placeholder, or a 404, so you decide the outcome up front instead of debugging a broken image later. ## Quick comparison | | Brandfetch | Clearbit Logo API (former) | | ---------------- | ------------------------------------------------------------- | ------------------------------------------------ | | Status | Actively maintained | Shut down, December 2025 | | Free tier | 1,000,000 requests/mo | Free, no published request quota | | Attribution | Never required | Required, a visible link back to clearbit.com | | Identifiers | Domain, ticker, ISIN, crypto | Domain only | | Customization | Size, format, theme, type, and fallback, all as path segments | Basic `size`, `format`, `greyscale` query params | | Fallback options | Lettermark, Brandfetch mark, transparent, 404 | None, missing logos returned a plain 404 | ## How requests compare **Clearbit (former)** ```text theme={null} https://logo.clearbit.com/nike.com ``` **Brandfetch** ```text theme={null} https://cdn.brandfetch.io/nike.com?c=BRANDFETCH_CLIENT_ID ``` Brandfetch was designed as a drop-in replacement: the same domain-based lookup, with a client ID added and a much richer set of optional parameters. ## Why teams choose Brandfetch * **Actually maintained.** Clearbit's Logo API is gone for good. Brandfetch is actively developed and used in production by Canva, Typeform, and Experian. * **No attribution required.** Clearbit's free usage required a visible link back to clearbit.com on every page showing a logo. Brandfetch never asks for one. * **Richer identifiers.** Beyond domains, look up logos by stock/ETF ticker, ISIN, or crypto symbol. * **More control over output.** Theme variants, logo type variants (icon, logo, symbol), and four fallback strategies, none of which Clearbit's Logo API offered. Migrating existing Clearbit URLs? Follow the [step-by-step migration guide](/guides/migrate-from-clearbit-logo-api). ## Get started See the full feature set and implementation guide Free account, no credit card required # DuckDuckGo Favicon API Source: https://docs.brandfetch.com/comparisons/duckduckgo-favicon-api Why DuckDuckGo's icon endpoint isn't a substitute for a real logo API DuckDuckGo exposes an internal icon-fetching endpoint at `icons.duckduckgo.com` that some developers repurpose to display company "logos" for free. Like Google's favicon endpoint, it wasn't built or documented for this use case. This is an unofficial DuckDuckGo service with no published support, uptime guarantee, or terms for third-party use. It can change or stop working at any time. ## Brand quality & time to value There's no brand dataset behind this endpoint either, it returns whatever `.ico` a site happens to expose, or a generic placeholder with a 404 status if it doesn't. Brandfetch resolves an actual logo for 95% of brands in its core distribution, and 86% even at the extreme long tail of small, non-tech businesses, [measured and published openly](/accuracy/coverage-and-quality). Failures surface as that generic placeholder in your UI: you find out a logo is missing when a user reports it, not before. Brandfetch's fallback options mean you decide up front what happens when a logo isn't available, instead of debugging it in production. ## Quick comparison | | Brandfetch | DuckDuckGo Favicon API | | --------------- | ------------------------------------------------------------- | ----------------------------------------------------------- | | Status | Actively maintained, documented | Unofficial, unsupported | | What it returns | The brand's actual logo, icon, or symbol | The site's favicon | | Format | PNG, JPG, WebP, SVG | The site's raw `favicon.ico` | | Size | Any size via `w`/`h`, aspect ratio preserved | Whatever sizes the site's `.ico` contains, commonly 16-48px | | Theme variants | Light, dark | Not available | | Fallback | Lettermark, Brandfetch mark, transparent, 404 | Generic placeholder icon, served with a 404 | | Identifiers | Domain, ticker, ISIN, crypto | Domain only | | Rate limits | 1,000,000 requests/mo free, with documented throughput limits | None published | ## How requests compare **DuckDuckGo Favicon API** ```text theme={null} https://icons.duckduckgo.com/ip3/nike.com.ico ``` **Brandfetch** ```text theme={null} https://cdn.brandfetch.io/nike.com/icon?c=BRANDFETCH_CLIENT_ID ``` ## Why teams choose Brandfetch * **Real logos, not favicons.** ICO favicons are tiny, often generic, and not meant to represent a brand in a product UI. * **Predictable failure handling.** DuckDuckGo's endpoint swaps in a generic placeholder when a favicon is missing. Brandfetch gives you four documented fallback strategies to choose from instead. * **Built for production.** 100% uptime and documented rate limits, backed by a team that supports it. ## Get started See the full feature set and implementation guide Free account, no credit card required # Firecrawl Source: https://docs.brandfetch.com/comparisons/firecrawl How Firecrawl's branding extraction compares to Brandfetch's brand data APIs Firecrawl is a web scraping and crawling API built for AI agents. It turns any URL into markdown, structured JSON, or a screenshot, and its "branding" format extracts a logo, color palette, fonts, and spacing from a live page. That output overlaps with what Brandfetch serves, so this page compares the two on brand data: what you get, how it's sourced, and what it costs. ## Brand quality & time to value Firecrawl doesn't maintain a brand dataset. A branding scrape extracts whatever is in the page's current HTML, results are cached for up to two days by default, then re-rendered, with no published coverage numbers either way. Brandfetch maintains verified brand records and [publishes its coverage openly](/accuracy/coverage-and-quality): in its core distribution, logos resolve for 95% of brands, colors for 97%, and company descriptions for 94%, and logo coverage holds at 86% even at the extreme long tail of small, non-tech businesses. That difference compounds at scale. Firecrawl bills a credit on every request, even when the response comes from its cache. Brandfetch's lookup is instant and consistent, the hundredth request for a domain gets the same verified record as the first. ## Quick comparison | | Brandfetch | Firecrawl | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | Core product | Dedicated brand data platform | Web scraping/crawling API for AI agents | | How brand data is sourced | Pre-indexed, verified brand records | Rendered live from the page's HTML | | Brand data returned | Typed logos (icon, logo, symbol), full color palette, fonts, banners, description, firmographics (industry, employees, location, founded year) | Page-derived logo, palette, fonts, typography, spacing, favicon/og:image | | Request type | REST `GET` returning JSON, plus hotlinkable logo CDN URLs | Server-side POST, returns JSON | | Speed | Instant, pre-indexed lookup | Seconds for a fresh render, faster from its short-lived cache | | Published coverage | 95% logos, 97% colors in core distribution | None published | | Free tier | Brand API: 100 requests to try it; Logo API: 1,000,000 requests/mo | 1,000 credits/mo (a branding scrape is 1 credit, JSON extraction is 5) | | Identifiers | Domain, ticker, ISIN, crypto | URL only | ## How requests compare One branding scrape against one Brand API lookup for the same company: **Firecrawl** ```python theme={null} from firecrawl import Firecrawl firecrawl = Firecrawl(api_key="FIRECRAWL_API_KEY") result = firecrawl.scrape(url="https://nike.com", formats=["branding"]) print(result.branding.logo) ``` **Brandfetch** ```bash theme={null} curl "https://api.brandfetch.io/v2/brands/domain/nike.com" \ -H "Authorization: Bearer BRANDFETCH_API_KEY" ``` One response carries the brand's logos in every format and theme, the full color palette, fonts, banners, description, and company firmographics. And when all you need is the logo image itself, the [Logo API](/logo-api/overview) skips the JSON entirely, `https://cdn.brandfetch.io/nike.com?c=BRANDFETCH_CLIENT_ID` drops straight into an `img` tag. Firecrawl is a good fit if you're already scraping pages for other content and want brand hints as a byproduct, or if the data you need only exists on a rendered page. If brand data is the actual goal, a verified, pre-indexed record avoids rendering pages to reconstruct it. ## Build vs. buy Reaching for a scraper to get brand data is really a decision to build. Firecrawl hands you raw extraction, and everything that makes it production-grade is yours to own: designing the extraction schema, catching pages that return the wrong logo or none at all, choosing fallback behavior, deciding when cached results are stale, and re-running the pipeline as sites redesign. None of that work ends, because the web keeps changing underneath it. Buying the data means that pipeline already exists and is someone else's job to maintain. Brandfetch indexes, verifies, and refreshes brand records continuously, publishes [the coverage you can expect](/accuracy/coverage-and-quality), and serves the result as a single lookup. Your engineering time goes into your product instead of into keeping a scraper honest. ## Why teams choose Brandfetch * **Verified records, not page guesses.** Brandfetch's dataset is pre-indexed and curated, not extracted on the fly from whatever a page's HTML happens to expose. * **The whole brand in one call.** Typed logos, palette, fonts, banners, description, and firmographics come back together, no schema to design, no extraction to tune. * **Hotlinkable logos on top.** The Logo API serves the image directly from a CDN with size, theme, and fallback control, something a scraping response can't do. * **Published coverage.** Coverage numbers are [measured and published](/accuracy/coverage-and-quality), so you know how it behaves beyond the domains you demo. ## Beyond brand data Firecrawl's core product is a general-purpose web scraping and crawling API: turning any URL into markdown, HTML, a screenshot, or schema-guided structured JSON, with search and agent-style page interaction on top. Brand extraction is one format among many, and Brandfetch doesn't compete with the rest of it, there's no scraping, crawling, or page interaction in its APIs. If you need arbitrary content off arbitrary pages, Firecrawl is the right tool. If you need brand data specifically, Brandfetch's pre-indexed dataset ([Brand API](/brand-api/overview): logos, colors, fonts, banners, firmographics) plus the [Brand Context API](/brand-context-api/overview) for narrative, LLM-ready brand context avoids re-scraping the same sites on every request. ## Get started See everything a brand record contains and how to query it Free account, no credit card required # Google Favicon API Source: https://docs.brandfetch.com/comparisons/google-favicon-api Why Google's unofficial favicon endpoint isn't a substitute for a real logo API Google's `s2/favicons` endpoint fetches a website's favicon, not its logo, but it's free and shows up often as a quick hack for displaying company "logos." It's worth understanding what it actually returns before relying on it. Google doesn't publish or officially support this endpoint. It's unmaintained, has no uptime guarantee, and can change or disappear at any time. ## Brand quality & time to value There's no brand dataset behind Google's endpoint, it returns whatever favicon happens to be declared in a site's HTML at request time, with no check that it represents the brand at all. Brandfetch resolves an actual logo for 95% of brands in its core distribution, and 86% even at the extreme long tail of small, non-tech businesses, [measured and published openly](/accuracy/coverage-and-quality). That gap turns into engineering time, not just a worse-looking result. Teams pulling from Google's endpoint end up writing their own detection for missing, generic, or wrong-looking favicons before they can ship. A link that's already been verified against real brand data skips that work entirely. ## Quick comparison | | Brandfetch | Google Favicon API | | --------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | Status | Actively maintained, documented | Unofficial, unsupported | | What it returns | The brand's actual logo, icon, or symbol | The site's favicon, 16px by default | | Max size | Any size via `w`/`h`, aspect ratio preserved | Capped by the icons the site itself exposes, a 256px request can come back at 192px, 32px, or less | | Formats | PNG, JPG, WebP, SVG | PNG only | | Theme variants | Light, dark | Not available | | Fallback | Lettermark, Brandfetch mark, transparent, 404 | Generic globe icon, served with a 404 | | Identifiers | Domain, ticker, ISIN, crypto | Domain only | | Rate limits | 1,000,000 requests/mo free, with documented throughput limits | None published, aggressive use may be throttled | ## How requests compare **Google Favicon API** ```text theme={null} https://www.google.com/s2/favicons?domain=nike.com&sz=128 ``` **Brandfetch** ```text theme={null} https://cdn.brandfetch.io/nike.com/w/128/h/128/icon?c=BRANDFETCH_CLIENT_ID ``` ## Why a favicon isn't a logo Favicons are designed to be legible at 16x16 pixels in a browser tab, not to represent a brand in a product UI. Most sites' favicons are cropped, low-resolution, or a generic icon unrelated to the brand's actual logo. There's no way to request a full logo, a dark-mode variant, or a specific brand asset type from Google's endpoint, because it was never built to serve one. ## Why teams choose Brandfetch * **Real logos, not favicons.** Every request pulls from Brandfetch's brand dataset, not a compressed browser-tab icon. * **Built for production.** 100% uptime and documented rate limits, backed by a team that maintains it. * **Actual customization.** Size, format, theme, type, and fallback are all first-class parameters. ## Get started See the full feature set and implementation guide Free account, no credit card required # Logo.dev Source: https://docs.brandfetch.com/comparisons/logo-dev How Logo.dev's Logo API compares to Brandfetch's Logo API Logo.dev started as a hosted logo image API, built by the same team behind Clearbit's Logo API as its successor, retrieving company logos from a domain, ticker, ISIN, or crypto symbol through a simple image URL. It's since grown into a broader brand data platform, with search, company data, and transaction lookup products alongside the logo endpoint. The comparison below focuses on the two Logo APIs specifically; see [Beyond logos](#beyond-logos) for how the wider platforms stack up. ## Brand quality & time to value Both APIs resolve in a single request, so time to first logo is about the same either way. The real difference shows up once you're live and requesting logos for domains you haven't hand-picked in a demo: Brandfetch publishes its actual [coverage numbers](/accuracy/coverage-and-quality). A logo resolves for 95% of brands in the core distribution, and 86% even at the extreme long tail of small, non-tech businesses. Logo.dev doesn't publish comparable figures, so there's no way to check how it performs outside the brands you happen to test. ## Quick comparison | | Brandfetch | Logo.dev | | ------------------------ | -------------------------------------------------------------- | --------------------------------------------------------------- | | Free tier | 1,000,000 requests/mo | 500,000 requests/mo | | Attribution on free tier | Never required | Required for commercial use | | Identifiers | Domain, ticker, ISIN, crypto | Domain, ticker, ISIN, crypto, name | | Formats | PNG, JPG, WebP (default), SVG (free, on `logo`/`symbol` types) | JPG, PNG, WebP, SVG (Enterprise plans only) | | Logo type variants | Icon, logo, symbol | Not on the image API (wordmark only via the Pro-plan Brand API) | | Theme variants | Light, dark | Light, dark, auto | | Fallback options | Lettermark, Brandfetch mark, transparent, 404 | Monogram, 404 | | Greyscale | Apply via CSS `filter` | Built-in parameter | ## How requests compare Both APIs work the same way: a CDN URL built from a domain (or other identifier), with your key passed as a query parameter. **Logo.dev** ```text theme={null} https://img.logo.dev/nike.com?token=LOGO_DEV_PUBLISHABLE_KEY ``` **Brandfetch** ```text theme={null} https://cdn.brandfetch.io/nike.com?c=BRANDFETCH_CLIENT_ID ``` ## Why teams choose Brandfetch * **No attribution, on any plan.** Logo.dev's free "Community" tier requires a visible link back to Logo.dev for commercial use. Brandfetch never asks for one. * **SVG and type variants included for free.** Logo.dev reserves SVG for Enterprise customers. Brandfetch includes SVG output and icon/logo/symbol variants on every plan. * **Reliable at scale.** Brandfetch runs at 100% uptime and is trusted in production by Canva, Typeform, and Experian. ## Beyond logos Logo.dev isn't just a logo API either. It also offers a Search API (name-to-domain matching), a Describe API (structured company data: name, description, colors, socials), a Brand API (full brand profile: logo, brandmark, banners, colors, description, socials), and an early-access Transaction API (merchant identification from card transactions). Brandfetch's broader suite covers similar ground: [Brand API](/brand-api/overview) for a full brand profile, [Brand Context API](/brand-context-api/overview) for LLM-ready brand context, [Brand Search API](/brand-search-api/overview) for name-to-domain matching, [Transaction API](/transaction-api/overview) for merchant identification, and an [MCP server](/mcp/overview) that exposes all of it to AI assistants like Claude and Cursor. If you're evaluating the two platforms as a whole rather than just their logo endpoints, compare those products directly rather than relying on the logo-only comparison above. ## Get started See the full feature set and implementation guide Free account, no credit card required # Data ingestion & operationalization Source: https://docs.brandfetch.com/delivery-methods/data-ingestion ## Recommended ingestion The typical deployment for Brandfetch enterprise customers begins with an initial bulk delivery of the full dataset, followed by subscriptions for incremental updates. Newly observed merchants are resolved through the API and then maintained through webhook notifications. In production, the initial dataset is delivered as a bulk file in CSV or JSON format, transferred to the customer's S3 or SFTP environment, or made available for secure download. After the initial load, updates are delivered through a combination of webhooks and targeted API calls. Most large customers adopt a hybrid model: a one-time bulk load to establish baseline coverage, followed by continuous updates to maintain freshness. This approach minimizes operational overhead while keeping the dataset current. We can also support alternative ingestion paths based on customer constraints or internal architecture. Our engineering team reviews this during implementation to align on the preferred delivery model. ## Delivery methods Fetch data on demand over HTTPS with a simple, typed REST interface Receive push notifications whenever a brand you track is updated Request exactly the fields you need in a single, typed query # GraphQL Source: https://docs.brandfetch.com/delivery-methods/graphql ## What is GraphQL? [GraphQL](https://graphql.org/) is a query language for APIs that lets you request exactly the fields you need in a single, typed request, with no over-fetching and no chained calls. Brandfetch's GraphQL endpoint is available at `https://graphql.brandfetch.io` and authenticates with the same API key as the REST APIs. ## GraphQL Playground Explore the GraphQL API using the interactive playground: * [Apollo Studio playground](https://studio.apollographql.com/sandbox/explorer?endpoint=https%3A%2F%2Fgraphql.brandfetch.io) ## GraphQL schema definition You can find a guide on previewing the full schema reference in the following sections: * [Appollo Studio schema overview](https://studio.apollographql.com/sandbox/schema/sdl?selectedSchema=%23%40%21api%21%40%23\&endpoint=https%3A%2F%2Fgraphql.brandfetch.io) # REST API Source: https://docs.brandfetch.com/delivery-methods/rest-api Fetch brand data on demand over HTTPS with a simple, typed REST interface. ## What is the REST API? The REST API is the primary way to retrieve brand data from Brandfetch. Each API is a standard HTTPS endpoint that returns JSON and authenticates with your API key. Request a brand by domain, ticker, ISIN, or crypto address and get logos, colors, fonts, and company details back in a single call. Use the REST API when you need brand data on demand, whether you're enriching records in real time, powering search and autocomplete, or resolving newly observed merchants before maintaining them through [webhooks](/delivery-methods/webhooks/overview). ## API references Explore the full endpoint reference, parameters, and response schemas: Fetch logos, colors, fonts, and company details Brand context built to ground AI agents and LLMs Match brand names to their domain and logo Turn payment transactions into merchant data Verify your API key and see who you're connected as # Best practices Source: https://docs.brandfetch.com/delivery-methods/webhooks/best-practices Review these best practices to make sure your webhooks remain secure and function well with your integration. ## Handle duplicate events Webhook endpoints might occasionally receive the same event more than once. You can guard against duplicated event receipts by making your event processing idempotent. One way of doing this is logging the events you’ve processed, and then not processing already-logged events. Each event payload includes an event URN, a unique identifier for the event, which can be used as an idempotency key. ## Only listen to event types your integration requires Configure your webhook endpoints to receive only the types of events required by your integration. Listening for extra events (or all events) puts undue strain on your server and we don’t recommend it. You can change the events that a webhook endpoint receives by updating the webhook object using the `updateWebhook` [mutation](/delivery-methods/graphql). ## Handle events asynchrounously The volume of events that get generated can be spike-y. A data enrichment may result in millions of objects being updated in a very short period of time. Configure your handler to process incoming events with an asynchronous queue. You might encounter scalability issues if you choose to process events synchronously. Any large spike in webhook deliveries (for example, during a large data enrichment) might overwhelm your endpoint hosts. Asynchronous queues allow you to process the concurrent events at a rate your system can support. For example, your webhook endpoint could simply verify a payload and then push the event directly to a queue (like AWS SQS) where you can then process the events with better concurrency control. ## Receive events with an HTTPS server You must use an HTTPS URL for your webhook endpoint. Brandfetch validates that the connection to your server is secure before sending your webhook data. For this to work, your server must be correctly configured to support HTTPS with a valid server certificate. ## Verify events are sent from Brandfetch Verify webhook signatures to confirm that received events are sent from Brandfetch. Brandfetch signs webhook payload sent to your endpoints by including a signature in each event’s `Webhook-Signature` header. This allows you to verify that the events were sent by Brandfetch, not by a third party. ## Preventing replay attacks A replay attack is when an attacker intercepts a valid payload and its signature, then re-transmits them. To mitigate such attacks, Brandfetch includes a timestamp in the `Webhook-Signature` header. Because this timestamp is part of the signed payload, it’s also verified by the signature, so an attacker can’t change the timestamp without invalidating the signature. If the signature is valid but the timestamp is too old, you can have your application reject the payload. We recommend a tolerance of no greater than 5 minutes between the timestamp and the current time. Use Network Time Protocol (NTP) to make sure that your server’s clock is accurate and is in-sync with the time on Brandfetch’s servers. Brandfetch generates the timestamp and signature each time we send an event to your endpoint. If Brandfetch retries an event (for example, your endpoint previously replied with a non-2xx status code), then we generate a new signature and timestamp for the new delivery attempt. ## Example code for handling signature and timing verification ```javascript JavaScript theme={null} import crypto from "node:crypto"; const TIMESTAMP_TOLERANCE_IN_MILISECONDS = 2 * 60 * 1000; // 2 minutes function hasVerifiedPayload({ sharedWebhookSecret, headers, rawRequestBody }) { const webhookId = headers["webhook-id"]; const signature = headers["webhook-signature"].split(",")[1]; const timestamp = Number(headers["webhook-timestamp"]); const signatureAlgorithm = headers["webhook-signature-algorithm"]; const now = Date.now(); const signatureIsOk = crypto .createHmac(signatureAlgorithm, sharedWebhookSecret) .update(`${webhookId}.${timestamp}.${rawRequestBody}`) .digest("hex") === signature; const timingIsOk = timestamp < now && timestamp > now - TIMESTAMP_TOLERANCE_IN_MILISECONDS; return signatureIsOk && timingIsOk; } ``` ## Quickly return a 2xx response Your endpoint must quickly return a successful status code (2xx) prior to any complex logic that could cause a timeout. For example, you must return a 200 response before updating any records in your database or making additional API requests. # Delivery behaviors Source: https://docs.brandfetch.com/delivery-methods/webhooks/delivery-behaviors This section helps you understand different behaviors to expect regarding how Brandfetch sends events to your webhook endpoint. ## Retry behavior A delivery attempt counts as failed when your endpoint answers with anything other than a 2xx status code, when it does not respond within 16 seconds, or when it cannot be reached at all. Brandfetch retries a failed delivery up to 15 times after the first attempt, so a single event gets at most 16 attempts against your endpoint, and the final attempt lands a little under eight days after the first. The wait between attempts widens as the retries progress: the first retry follows immediately, the next few are seconds and then minutes apart, the gaps after that stretch to several hours, and the last attempts are a day apart. An endpoint that is down for a weekend, or for several days, still receives the events it missed once it starts accepting deliveries again. Every attempt appears as its own entry in your [delivery history](/delivery-methods/webhooks/setup#debugging-delivery-issues), with the status code and any error message we recorded, so you can count the attempts made for an event and see what your endpoint returned each time. If your webhook has been disabled or deleted by the time a retry comes due, that retry and any remaining retries of the event are dropped. If you disable and then re-enable the webhook before the retry comes due, the retry is attempted as normal. When the last attempt fails, Brandfetch stops retrying that event and never sends it to your endpoint again. We email your organization’s contacts with the event type, the number of attempts made, and the status code we received on the final attempt. While an endpoint stays broken you receive at most one of these emails per webhook per week, however many events are abandoned in the meantime. A successful delivery clears that limit, so an endpoint that recovers and later breaks again is not left silent. ## Disable behavior If your endpoint goes 14 consecutive days without accepting a single delivery, Brandfetch switches the webhook off and emails your organization’s contacts to tell you. The check runs on failed deliveries, so it is the first failure after the fourteenth day that switches the webhook off, and the email reports how long the endpoint had been failing along with the status code from that attempt. The 14 days are measured as an unbroken run of failures. Any successful delivery resets the count, so an endpoint that fails intermittently and then recovers is never switched off automatically; only one that has accepted nothing for two full weeks is. A webhook that has been switched off receives no further deliveries, including retries of events that were already scheduled. Its subscriptions are left in place: they stay active and keep renewing every month until you remove them, so removing the subscriptions is what ends the monthly charge for them. Because the subscriptions survive, you only need to fix your endpoint and set `enabled` back to `true` with the `updateWebhook` [mutation](/delivery-methods/graphql) to resume deliveries, with no need to subscribe again. Re-enabling also clears the failure history: the 14 day count starts again from the next failure, and so does the weekly limit on these emails. If the attempt that trips the 14 day limit is also the attempt that exhausts an event’s retries, you receive this notice instead of the email about that abandoned event. ## Event ordering While events are usually in order, your integration should not depend on it. Brandfetch doesn’t guarantee delivery of events in the order in which they’re generated. For example, re-indexing a brand might generate the following events: * `brand.company.updated` * `brand.updated` Your endpoint shouldn’t expect delivery of these events in this order, and needs to handle delivery accordingly. You can also use the API to fetch any missing objects (for example, you can fetch the current brand information from `brand.company.updated` if you happen to receive this event first). # Event types Source: https://docs.brandfetch.com/delivery-methods/webhooks/event-types Overview of subscribable event types The following table lists the type of events which can be subscribed to. There are additional events not shown in this table. If you have a custom need for an additional event, please reach out to us. * **Event type**: `brand.claimed`
**Namespace**: `brand`
**Scope**: `urn:brandfetch:brand:`
**Description**: Triggered when a brand is claimed by the brand owner. * **Event type**: `brand.deleted`
**Namespace**: `brand`
**Scope**: `urn:brandfetch:brand:`
**Description**: Triggered when a brand is soft-deleted. This is exceedingly rare and usually related to a take-down request by the brand's owner. * **Event type**: `brand.updated`
**Namespace**: `brand`
**Scope**: `urn:brandfetch:brand:`
**Description**: Triggered anytime a brand's data is updated. * **Event type**: `brand.company.updated`
**Namespace**: `brand`
**Scope**: `urn:brandfetch:brand:`
**Description**: Triggered anytime a brand's company data is updated. * **Event type**: `brand.verified`
**Namespace**: `brand`
**Scope**: `urn:brandfetch:brand:`
**Description**: Triggered when a brand's data is human-reviewed (by our curation team). # Overview Source: https://docs.brandfetch.com/delivery-methods/webhooks/overview Get notified of changes by receiving events at your webhook URL. ## Why use webhooks When building Brandfetch integrations, you might want your applications to receive events as they occur for brands you're interested in, so that your backend systems can execute actions accordingly. To enable webhook events, you need to [register webhook endpoints](/delivery-methods/webhooks/setup#register-your-endpoint). After you register them, Brandfetch can push real-time event data to your application’s webhook endpoint when things happen. Brandfetch uses HTTPS to send webhook payloads to your app as a JSON payload that includes an Event object. The implementation follows the v1 of the [Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md) specification. Receiving webhook events is particularly useful for listening to asynchronous events such as when a brand’s logo changes, a company detail is updated, or when we index new data. ## Pricing and eligibility Webhooks are available on every paid plan, with no contract and no sales call. They do require an active paid subscription, either a self-serve plan or a custom contract: without one, creating a webhook is declined with the code `NO_ACTIVE_SUBSCRIPTION` and the message "Webhooks require an active paid subscription." Registering an endpoint costs nothing, and neither does receiving deliveries, however many events your brands generate. What consumes API credits is each brand you subscribe a webhook to. | Action | Cost | | --------------------------------------------------- | --------------------------------- | | Registering a webhook endpoint | Free | | Receiving event deliveries | Free, at any volume | | Subscribing a webhook to a brand | 1 API credit, charged on creation | | Holding that subscription into a new calendar month | 1 API credit per month | | Subscribing to `brandfetch.com` | Free of credits | The creation credit is consumed as soon as the subscription exists, even if you remove it moments later, and it is not pro-rated. There are no refunds, so removing a brand and adding it back charges again. A subscription you created during the current month has already paid for that month, and renews at the start of the next one. Subscribing to `brandfetch.com` is free of credits, so you can wire up an endpoint and test it end to end without spending anything. The exemption covers credits only: the subscription still occupies one of your plan's subscription slots, like any other. ### Limits | Limit | Value | | ------------------------------------------------------------- | ---------------------------------------- | | Brand subscriptions held at once, across all of your webhooks | Your plan's monthly API credit allowance | | Webhook endpoints per organization | 100 | Prepaid credit packs pay for subscription charges, but they do not raise the subscription limit; that limit follows your plan's monthly allowance, so upgrading is what raises it. If your plan's allowance is unlimited, this limit will not be a practical constraint. The subscription limit is checked when you add subscriptions, not maintained continuously, so a plan downgrade does not remove anything you already hold. What it changes is your next monthly renewal: if the renewal charge no longer fits your allowance plus any prepaid credits, your webhooks are paused, as described below. | Denial | Code | | ----------------------------------------------------------- | ----------------------- | | Adding subscriptions past the subscription limit | `CAPACITY_EXCEEDED` | | Adding more subscriptions than your remaining credits cover | `INSUFFICIENT_CREDITS` | | Registering an endpoint when you already hold 100 | `WEBHOOK_LIMIT_REACHED` | Delete unused endpoints before registering another. ### When a renewal cannot be funded Monthly renewals never spill into overage billing. They are paid from your monthly allowance plus any prepaid credits, and when that is not enough, we pause your organization's webhooks rather than bill you for the difference. The same pause applies if the paid subscription itself lapses. While webhooks are paused: * Deliveries stop. Events that fire during the pause are skipped rather than held back, so they are not replayed once deliveries resume. * Creating webhooks and adding subscriptions are declined with the code `BILLING_HOLD`. * Your endpoints, their subscriptions, and their configuration all stay exactly as they were. | What you do | When deliveries resume | | ------------------------------------------------------ | ---------------------------------------------------------------- | | Remove enough subscriptions to fit within your credits | Usually as part of the removal itself, otherwise within 24 hours | | Buy more credits, or upgrade your plan | Within 24 hours | | Restore a lapsed paid subscription | Within 24 hours | Removing subscriptions is re-checked during the removal, so it normally lifts the pause on the spot. Every remedy is also picked up by a daily check, which is where the 24 hour figure comes from. Disabling a webhook stops its deliveries, but its subscriptions stay in place and keep renewing every month. Deleting the subscriptions is what stops the charge. If a payment fails, your existing webhooks keep running and keep renewing, but new webhooks and new subscriptions are declined with the code `PAYMENT_FAILED` until you update your payment method. ## Event overview Brandfetch implements version 1.0.0 of [the Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md) specification. Brandfetch generates event data that we can send you to inform you of brand activity. When an event occurs, Brandfetch generates a new event object. A single API request might result in the creation of multiple events. For example, if we re-index a brand, you may receive `brand.company.updated` and `brand.updated` events. By registering webhook endpoints with Brandfetch, you enable us to automatically send event payloads as part of POST requests to the registered webhook endpoint hosted by your application. After your webhook endpoint receives the event payload, your app can run backend actions (for example, updating your database after you receive a `brand.updated` event). ### Event payload The event object we send to your webhook endpoint provides a snapshot of the object that changed. They might include a `delta` property that indicates the change, when applicable. See the full [list of event types](/delivery-methods/webhooks/event-types) that we can send to your webhook. ### Example event payload The following event shows a subscription update at the end of a trial. ```JSON JSON theme={null} { "type": "brand.updated", "timestamp": "2024-01-01T00:00:00.000000Z", "urn": "urn:brandfetch:organization:0123:webhook:1234:event:2345", "data": { "object": { "__typename": "Brand", "id": "id123456", "domain": "brandfetch.com", "verified": true, ... }, "delta": { "verified": { "old": false, "new": true } } } } ``` ```TypeScript TypeScript theme={null} interface WebhookEventPayload { readonly type: string; readonly timestamp: string; readonly urn: string; readonly data: { readonly object: Record; readonly delta: Record; }; } ``` ### Event type You receive events for all of the event types your webhook endpoint is listening for in your configuration. Use the received event type to determine what processing your application needs to perform. The `data.object` corresponding to each event type varies, but typically will be the namespace object (e.g. a Brand given brand.updated where `brand.*` is the event namespace.) ### Data object and previous attributes delta Event payloads may include a `data.delta` property which will indicate which fields changed. For `*.updated` events, the event payload always includes the `data.delta` property which will allow you to inspect what’s been updated on the object. The delta attributes in the example `brand.updated` event above indicates that the brand has a previous value of `verified: false`. The `data.object` property shows that the verified field has been set to `true` which indicates that the brand has been `verified` by Brandfetch's curation team. # Setup a webhook Source: https://docs.brandfetch.com/delivery-methods/webhooks/setup Start receiving event payloads ## Summary To start receiving webhook events in your integration, create and register a webhook endpoint by following the steps below: 1. Create a webhook endpoint handler to receive event data POST requests. 2. Register your endpoint with Brandfetch via an API request. 3. Secure your webhook endpoint. You can register and create one endpoint to handle several different event types at once, or set up individual endpoints for specific events. ## Create a handler See the [events reference](/delivery-methods/webhooks/event-types) to identify the event types your webhook handler needs to process. Set an HTTPS endpoint function that can accept webhook requests with a POST method. Set up your endpoint function so that it: 1. Handles POST requests with a JSON payload consisting of an event object. 2. Quickly returns a successful status code (2xx) prior to any complex logic that could cause a timeout. ### Example endpoint This code snippet is a webhook function configured to check that the event type was received, to handle the event, and return a 200 response. Example code for `hasVerifiedPayload()` is available [here](/delivery-methods/webhooks/best-practices#example-code-for-handling-signature-and-timing-verification). ```javascript theme={null} const express = require("express"); const app = express(); // Verify the signature by comparing the signature // provided in the signature header with one we // compute ourselves with the shared secret. // If the signatures don't match, we return an error function verifyWebhook(request, response, rawBodyBuffer, encoding) { if (!rawBodyBuffer || !rawBodyBuffer.length) { return response.status(400).json({ message: "Request body missing" }); } const payload = rawBodyBuffer.toString(encoding || "utf8"); const headers = request.headers; if ( !hasVerifiedPayload({ sharedWebhookSecret: process.env.SHARED_WEBHOOK_SECRET, headers, rawRequestBody: payload, }) ) { return response.status(400).json({ message: "Signature does not match.", }); } } app.post( "/webhook", express.json({ type: "application/json", verify: verifyWebhook }), (request, response) => { const event = request.body; switch (event.type) { case "brand.updated": const brand = event.data.brand; const changes = event.data.delta; // Then define and call a method to handle the brand updated event. handleBrandUpdated(brand, changes); break; case "brand.verified": const brand = event.data.brand; // Then define and call a method to handle the brand verified event. handleBrandVerified(brand); break; // ... handle other event types default: console.log(`Unhandled event type ${event.type}`); } // Return a response to acknowledge receipt of the event response.json({ received: true }); } ); app.listen(8000, () => console.log("Running on port 8000")); ``` ## Register your endpoint Once your handler is deployed on the web and ready to go, register your endpoint with Brandfetch by creating a webhook using the GraphQL APIs `createWebhook` [mutation](/delivery-methods/graphql). Registered webhook endpoint URLs must be publicly accessible HTTPS URLs. ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"mutation CreateWebhook($input: CreateWebhookInput!) {\n createWebhook(input: $input) {\n code\n message\n success\n webhook {\n urn\n enabled\n }\n }\n}","variables":{"input":{"description":"My new Webhoook","events":["brand.updated","brand.verified"],"url":"https://httpbin.org/status/200"}}}' ``` ```GraphQL GraphQL theme={null} mutation CreateWebhook($input: CreateWebhookInput!) { createWebhook(input: $input) { code message success webhook { urn } } } # Example Variables: { "input": { "description": "Get updates when a brand's logo changes", "events": ["brand.updated"], "url": "https://httpbin.org/status/200"}} ``` ## Subscribe to brands by URN or domain The final step is to subscribe to the objects (like brands) for which you want to receive events. You can subscribe to a few objects, or many thousands, one at a time or in batches. For example, perhaps you want to receive events for the Brandfetch brand. The URN for this brand is `urn:brandfetch:brand:idL0iThUh6which` means we would subscribe to that URN. To add a subscription we need two things: The URN for the webhook we created (`$webhookUrn: URN!`) and the URN for the object to which we want to subscribe to (`$subscriptions: [URN!]!`). ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"mutation AddWebhookSubscriptions($webhookUrn: URN!, $subscriptions: [URN!]!) {\n addWebhookSubscriptions(webhook: $webhookUrn, subscriptions: $subscriptions) {\n code\n message\n success\n webhook {\n urn\n }\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:5678","subscriptions":["urn:brandfetch:brand:idL0iThUh6"]}}' ``` ```GraphQL GraphQL theme={null} mutation AddWebhookSubscriptions($webhookUrn: URN!, $subscriptions: [URN!]!) { addWebhookSubscriptions(webhook: $webhookUrn, subscriptions: $subscriptions) { code message success webhook { urn } } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "subscriptions": ["urn:brandfetch:brand:id123456"] } ``` ### Subscribe by domain If all you have is a website, you can skip the brand lookup: `addWebhookSubscriptions` also accepts a `domains` argument of type `[FQDN!]`, and resolves each domain to the brand registered for it before creating the subscription. `subscriptions` is optional now, so one call can name `domains`, `subscriptions`, or both. A few things worth knowing: * Subdomains resolve to the registrable domain, so subscribing to `blog.nike.com` subscribes you to the same brand as `nike.com`. * One call can name at most 1,000 entries, counted across `subscriptions` and `domains` together. The cap counts the entries you send, so a brand named twice, once by URN and once by domain, counts twice towards it. * A brand named both ways is still subscribed once and charged once. * A domain Brandfetch has not indexed yet is refused, and the error names the domains at fault ("No brand is registered for these domains yet: example.com"), so you can tell which entry of a batch was the problem. Nothing in the call is subscribed when that happens: correct the list and send it again. * A call that names neither argument, or names only empty lists, is refused with "Provide at least one of `subscriptions` or `domains`." ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"mutation AddWebhookSubscriptions($webhookUrn: URN!, $domains: [FQDN!]) {\n addWebhookSubscriptions(webhook: $webhookUrn, domains: $domains) {\n code\n message\n success\n webhook {\n urn\n }\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:5678","domains":["brandfetch.com","nike.com"]}}' ``` ```GraphQL GraphQL theme={null} mutation AddWebhookSubscriptions($webhookUrn: URN!, $domains: [FQDN!]) { addWebhookSubscriptions(webhook: $webhookUrn, domains: $domains) { code message success webhook { urn } } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "domains": ["brandfetch.com", "nike.com"] } ``` ## Edit a webhook To change a webhook you already registered, send just the fields you want to change to the `updateWebhook` mutation. A field you leave out, or set to `null`, keeps its current value. | Field | What it changes | | ------------- | ----------------------------------------------------------------------------------------------------------------- | | `url` | The endpoint deliveries are sent to. It must be a publicly accessible HTTPS URL. | | `urlHeaders` | The header we send with each delivery. Only a single `Authorization` header is supported. Pass `[]` to remove it. | | `events` | The event types this webhook listens for. | | `description` | The short name or description you gave the webhook. | | `enabled` | Whether the webhook delivers at all. See [Pause a webhook](#pause-a-webhook). | `events` replaces the stored set rather than adding to it, so send the complete list of event types you want, not just the ones you are adding. An empty list is refused with "A webhook must subscribe to at least one event.", because a webhook with no event types keeps its subscriptions but can never deliver anything. Subscriptions are not managed through `updateWebhook`. `UpdateWebhookInput` still accepts a `urns` field, but nothing is done with it: a call that passes `urns` comes back with `success: true` and no subscription is added, removed, or replaced. Use `addWebhookSubscriptions` and `removeWebhookSubscriptions` instead. ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"mutation UpdateWebhook($webhookUrn: URN!, $input: UpdateWebhookInput!) {\n updateWebhook(webhook: $webhookUrn, input: $input) {\n code\n message\n success\n webhook {\n urn\n url\n events\n enabled\n }\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:5678","input":{"events":["brand.updated","brand.verified"],"url":"https://example.com/brandfetch-webhook"}}}' ``` ```GraphQL GraphQL theme={null} mutation UpdateWebhook($webhookUrn: URN!, $input: UpdateWebhookInput!) { updateWebhook(webhook: $webhookUrn, input: $input) { code message success webhook { urn url events enabled } } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "input": { "events": ["brand.updated", "brand.verified"], "url": "https://example.com/brandfetch-webhook" } } ``` ## Pause a webhook Set `enabled` to `false` to stop deliveries without taking anything apart. The endpoint, its event types, and every one of its subscriptions stay exactly as they are, and nothing is delivered while the webhook is off. Set `enabled` back to `true` to resume. An event that happens while the webhook is off is skipped rather than held back, so switching the webhook on again does not replay what it missed. Re-enabling also clears the run of failures behind an automatic disable, so a webhook we switched off after 14 days without a single successful delivery starts again with a clean slate rather than resuming an outage you have already fixed. ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"mutation UpdateWebhook($webhookUrn: URN!, $input: UpdateWebhookInput!) {\n updateWebhook(webhook: $webhookUrn, input: $input) {\n code\n message\n success\n webhook {\n urn\n enabled\n }\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:5678","input":{"enabled":false}}}' ``` ```GraphQL GraphQL theme={null} mutation UpdateWebhook($webhookUrn: URN!, $input: UpdateWebhookInput!) { updateWebhook(webhook: $webhookUrn, input: $input) { code message success webhook { urn enabled } } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "input": { "enabled": false } } ``` Pausing a webhook does not pause its subscriptions. They stay in place, renew every month, and keep costing one credit each per month while the webhook is off, apart from the free `brandfetch.com` subscription. To stop paying for them, [remove the subscriptions](#unsubscribe-from-objects) or delete the webhook. ## When a request is declined `createWebhook` and `addWebhookSubscriptions` check your plan and your billing status before they change anything. When a check fails, the mutation returns `success: false` with a `code` you can branch on and a `message` you can show, and nothing is created or subscribed. A call that goes through returns `code: "success"`. | `code` | Message | What to do | | ------------------------ | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `NO_ACTIVE_SUBSCRIPTION` | Webhooks require an active paid subscription. | Webhooks are available on every paid plan. Start a paid plan, then retry. | | `PAYMENT_FAILED` | Your last payment failed. Update your payment method to create new webhooks or subscriptions. | Update your payment method in Plans & Billing. Webhooks you already have keep delivering; only new webhooks and new subscriptions are refused. | | `CAPACITY_EXCEEDED` | Your plan does not have room for more webhook subscriptions. | Your plan covers a set number of brand subscriptions. Remove subscriptions you no longer need, or move to a larger plan. | | `INSUFFICIENT_CREDITS` | Your organization does not have enough API credits. | A new brand subscription costs one credit, and every subscription you hold costs one credit per month. Retry with a smaller batch, or wait for your allowance to reset. | | `BILLING_HOLD` | Webhooks are paused for this organization. Resolve the billing hold to create webhooks. | Your organization's webhooks are on hold, which happens when a paid plan ends or a monthly renewal cannot be covered by your credits. No events are delivered while the hold is in place. It clears on its own once the plan or the credit balance is restored. | | `WEBHOOK_LIMIT_REACHED` | Your organization holds the maximum number of webhooks. Delete unused webhooks first. | Returned by `createWebhook` only. Delete a webhook you no longer use, or point an existing one at the new endpoint with `updateWebhook`. | These codes come back on the mutation result. Problems with the request itself, such as an unknown domain, more than 1,000 entries in one call, or an empty `events` list, come back as a GraphQL error instead, with a message naming what to fix. ## Unsubscribe from objects If you no longer want to receive events for an object, remove it with the `removeWebhookSubscriptions` mutation. As with subscribing, you can remove one or many subscriptions in a single call by passing multiple URNs. ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"mutation RemoveWebhookSubscriptions($webhookUrn: URN!, $subscriptions: [URN!]!) {\n removeWebhookSubscriptions(webhook: $webhookUrn, subscriptions: $subscriptions) {\n code\n message\n success\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:5678","subscriptions":["urn:brandfetch:brand:idL0iThUh6"]}}' ``` ```GraphQL GraphQL theme={null} mutation RemoveWebhookSubscriptions($webhookUrn: URN!, $subscriptions: [URN!]!) { removeWebhookSubscriptions(webhook: $webhookUrn, subscriptions: $subscriptions) { code message success } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "subscriptions": ["urn:brandfetch:brand:id123456"] } ``` ## Debugging delivery issues To help debug your endpoint, or to later retrieve failed event deliveries when your endpoint has a long duration outage, you can review all of the events Brandfetch attempted to deliver to your webhook endpoint using the GraphQL API. Performing the following GraphQL query on the Webhooks API will return a list of all attempted webhook deliveries, responses from your endpoint, and the respective HTTP status codes we received. Delivery history is kept for 90 days after which time it is irreversibly deleted. ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"query RetrieveWebhookDeliveries($webhookUrn: URN!) {\n webhook(webhook: $webhookUrn) {\n url\n urn\n description\n enabled\n deliveries {\n totalCount\n edges {\n node {\n createdAt\n deliveredAt\n status\n result {\n body\n headers {\n name\n value\n }\n message\n statusCode\n }\n }\n }\n }\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:1234"}}' ``` ```GraphQL GraphQL theme={null} query RetrieveWebhookDeliveries($webhookUrn: URN!) { webhook(webhook: $webhookUrn) { url urn description enabled deliveries { totalCount edges { node { createdAt deliveredAt status result { body headers { name value } message statusCode } } } } } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234" } ``` ### Filter and page the history `deliveries` takes three optional arguments: ```graphql theme={null} deliveries(filter: WebhookDeliveryFilter, first: IntegerBetween1And100 = 100, after: ID) ``` `filter` narrows the history to a time window on `createdAt`. Both bounds are inclusive, and you can pass either on its own: omit `from` to start at the oldest delivery still retained, and omit `to` to end at the newest. `first` sets the page size. It defaults to `100` and cannot exceed it. To read further back, pass the `endCursor` from `pageInfo` as `after` and repeat the query until `hasNextPage` is `false`. Every edge also carries its own `cursor`, so you can resume from a specific delivery rather than from the end of a page. `totalCount` is the number of deliveries the webhook has recorded since it was created. It is a lifetime total rather than the size of the result: it counts deliveries that have aged out of the retention window, and a `filter` does not narrow it. To count the deliveries in a window, page through the window and count the edges. `pageInfo.currentPage` and `pageInfo.totalPages` are `null` here, because neither can be computed while paging by cursor. Use `hasNextPage` and `endCursor` to walk the history instead. The query below reads the failed deliveries from a single day, oldest page first. ```cURL cURL theme={null} curl --request POST \ --header 'content-type: application/json' \ --header 'authorization: Bearer YOUR_API_KEY_HERE' \ --url 'https://graphql.brandfetch.io' \ --data '{"query":"query RetrieveWebhookDeliveries($webhookUrn: URN!, $filter: WebhookDeliveryFilter, $first: IntegerBetween1And100, $after: ID) {\n webhook(webhook: $webhookUrn) {\n urn\n deliveries(filter: $filter, first: $first, after: $after) {\n totalCount\n pageInfo {\n endCursor\n hasNextPage\n }\n edges {\n cursor\n node {\n createdAt\n deliveredAt\n status\n result {\n statusCode\n message\n }\n }\n }\n }\n }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:1234","filter":{"from":"2026-08-01T00:00:00Z","to":"2026-08-01T23:59:59Z"},"first":25}}' ``` ```GraphQL GraphQL theme={null} query RetrieveWebhookDeliveries( $webhookUrn: URN! $filter: WebhookDeliveryFilter $first: IntegerBetween1And100 $after: ID ) { webhook(webhook: $webhookUrn) { urn deliveries(filter: $filter, first: $first, after: $after) { totalCount pageInfo { endCursor hasNextPage } edges { cursor node { createdAt deliveredAt status result { statusCode message } } } } } } # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "filter": { "from": "2026-08-01T00:00:00Z", "to": "2026-08-01T23:59:59Z" }, "first": 25 } ``` If you already read `deliveries` without passing `first`, check that query. `first` now defaults to `100` and is capped there, where it was previously ignored and the field returned the whole retained history in one response. A query that relied on that behavior needs to follow `endCursor` to see everything it used to. # Getting started Source: https://docs.brandfetch.com/get-started The brand layer for products and AI agents [Brandfetch](https://brandfetch.com/developers) provides instant access to company logos and brand assets through a simple API. Retrieve high-quality logo files in multiple formats and sizes by passing a company name or domain. Eliminates manual logo collection and ensures consistent, up-to-date brand imagery across your application. ## Products Instant free access to any company logos Fetch logos, colors, fonts, and company details Brand context built to ground AI agents and LLMs Match brand names to their domain and logo Turn payment transactions into merchant data Brandfetch for AI assistants (Claude, Codex, more...) ## Use cases * **[User XP](https://brandfetch.com/developers/user-xp) - Bring verified brand visuals into your product**: Add real logos, colors, brand styles or company information directly to your interface instantly and accurately. * **[Finance](https://brandfetch.com/developers/finance) - Identify merchants and enrich transactions**: Turn raw transaction data into recognizable brands. Perfect for banking apps, spending trackers, or transaction feeds. * **[Growth](https://brandfetch.com/developers/onboard) - Boost your campaigns with consistent brand data**: Enrich your marketing dashboards and reports with verified brand assets and metadata that stay current automatically. * **[Sales](https://brandfetch.com/developers/enrich) - Enrich your leads with brand identity**: Give your CRM and sales tools a visual upgrade by automatically adding company logos, colors, and brand data. * **[Gen AI](https://brandfetch.com/developers/gen-ai) - Feed real-time brand data into your AI models**: Give your AI tools brand context so they can generate accurate, on-brand visuals and text every time. ## Customer stories Don't take our word for it. Learn how brand data enables new heights in B2B personalization. * [How Synthesia keeps Fortune 100 companies on-brand with the Brand API](https://brandfetch.com/developers/customers/synthesia) * [How GBM made investing instantly recognizable with Brandfetch’s Logo API](https://brandfetch.com/developers/customers/gbm) * [How CyberRisk saw a 650% increase in conversion with one API call](https://brandfetch.com/developers/customers/cyberrisk) * [How Envestnet | Yodlee augmented their Merchant API for better merchant identification](https://brandfetch.com/developers/customers/yodlee) * [How Senja increased customer activation by 233% using the Brand API](https://brandfetch.com/developers/customers/senja) * [How Typeform saw a 5% lift in conversion by transforming their onboarding](https://brandfetch.com/developers/customers/typeform) See how other companies are leveraging our APIs to enhance their products and user experiences on [our website](https://brandfetch.com/developers/customers). # Guide to Logo Fair use Source: https://docs.brandfetch.com/guides/logo-fair-use Understanding fair use principles for logo usage ## What is Logo Fair Use? When using another company’s logo or branding through Brandfetch’s APIs, it’s essential to understand logo fair use to avoid legal issues. This guide explains fair use, its applications, and limitations, helping you use logos confidently and legally. ## DO’s and️ DONT’s ### ✅ What’s allowed: * **Referring:** One of the most common principles of fair use is to cite a brand using their logo. For example, a stock trading app might feature each company's logo to clearly identify the brands. * **Commentary:** You can use a logo when discussing or reviewing a company or its products. For instance, a tech blogger might include a logo in a review of a new smartphone to add relevance. * **Educational:** Logos can be used in educational contexts, like school projects or presentations analyzing branding strategies. A marketing class might use a logo to explore a company’s branding approach. * **Parody or Satire:** Logos can be used in parodies, as long as it’s clear the intent is humorous and not commercial. A comedic take on a brand’s ad campaign, using its logo, falls under fair use if it’s obviously a joke. ### ❌ What’s not allowed: * **Commercial Use:** Using a third party logo to on your own products or services is not fair use. For instance, placing a famous logo on merchandise without permission is likely trademark infringement. * **Confusing Similarity:** Any use that might mislead consumers into believing your business is affiliated with the logo owner is not fair use. Using a well-known logo on your website to imply a false affiliation can lead to legal issues. * **Trademark Damage:** If your use of the logo harms the reputation of the brand or makes it look bad, this is not fair use. For instance, using a logo in a way that insults the company can get you into trouble. * **Imitating the Logo’s Style:** Copying a logo’s style doesn’t qualify as fair use. Creating a similar logo to mimic a well-known brand violates trademark law. ## 4 Practical ways to determine fair use One well-known example is the case of "Louis Vuitton vs. Warner Bros" involving the movie The Hangover Part II. * **What happened:** In the movie, a character is seen carrying a bag that looks like a Louis Vuitton bag. The character even refers to it as a "Louis Vuitton" bag in a scene. However, the bag was actually a fake (a knockoff), not a real Louis Vuitton product. * **Designation of Origin:** Do you use the logo of a third party in a way that leads others to think your product could come from that third party? If yes, it’s likely not fair use. * **Market:** Will your use of the logo hurt the company’s ability to make money from it? If your use is unlikely to diminish the brand’s revenue or market position, it’s likely to be fair use. * **Compliance:** Are you using the logo as intended by the company, with the latest version and in accordance with brand guidelines? Use Brandfetch to ensure compliance and streamline your pro ## Legal considerations Trademark law is straightforward and consistent across most jurisdictions, and the downsides are usually manageable. Here’s the typical process: > *You can use the trademarks of others without infringing trademark law. When the legal situation is unclear and a brand has concerns about your use of their trademark, they’ll usually start with a request to take it down before taking legal action.*

**Christian Meisser - CEO of LEXR Law Switzerland AG** To help you stay compliant, Brandfetch provides the most up-to-date logos. If you're unsure, seek permission from the logo owner, email us, or consult a lawyer. *** *Logos are the property of their respective trademark owners. Logo usage must comply with the principles of "fair use," which allow referencing a brand without endorsement, misrepresentation, or alteration. If you're unsure, consult a legal professional.* # Migrating from Clearbit to Brandfetch Logo API Source: https://docs.brandfetch.com/guides/migrate-from-clearbit-logo-api Complete guide to replacing Clearbit's deprecated Logo API with Brandfetch Clearbit's Logo API shut down on December 8, 2025. Brandfetch Logo API is the ideal future-proof replacement for modern startups and large enterprises. Clearbit's once-popular Logo API has shut down, leaving many developers searching for a Clearbit logo alternative that offers reliable, up-to-date logos. If your code still relies on `https://logo.clearbit.com/:domain` to fetch brand logos, your app is no longer rendering logos. This guide provides a comprehensive overview of migrating to a new Logo API solution. We'll explain why you should consider migrating, and walk through the migration process (using Brandfetch's Logo API as an example) with code samples and best practices. By the end, you'll have a clear path to replace Clearbit's Logo API with a robust alternative. ## Why Brandfetch? Clearbit's Logo API service **terminated on December 8, 2025** after being deprecated earlier that year. Existing integrations that still point at it are broken. To keep your product's UI displaying company logos, migrating to a new Logo API is a must. Fortunately, several alternatives have emerged. Logo API from Brandfetch is a strong choice, it's reliable with a 100% uptime, it's trusted in production by Canva, Typeform and Experian, and has the most generous free tier with up to 1,000,000 requests/month making it the no-brainer alternative solution. ## Migration guide Below is a simplified pathway for migrating from Clearbit's Logo API to Brandfetch as your primary logo API. Brandfetch is designed as a drop-in replacement for Clearbit's Logo API. The migration primarily involves updating the base URL in your existing requests. ```text Clearbit Base URL theme={null} https://logo.clearbit.com/ ``` ```text Brandfetch Base URL theme={null} https://cdn.brandfetch.io/ ``` Beyond simply swapping out the base URL, Brandfetch's Logo API offers powerful features to enhance your logo fetching experience: * **Logo types:** Access not just logo icons, but also brand symbols and main logos. * **Theme variants:** Access dark or light logos, display them on any background. * **Customizable sizing:** Adjust the logo’s height and width to fit your needs. * **Smart fallbacks:** Even when a logo isn’t available, you’ll get fallbacks. * **Search by Stock or ETF ticker, Crypto symbol:** Query directly by Stock/ETF ticker, or Crypto symbol (e.g., `NKE`, `QQQ`, `BTC`). * **Search by ISIN**: Query directly by ISIN (e.g., `US6541061031`). To make the most of your logo integrations, explore these options in our [Logo API](/logo-api/overview). Each request must include your unique client ID. This ensures your usage stays within fair limits and logos render reliably. ```text Brandfetch Base URL theme={null} https://cdn.brandfetch.io/:domain?c=BRANDFETCH_CLIENT_ID ``` To get your client ID, register for free from our [Developer Portal](https://developers.brandfetch.com/register). ## Pricing, Attribution & Rate Limits Logo API is free with 1,000,000 requests/mo and you don't need to display an attribution link. Simply include your client ID in every request. If you anticipate heavy usage, [contact sales](https://brandfetch.com/developers/contact/sales) to explore enterprise packages including custom caching rules, SLAs, and flexible legal terms. ## Conclusion [Brandfetch Logo API](https://brandfetch.com/developers/logo-api) is the replacement for modern startups and large enterprise with reliable maintenance, and a far richer dataset for those who want to expand beyond simple logos. Get started today by signing up for a free account on our [Developer Portal](https://developers.brandfetch.com/register). # Use Brandfetch with Airtable Source: https://docs.brandfetch.com/integrations/airtable Airtable's Attachment fields store real files, not URLs, so there's no `IMAGE`-style formula like Sheets or Microsoft Excel. Instead, build the logo URL with a formula field, then turn it into a real attachment with a no-code automation, or a script if you want more control. ## Prerequisites * A [Brandfetch account](https://developers.brandfetch.com/) with an active client ID * A table with a text field holding each record's domain (this guide uses `Domain`) ## Build the logo URL Add a formula field, e.g. named `Logo URL`, that concatenates the domain into a Brandfetch CDN URL the same way you would in Microsoft Excel or Sheets: ``` "https://cdn.brandfetch.io/" & {Domain} & "/icon.png?c=BRANDFETCH_CLIENT_ID" ``` Requesting `icon.png` (the default type, as a real file extension) matters here: Brandfetch serves logos in WebP by default with no extension in the URL, and both of those can trip up Airtable's URL-to-attachment conversion in the next step. This field only holds text. Airtable won't render an image from it directly, it just feeds the next step. ## Turn the URL into an attachment Create a field named `Logo` with type **Attachment**. Go to **Automations > Create automation**. Trigger on **When a record matches conditions** (e.g. `Domain` is not empty and `Logo` is empty), so it fires once per record instead of re-downloading on every edit. Add an **Update record** action on the same table. Set the `Logo` field's value to the `Logo URL` field from the trigger. Airtable downloads the file at that URL and stores it as a real attachment. If a record's `Logo` field still doesn't populate, use the script method below, it lets you set the filename explicitly. ## Scripting The **Scripting** extension, or a **Run a script** step in Automations, gives you a loop over every record in one run and lets you set the attachment's filename directly: ```js Attach Logos theme={null} let table = base.getTable("Companies"); let records = await table.selectRecordsAsync({ fields: ["Domain", "Logo"] }); const clientId = "BRANDFETCH_CLIENT_ID"; for (let record of records.records) { let domain = record.getCellValue("Domain"); if (!domain || record.getCellValue("Logo")) continue; let url = `https://cdn.brandfetch.io/${domain}/w/512/h/512/icon.png?c=${clientId}`; await table.updateRecordAsync(record.id, { Logo: [{ url: url, filename: `${domain}.png` }], }); } ``` Swap `"Companies"` for your table's name. Since this loops over every record with an empty `Logo` field, it's safe to rerun after adding new rows. For large tables, run it in the Scripting extension rather than an automation, automation scripts stop after 30 seconds. ## Theme and fallback Any [Logo API parameter](/logo-api/parameters) works the same way inside the URL, for example a dark-theme icon with a lettermark fallback, combined with the `.png` extension from above: ``` https://cdn.brandfetch.io/nike.com/theme/dark/fallback/lettermark/icon.png?c=BRANDFETCH_CLIENT_ID ``` ## Access all brand data (logos, colors, company data...) Attachments cover the logo, but a CRM-style base usually wants more: the brand's name, colors, and fonts. Those come from the [Brand API](/brand-api/overview), which the same script pattern can call with `fetch`. You'll need a Brand API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys), this is a secret key, separate from the client ID used above. Add text fields named `Brand Name`, `Accent Color`, and `Title Font`, then run: ```js Enrich With Brand Data theme={null} let table = base.getTable("Companies"); let records = await table.selectRecordsAsync({ fields: ["Domain", "Brand Name", "Accent Color", "Title Font"], }); const apiKey = "YOUR_BRAND_API_KEY"; for (let record of records.records) { let domain = record.getCellValue("Domain"); if (!domain || record.getCellValue("Brand Name")) continue; let res = await fetch(`https://api.brandfetch.io/v2/brands/domain/${domain}`, { headers: { Authorization: `Bearer ${apiKey}` }, }); if (!res.ok) continue; let brand = await res.json(); let accent = brand.colors.find((c) => c.type === "accent"); let titleFont = brand.fonts.find((f) => f.type === "title"); await table.updateRecordAsync(record.id, { "Brand Name": brand.name, "Accent Color": accent ? accent.hex : "", "Title Font": titleFont ? titleFont.name : "", }); } ``` Each enriched record costs one Brand API request against your plan's quota; the `Brand Name` check keeps reruns from re-billing records that are already filled. Brand API keys are secret. Anyone who can open the base's automations or extensions can read the key, so keep the base's collaborator list in mind before pasting it in. # Use Brandfetch with Google Sheets Source: https://docs.brandfetch.com/integrations/google-sheets Google Sheets' native `IMAGE` function can load any Brandfetch CDN URL directly, so you can show live company logos in a spreadsheet without installing an add-on. ## Prerequisites * A [Brandfetch account](https://developers.brandfetch.com/) with an active client ID ## Basic formula Drop a hardcoded domain straight into the formula: ``` =IMAGE("https://cdn.brandfetch.io/nike.com?c=BRANDFETCH_CLIENT_ID") ``` ## Reference a cell Most sheets store the domain in a column rather than hardcoding it. Concatenate the cell reference into the URL instead: ``` =IMAGE("https://cdn.brandfetch.io/"&A2&"?c=BRANDFETCH_CLIENT_ID") ``` ## Apply to an entire column Wrap the formula in `ARRAYFORMULA` to fill logos down a column automatically as new domains are added: ``` =ARRAYFORMULA(IF(A2:A="",,IMAGE("https://cdn.brandfetch.io/"&A2:A&"?c=BRANDFETCH_CLIENT_ID"))) ``` ## Sizing `IMAGE` takes an optional mode argument as its second parameter: `1` fits the image to the cell, `2` stretches it, `3` keeps its original size, and `4` lets you pass custom width/height in pixels. For predictable results regardless of cell size, size the logo itself using the [Logo API's](/logo-api/parameters) own `w`/`h` path segments and keep `IMAGE` at mode `3`: ``` =IMAGE("https://cdn.brandfetch.io/nike.com/w/128/h/128?c=BRANDFETCH_CLIENT_ID", 3) ``` ## Theme and fallback Any [Logo API parameter](/logo-api/parameters) works the same way inside the formula, for example a dark-theme icon with a lettermark fallback: ``` =IMAGE("https://cdn.brandfetch.io/nike.com/theme/dark/fallback/lettermark/icon?c=BRANDFETCH_CLIENT_ID") ``` ## Access all brand data (logos, colors, company data...) `IMAGE` can only embed images. The rest of a brand's identity, its color palette, fonts, and company info, comes from the [Brand API](/brand-api/overview), which returns JSON and needs an `Authorization` header that no spreadsheet formula can send. A small Apps Script custom function fills the gap. You'll need a Brand API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys), this is a secret key, separate from the client ID used above. Open **Extensions > Apps Script**, paste the function below, and save: ```js Code.gs theme={null} const API_KEY = "YOUR_BRAND_API_KEY"; /** * Returns a brand attribute from the Brandfetch Brand API. * * @param {string} domain The company domain, e.g. "nike.com". * @param {string} field One of "name", "description", "accent", "font". * @return The requested value. * @customfunction */ function BRANDFETCH(domain, field) { const res = UrlFetchApp.fetch( "https://api.brandfetch.io/v2/brands/domain/" + domain, { headers: { Authorization: "Bearer " + API_KEY }, muteHttpExceptions: true } ); if (res.getResponseCode() !== 200) return ""; const brand = JSON.parse(res.getContentText()); if (field === "name") return brand.name; if (field === "description") return brand.description; if (field === "accent") { const accent = brand.colors.find((c) => c.type === "accent"); return accent ? accent.hex : ""; } if (field === "font") { const title = brand.fonts.find((f) => f.type === "title"); return title ? title.name : ""; } return "Unknown field: " + field; } ``` Then use it like any built-in function, next to the `IMAGE` logo column: ``` =BRANDFETCH(A2, "accent") ``` Brand API keys are secret. Anyone who can edit the spreadsheet can open the script and read the key, so don't share the sheet outside your team with the key in place. Custom functions re-run when the sheet recalculates (for example on reopen), and every run counts against your Brand API plan's quota. Once a column is filled, freeze it with **Edit > Paste special > Values only**. # Use Brandfetch with Microsoft Excel Source: https://docs.brandfetch.com/integrations/microsoft-excel Microsoft Excel's `IMAGE` function can load any Brandfetch CDN URL directly, so you can show live company logos in a spreadsheet without installing an add-on. `IMAGE` is only available to Microsoft 365 subscribers, and isn't in perpetual licenses like Microsoft Excel 2019 or 2021. ## Prerequisites * A [Brandfetch account](https://developers.brandfetch.com/) with an active client ID ## Basic formula Drop a hardcoded domain straight into the formula: ``` =IMAGE("https://cdn.brandfetch.io/nike.com?c=BRANDFETCH_CLIENT_ID") ``` ## PNG instead of WebP Brandfetch serves logos in WebP by default. `IMAGE` renders WebP fine on Microsoft Excel desktop (Windows and Mac), but not in [Excel for the web or Android](https://support.microsoft.com/en-us/excel/functions/image-function). Request PNG instead by adding the extension to the type segment (the default type is `icon`): ``` =IMAGE("https://cdn.brandfetch.io/nike.com/icon.png?c=BRANDFETCH_CLIENT_ID") ``` `logo` and `symbol` type variants also support `.svg`, where the brand has a distinct vector asset for that type: ``` =IMAGE("https://cdn.brandfetch.io/nike.com/type/logo.svg?c=BRANDFETCH_CLIENT_ID") ``` ## Reference a cell Most sheets store the domain in a column rather than hardcoding it. Concatenate the cell reference into the URL instead: ``` =IMAGE("https://cdn.brandfetch.io/"&A2&"?c=BRANDFETCH_CLIENT_ID") ``` ## Apply to an entire column Inside a Microsoft Excel Table, `IMAGE` fills down automatically like any other formula column, no array wrapper needed. Using a structured reference: ``` =IMAGE("https://cdn.brandfetch.io/"&[@Domain]&"?c=BRANDFETCH_CLIENT_ID") ``` Outside a Table, drag the fill handle down the column, or select the range and press **Ctrl+D**. ## Sizing `IMAGE` takes optional `sizing`, `height`, and `width` arguments as its 3rd–5th parameters: `0` (default) fits the image to the cell keeping its aspect ratio, `1` stretches it to fill the cell, `2` keeps the image at its original size regardless of cell size, and `3` uses the custom `height` and `width` you pass in pixels. For predictable results regardless of cell size, size the logo itself using the [Logo API's](/logo-api/parameters) own `w`/`h` path segments and keep `sizing` at `0`: ``` =IMAGE("https://cdn.brandfetch.io/nike.com/w/128/h/128?c=BRANDFETCH_CLIENT_ID", "Nike logo", 0) ``` ## Theme and fallback Any [Logo API parameter](/logo-api/parameters) works the same way inside the formula, for example a dark-theme icon with a lettermark fallback: ``` =IMAGE("https://cdn.brandfetch.io/nike.com/theme/dark/fallback/lettermark/icon?c=BRANDFETCH_CLIENT_ID") ``` ## Prefer static pictures? Use a macro `IMAGE` results stay live, they re-fetch over the network and can't be viewed offline or reliably exported. To freeze logos into the file as real pictures, use a macro instead. This one reads domains from column A and drops a logo next to each one in column B, sized to fit the cell. It requests the `icon.png` variant rather than the WebP default, since `AddPicture` inserts PNG reliably across Office versions: This needs a current Microsoft 365 desktop build: older Microsoft Excel versions don't fetch URLs in `AddPicture` at all (they raise error 1004, "The specified file was not found"). ```vb Insert Logos From Column theme={null} Sub InsertLogosFromColumn() Dim ws As Worksheet Set ws = ActiveSheet Dim clientId As String clientId = "BRANDFETCH_CLIENT_ID" Dim lastRow As Long lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row Dim r As Long, domain As String, url As String, cell As Range For r = 2 To lastRow domain = ws.Cells(r, "A").Value If domain <> "" Then url = "https://cdn.brandfetch.io/" & domain & "/w/128/h/128/icon.png?c=" & clientId Set cell = ws.Cells(r, "B") ws.Shapes.AddPicture FileName:=url, LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, _ Left:=cell.Left, Top:=cell.Top, Width:=cell.Height, Height:=cell.Height End If Next r End Sub ``` Open the VBA editor with **Alt+F11** (Windows) or **Fn+Option+F11** (Mac), paste the macro into a new module (**Insert > Module**), then run it with **F5**. Save the workbook as **Excel Macro-Enabled Workbook (.xlsm)** to keep the macro for next time. ## Access all brand data (logos, colors, company data...) `IMAGE` can only embed images. The rest of a brand's identity, its color palette, fonts, and company info, comes from the [Brand API](/brand-api/overview), which returns JSON and needs an `Authorization` header. Power Query handles both. You'll need a Brand API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys), this is a secret key, separate from the client ID used above. Go to **Data > Get Data > From Other Sources > From Web** and switch to **Advanced**. Enter `https://api.brandfetch.io/v2/brands/domain/nike.com` as the URL, and under **HTTP request header parameters** add `Authorization` with the value `Bearer YOUR_BRAND_API_KEY`. If Microsoft Excel asks how to connect to the source, pick **Anonymous**, authentication already happens through the header. The Power Query editor opens the response as a record. Drill into the parts you want, for example click the **List** next to `colors`, choose **To Table**, then expand the records into `hex` and `type` columns. Click **Close & Load** to land the result as a worksheet table. **Data > Refresh All** re-fetches it whenever you need current data; each refresh counts against your Brand API plan's quota. The API key is saved inside the query, anyone who gets the workbook can read it in the Power Query editor. Share exports (PDF, values-only copies) rather than the workbook itself. # Use Brandfetch with Microsoft PowerPoint Source: https://docs.brandfetch.com/integrations/microsoft-powerpoint Microsoft PowerPoint has no `IMAGE` function like Sheets or Microsoft Excel, so logos go in as static pictures. For a single slide, paste a Brandfetch URL directly into the picture dialog. For a whole deck, VBA's `Shapes.AddPicture` accepts a Brandfetch URL too, so a short macro can drop dozens of logos in one run instead of pasting each one by hand. ## Quick manual insert Use a high resolution so the logo stays sharp if it's resized on the slide: ``` https://cdn.brandfetch.io/nike.com/w/512/h/512?c=BRANDFETCH_CLIENT_ID ``` In Microsoft PowerPoint for Windows, go to **Insert > Pictures > This Device**, then paste the URL into the filename field instead of picking a local file, and click **Insert**. The picture dialogs in Microsoft PowerPoint for Mac and Microsoft PowerPoint for web don't accept URLs. Download the image in your browser first, then insert it from disk. To keep a logo consistent across every slide in a layout, add it to the **Slide Master** (**View > Slide Master**) once instead of pasting it slide by slide. ## Macros: insert logos in bulk `Shapes.AddPicture` is documented as taking a local file path, but current Microsoft 365 desktop builds also accept an `http`/`https` URL directly in that argument and fetch it on the spot, no download-then-insert step needed. That makes it a drop-in replacement for the CDN URL used above, looped over as many logos as you need. Both macros below request the `icon.png` variant rather than Brandfetch's WebP default, since `AddPicture` inserts PNG reliably across Office versions. Macros need Microsoft PowerPoint desktop; they don't run in Microsoft PowerPoint for web. Save the file as a macro-enabled presentation (`.pptm`) and allow macros when you reopen it. If `AddPicture` raises error 1004 ("The specified file was not found"), your build doesn't fetch URLs, download the logo files first and pass local paths instead. ### Build a logo wall Drops a grid of logos onto the current slide from a list of domains, useful for a "trusted by" or portfolio slide. Each inserted picture is tagged with the domain in its **Alt Text**, so the refresh macro below can find it again later. ```vb Insert Logo Wall theme={null} Sub InsertLogoWall() Dim domains As Variant domains = Array("nike.com", "airbnb.com", "slack.com", "notion.so", "figma.com", "linear.app") Dim clientId As String clientId = "BRANDFETCH_CLIENT_ID" Dim sld As Slide Set sld = ActiveWindow.View.Slide Dim cols As Integer, logoSize As Single, gap As Single cols = 3 logoSize = 90 gap = 24 Dim i As Integer, col As Integer, row As Integer Dim domain As String, url As String, pic As Shape For i = 0 To UBound(domains) domain = domains(i) url = "https://cdn.brandfetch.io/" & domain & "/w/256/h/256/icon.png?c=" & clientId col = i Mod cols row = i \ cols Set pic = sld.Shapes.AddPicture(FileName:=url, LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, _ Left:=40 + col * (logoSize + gap), Top:=100 + row * (logoSize + gap), _ Width:=logoSize, Height:=logoSize) pic.AlternativeText = "brandfetch:" & domain Next i End Sub ``` ### Refresh every logo in a deck Rerun this any time to swap in fresh logos across every slide at once, for example after a client rebrand, or to bump resolution before a deck goes to print. It finds every picture tagged by the macro above, re-fetches it at the shape's current size and position, and replaces it in place. ```vb Refresh All Logos theme={null} Sub RefreshAllLogos() Dim clientId As String clientId = "BRANDFETCH_CLIENT_ID" Dim sld As Slide, shp As Shape, newShp As Shape Dim i As Integer, domain As String For Each sld In ActivePresentation.Slides For i = sld.Shapes.Count To 1 Step -1 Set shp = sld.Shapes(i) If shp.Type = msoPicture And Left(shp.AlternativeText, 11) = "brandfetch:" Then domain = Mid(shp.AlternativeText, 12) Set newShp = sld.Shapes.AddPicture(FileName:="https://cdn.brandfetch.io/" & domain & "/w/512/h/512/icon.png?c=" & clientId, _ LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, _ Left:=shp.Left, Top:=shp.Top, Width:=shp.Width, Height:=shp.Height) newShp.AlternativeText = shp.AlternativeText shp.Delete End If Next i Next sld End Sub ``` ### Running a macro Press **Alt+F11** (Windows) or **Fn+Option+F11** (Mac), then **Insert > Module** and paste one of the macros above. With a slide open in Normal view, press **F5** or **Run > Run Sub/UserForm**. Save the deck as **PowerPoint Macro-Enabled Presentation (.pptm)** so the macros are kept for next time. ## Access all brand data (logos, colors, company data...) Logos are only half of an on-brand deck, the other half is the brand's colors. Those come from the [Brand API](/brand-api/overview), which returns each brand's color palette, fonts, and company info as JSON. You'll need a Brand API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys), this is a secret key, separate from the client ID used above. This macro fetches a brand's accent color and draws a color bar across the bottom of every slide: ```vb Apply Brand Accent theme={null} Sub ApplyBrandAccent() Dim apiKey As String, domain As String apiKey = "YOUR_BRAND_API_KEY" domain = "nike.com" Dim http As Object Set http = CreateObject("MSXML2.XMLHTTP") http.Open "GET", "https://api.brandfetch.io/v2/brands/domain/" & domain, False http.setRequestHeader "Authorization", "Bearer " & apiKey http.Send If http.Status <> 200 Then MsgBox "Brand API returned status " & http.Status Exit Sub End If ' pull the accent color's hex code out of the JSON Dim re As Object, matches As Object Set re = CreateObject("VBScript.RegExp") re.Pattern = "\{[^{}]*""type""\s*:\s*""accent""[^{}]*\}" Set matches = re.Execute(http.responseText) If matches.Count = 0 Then MsgBox "No accent color found for " & domain Exit Sub End If re.Pattern = "#[0-9A-Fa-f]{6}" Dim hexColor As String hexColor = re.Execute(matches(0).Value)(0).Value Dim accentRGB As Long accentRGB = RGB(CLng("&H" & Mid(hexColor, 2, 2)), _ CLng("&H" & Mid(hexColor, 4, 2)), _ CLng("&H" & Mid(hexColor, 6, 2))) Dim sld As Slide, bar As Shape For Each sld In ActivePresentation.Slides Set bar = sld.Shapes.AddShape(msoShapeRectangle, _ 0, ActivePresentation.PageSetup.SlideHeight - 8, _ ActivePresentation.PageSetup.SlideWidth, 8) bar.Fill.ForeColor.RGB = accentRGB bar.Line.Visible = msoFalse Next sld End Sub ``` The same response carries the full palette (`colors`), the brand's fonts, and company data, so the pattern extends to title colors, themed shapes, or a closing slide with company facts. Each run counts against your Brand API plan's quota. `MSXML2.XMLHTTP` (the HTTP client used here) is Windows-only, so this macro doesn't run on Microsoft PowerPoint for Mac. On a Mac, fetch the JSON once with `curl` in Terminal and hardcode the hex value instead. Brand API keys are secret. A macro embeds the key in the presentation file, so strip it before sharing the deck outside your team. ## At scale: Macabacus Logo Library If your team inserts logos into decks constantly (pitch books, client reports), [Macabacus](https://macabacus.com/features/logo-library) partners with Brandfetch to power **Logo Library**, a Microsoft PowerPoint add-in that lets you search and insert from Brandfetch's logo dataset directly inside Microsoft PowerPoint, no URL-pasting required. # No-code integrations Source: https://docs.brandfetch.com/integrations/overview Connect Brandfetch to Zapier, Make, and n8n without writing code Brandfetch connects to no-code automation platforms so any workflow can pull in logos, colors, fonts, and company data on demand, no API client, no glue code. Zapier connects Brandfetch to more than 9,000 apps through trigger-based workflows called Zaps. Once the Brandfetch app is added to your account, any Zap you build can pull in logos, colors, fonts, and company data on demand. In this guide you'll set up the connection and ship a working Zap: an Airtable CRM that auto-enriches every new lead with its company's brand data. **Prerequisites** * A [Zapier](https://zapier.com) account (the free tier is enough to follow along) * A [Brandfetch account](https://developers.brandfetch.com/) with an active API key **Getting started** Add the Brandfetch app from the Zapier App Directory. Once added, Brandfetch will appear in the app picker whenever you build a Zap. Add the Brandfetch integration from the official Zapier App Directory. A *connection* tells Zapier how to authenticate with Brandfetch. You only need to set it up once, and every Zap you build can reuse it. 1. In Zapier, open any Zap and add a Brandfetch action step. 2. Click **Sign in** under the **Account** dropdown. 3. Give your account a memorable name (e.g. `Brandfetch - Production`). 4. Copy your API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys) and paste it into the **API Key** field. 5. Click **Yes, Continue to Brandfetch**. Let's enrich an Airtable CRM with brand data. Whenever a new lead is added with a company domain, the Zap fetches the company's logo, colors, and name, then writes them back to the same record. **High-level flow:** 1. **Trigger:** Airtable *New Record* on your leads table. 2. **Enrich:** Brandfetch *Find Brand by Domain Name*, using the domain field from the trigger. 3. **Update:** Airtable *Update Record*, mapping the Brandfetch output (logo URL, primary color, company name) back to the original record. Test each step as you go to confirm the mapping works, then publish your Zap so it runs automatically as new leads come in. The same pattern works with HubSpot, Pipedrive, Salesforce, Google Sheets, or any tool that stores a list of domains. Just swap the trigger and update steps. **Available actions** The Brandfetch app on Zapier exposes four **Search** actions. Search actions look up existing data and return it to the next step in your Zap. 1. **Find Brand by Domain Name** * Input: Domain (e.g. `apple.com`) * Output: Brand data including logos, colors, and company information 2. **Find Brand by Crypto Symbol** * Input: Crypto Symbol (e.g. `BTC`) * Output: Brand data including logos, colors, and company information 3. **Find Brand by ISIN** * Input: ISIN identifier * Output: Brand data including logos, colors, and company information 4. **Find Brand by Stock/ETF Ticker** * Input: Symbol/ETF Ticker (e.g. `AAPL`) * Output: Brand data including logos, colors, and company information **Common Zaps** A few patterns that work well with Brandfetch on Zapier: * **CRM enrichment**: Auto-populate Airtable, HubSpot, or Salesforce records with logos and brand data as new leads arrive. * **Lead alerts in Slack**: Post a new-lead message to Slack with the company's logo and brand colors inline. * **Branded asset pipelines**: Pull brand assets into Notion, Google Drive, or Figma whenever a new client is added. * **Create branded presentations**: Auto-generate Google Slides or Microsoft PowerPoint decks pre-populated with a prospect's logo, colors, and fonts. * **Financial dashboards**: Look up brand data by ticker or ISIN to enrich portfolio trackers and investor reports. **Error handling** When a Brandfetch action fails, Zapier surfaces the underlying API error code and message in the Zap History. The table below lists errors you might run into and how to resolve them. | Status | Title | Description | | ------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `400` | Bad Request | The request is malformed or missing required parameters. | | `401` | Unauthorized | The API key is missing, invalid, or expired. Manage your keys on the [API keys page](https://developers.brandfetch.com/dashboard/keys). | | `404` | Not Found or Invalid Domain Name | No brand matches the input. Confirm it exists at [brandfetch.com](https://brandfetch.com/). | | `429` | API key quota exceeded | You've hit your plan's request limit. Upgrade in the [developer dashboard](https://developers.brandfetch.com/). | Zapier automatically retries failed tasks for transient errors, and you can layer additional controls on top: * **Filters** stop a Zap when a condition isn't met. * **Paths** branch the workflow based on the Brandfetch response. * **Auto-Replay** retries held tasks once the underlying issue is resolved. You can also configure email or Slack notifications for failed Zaps from your account settings. For details on each, see Zapier's [error handling documentation](https://help.zapier.com/hc/en-us/articles/8496259603085). **Extract domain name from email** Most CRMs store an email but not a separate domain field. You can derive the domain on the fly using **Formatter by Zapier** before passing it to the Brandfetch action. Add a **Formatter by Zapier** step between your trigger and the Brandfetch action: 1. Choose the **Text** event. 2. Set **Transform** to **Split Text**. 3. Map the email field from your trigger into **Input**. 4. Set **Separator** to `@`. 5. Set **Segment Index** to `Second`. Then map the formatter's output into the **Domain** field of the *Find Brand by Domain Name* action. Make.com is a no-code automation platform that lets you connect Brandfetch to thousands of other apps, including Airtable, HubSpot, Slack, and Google Sheets. With the Brandfetch integration installed, you can enrich any workflow with logos, colors, fonts, and company data without writing a line of code. This guide walks you through connecting Brandfetch to Make and building your first scenario: automatically enriching an Airtable CRM with brand data. **Prerequisites** * A [Make](https://www.make.com) account (the free tier is enough to follow along) * A [Brandfetch account](https://developers.brandfetch.com/) with an active API key **Getting started** Install the Brandfetch app from the Make integrations directory. Once installed, Brandfetch will appear in the module picker whenever you build a scenario. Install the Brandfetch integration from the official Make directory. A *connection* tells Make how to authenticate with Brandfetch. You only need to set it up once, and every scenario you build can reuse it. 1. In Make, open any scenario and add a Brandfetch module. 2. Click **Create a connection**. 3. Give it a memorable name (e.g. `Brandfetch - Production`). 4. Copy your API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys) and paste it into the **API Key** field. 5. Click **Save**. Let's enrich an Airtable CRM with brand data. Whenever a new lead is added with a company domain, the scenario fetches the company's logo, colors, and name, then writes them back to the same record. **High-level flow:** 1. **Trigger:** Airtable *Watch Records* on your leads table. 2. **Enrich:** Brandfetch *Get brand by domain*, using the domain field from the trigger. 3. **Update:** Airtable *Update a Record*, mapping the Brandfetch output (logo URL, primary color, company name) back to the original record. Run the scenario once to confirm the mapping works, then turn on scheduling so it runs automatically as new leads come in. The same pattern works with HubSpot, Pipedrive, Salesforce, Google Sheets, or any tool that stores a list of domains. Just swap the trigger and update modules. **Available modules** The Brandfetch app on Make exposes five modules: 1. **Get brand by domain** (Action) * Input: Domain name (e.g. `apple.com`) * Output: Brand data including logos, colors, and company information 2. **Get brand by crypto symbol** (Action) * Input: Crypto ticker (e.g. `BTC`) * Output: Brand data including logos, colors, and company information 3. **Get brand by ISIN** (Action) * Input: ISIN identifier * Output: Brand data including logos, colors, and company information 4. **Get brand by stock/ETF ticker** (Action) * Input: Stock or ETF ticker (e.g. `AAPL`) * Output: Brand data including logos, colors, and company information 5. **Make an API call** (Universal) * Input: Any Brandfetch API endpoint and parameters * Output: Brand data including logos, colors, and company information **Common scenarios** A few patterns that work well with Brandfetch on Make: * **CRM enrichment**: Auto-populate Airtable, HubSpot, or Salesforce records with logos and brand data as new leads arrive. * **Lead alerts in Slack**: Post a new-lead message to Slack with the company's logo and brand colors inline. * **Create branded presentations**: Auto-generate Google Slides or Microsoft PowerPoint decks pre-populated with a prospect's logo, colors, and fonts. * **Financial dashboards**: Look up brand data by ticker or ISIN to enrich portfolio trackers and investor reports. **Error handling** When a Brandfetch module fails, Make surfaces the underlying API error code and message. The table below lists errors you might run into and how to resolve them. | Status | Title | Description | | ------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `400` | Bad Request | The request is malformed or missing required parameters. | | `401` | Unauthorized | The API key is missing, invalid, or expired. Manage your keys on the [API keys page](https://developers.brandfetch.com/dashboard/keys). | | `404` | Not Found or Invalid Domain Name | No brand matches the input. Confirm it exists at [brandfetch.com](https://brandfetch.com/). | | `429` | API key quota exceeded | You've hit your plan's request limit. Upgrade in the [developer dashboard](https://developers.brandfetch.com/). | Make offers five error handlers, **Ignore**, **Break**, **Resume**, **Commit**, and **Rollback**, that you can attach to any Brandfetch module. With the module's configuration dialog closed, right-click the module on the scenario canvas and choose **Add error handler**. For details on each handler, see Make's [error handling documentation](https://help.make.com/error-handling). **Extract domain name from email** Most CRMs store an email but not a separate domain field. You can derive the domain on the fly inside the Brandfetch module using Make's built-in functions. Paste the expression below straight into the **Domain** field: ``` {{ifempty(split(trim(email); "@")[2]; "")}} ``` `email` should reference the email field from the trigger module. n8n is a workflow automation platform you can run in the cloud or self-host. Brandfetch ships as a **built-in node**, so there's nothing to install: search for *Brandfetch* in the node panel and it's there. This guide walks you through connecting your API key and building your first workflow: automatically enriching an Airtable CRM with brand data. **Prerequisites** * An [n8n](https://n8n.io) account, or a self-hosted instance * A [Brandfetch account](https://developers.brandfetch.com/) with an active API key This guide covers **version 2** of the Brandfetch node. If your node shows a single *Operation* list without a **Type** selector, you're on version 1, update your n8n instance to get v2. Existing v1 nodes keep working, n8n pins each node to the version it was created with. **Getting started** In the n8n editor, click **+** to open the node panel, search for **Brandfetch**, and add it to your canvas. Browse the Brandfetch node in the official n8n integrations directory. A *credential* tells n8n how to authenticate with Brandfetch. You only need to set it up once, and every workflow on your instance can reuse it. 1. In the Brandfetch node, open the **Credential to connect with** dropdown and choose **Create new credential**. 2. Copy your API key from the [API keys page](https://developers.brandfetch.com/dashboard/keys) and paste it into the **API Key** field. 3. Click **Save**. n8n verifies the key immediately and shows **Connection tested successfully**. 4. Rename the credential to something memorable (e.g. `Brandfetch - Production`). Let's enrich an Airtable CRM with brand data. Whenever a new lead is added with a company domain, the workflow fetches the company's logo, colors, and name, then writes them back to the same record. **High-level flow:** 1. **Trigger:** Airtable *Trigger* on your leads table. 2. **Enrich:** Brandfetch, operation *Return All of a Brand's Data*, **Type** `Domain`, **Identifier** mapped to the domain field from the trigger. 3. **Update:** Airtable *Update Record*, mapping the Brandfetch output (logo URL, primary color, company name) back to the original record. Use **Test workflow** to run it once and confirm the mapping, then activate the workflow so it runs automatically as new leads come in. The Brandfetch node runs once per input item, so if the previous step returns 50 leads, one node enriches all 50 in a single execution. The same pattern works with HubSpot, Pipedrive, Salesforce, Google Sheets, or any tool that stores a list of domains. **Available operations** Unlike Zapier and Make, which expose a separate action per identifier type, the n8n node uses a single **Type** dropdown (`Domain`, `Stock/ETF Ticker`, `Crypto Symbol`, `ISIN`) plus a free-form **Identifier** field. Pick what you want back, then say how you're looking it up. 1. **Return All of a Brand's Data** * Input: **Type** + **Identifier** (e.g. `apple.com`, `AAPL`, `BTC`, `US0378331005`) * Output: The full brand payload, name, description, logos, colors, fonts, company data, and more 2. **Return Logos, Symbols and Icon** * Input: **Type** + **Identifier**, plus an optional **Download** toggle * Output: The `logos` array. With **Download** on, every logo variant is also attached to the item as binary data, ready to pass straight to Google Drive, S3, or an email node without a separate HTTP request 3. **Return Accent and Brand Colors** * Input: **Type** + **Identifier** * Output: The `colors` array 4. **Return Brand Context** * Input: **Domain** only, plus **Output Format** (`JSON` or `Markdown`) and a **Cached Only** toggle * Output: A structured, narrative-rich brand profile, identity, positioning, voice, and visual style. Choose **Markdown** to drop the result straight into an LLM prompt. See the [Brand Context API](/brand-context-api/overview) for details **Cached Only** returns a context only if one is already cached, responding instantly instead of crawling the domain. If nothing is cached, the node returns an empty item, so add an **IF** node downstream to handle that branch. **Use Brandfetch as an AI Agent tool** The Brandfetch node is tool-enabled. Connect it to the **Tool** input of an AI Agent node and the model can call it on its own, looking up a brand mid-conversation rather than on a fixed step in the flow. Pair it with the *Return Brand Context* operation set to **Markdown** for the cleanest grounding data: the agent gets a readable brand profile instead of raw JSON it has to interpret. **Common workflows** A few patterns that work well with Brandfetch on n8n: * **CRM enrichment**: Auto-populate Airtable, HubSpot, or Salesforce records with logos and brand data as new leads arrive. * **Bulk backfill**: Read a spreadsheet of domains, run them all through one Brandfetch node, and write the enriched rows back. * **Asset pipelines**: Use *Return Logos* with **Download** enabled to push brand files straight into Google Drive, S3, or Notion as binary data. * **On-brand content generation**: Feed *Return Brand Context* into an AI Agent or LLM Chain node to draft copy, emails, or landing pages in a prospect's voice. * **Lead alerts in Slack**: Post a new-lead message with the company's logo and brand colors inline. * **Financial dashboards**: Look up brand data by ticker or ISIN to enrich portfolio trackers and investor reports. **Error handling** When a Brandfetch node fails, n8n surfaces the underlying API error code and message in the node's output and in the execution log. The table below lists errors you might run into and how to resolve them. | Status | Title | Description | | ------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `400` | Bad Request | The request is malformed or missing required parameters. | | `401` | Unauthorized | The API key is missing, invalid, or expired. Manage your keys on the [API keys page](https://developers.brandfetch.com/dashboard/keys). | | `404` | Not Found or Invalid Domain Name | No brand matches the input. Confirm it exists at [brandfetch.com](https://brandfetch.com/). | | `429` | API key quota exceeded | You've hit your plan's request limit. Upgrade in the [developer dashboard](https://developers.brandfetch.com/). | You can control what happens on failure from the node's **Settings** tab: * **Retry On Fail** re-runs the node automatically, useful for transient errors. * **On Error → Continue (using error output)** sends failed items down a second branch so one bad domain doesn't stop a batch of 500. * **On Error → Continue** keeps the run going and passes an `error` field on the affected item. Add an **Error Trigger** workflow to get notified when an execution fails. For details, see n8n's [error handling documentation](https://docs.n8n.io/flow-logic/error-handling/). **Extract domain name from email** Most CRMs store an email but not a separate domain field. n8n expressions can derive the domain inline, no extra node needed. Paste this straight into the **Identifier** field: ```js theme={null} {{ $json.email.split("@")[1] }} ``` `$json.email` should reference the email field from the previous node. # Overview Source: https://docs.brandfetch.com/logo-api/overview Instantly add any company logos to your app or website [Logo API](https://brandfetch.com/developers/logo-api) is a simple CDN link that gives you access to any brand’s latest logos. It’s customizable with powerful transformation capabilities and is meant to be directly embedded in your HTML tags so the logo always remains up-to-date. ## Implementation guide The Logo API is a free product. Before you deploy your application to a live environment, be sure to consult our [rate limits](#rate-limits) and review our [usage guidelines](#usage-guidelines) to ensure a smooth launch. To avoid potential naming collisions between identifier types, you can use explicit type routes with the pattern `{type}/{identifier}`. To embed a logo, simply use an `img` tag with the following `src` attribute: ```html Domain theme={null} Logo by Brandfetch ``` ```html Ticker theme={null} Logo by Brandfetch ``` ```html Crypto theme={null} Logo by Brandfetch ``` ```html ISIN theme={null} Logo by Brandfetch ``` ```html Auto-detection (legacy) theme={null} Logo by Brandfetch ``` Without a type prefix, the API will auto-detect the identifier type by order (domain → ticker → isin → crypto). Logo API is free to use and we don't ask for any attribution. Each request must include your unique client ID. This ensures your usage stays within fair limits and logos render reliably. To get your client ID, register for free from our [Developer Portal](https://developers.brandfetch.com/register). Beyond simply swapping out the base URL, Brandfetch's Logo API offers powerful features to enhance your logo fetching experience: * **Logo types:** Access not just logo icons, but also brand symbols and main logos. * **Theme variants:** Access dark or light logos, display them on any background. * **Customizable sizing:** Adjust the logo’s height and width to fit your needs. * **Smart fallbacks:** Even when a logo isn’t available, you’ll get fallbacks. * **Flexible identifiers:** Query directly by domain (e.g., `nike.com`), Stock or ETF ticker (e.g., `NKE`, `QQQ`), ISIN (e.g., `US6541061031`), or Crypto symbol (e.g., `BTC`, `ETH`). Explore these options in our Logo API [parameters page](/logo-api/parameters). *** ## Default icon Get the brand's default logo icon. ```html Domain theme={null} Logos by Brandfetch ``` ```html Ticker theme={null} Logos by Brandfetch ``` ```html Crypto theme={null} Logos by Brandfetch ``` ### PNG or JPG instead of WEBP By default Logo API serves logos in the modern and highly efficient WebP format. You can use others formats by specifying the file extension in the URL. `logo`, `symbol` type variants support an additional `svg` format. ```html theme={null} Logos by Brandfetch ``` ### Logo sizing / Retina Customize the logo’s dimensions by adding `w` (width) and `h` (height) query parameters to the URL. The ratio of the logo is always respected. For Retina displays, double the size values for optimal display. e.g., for a 64x64 icon display, set `h=128` and `w=128`. ```html theme={null} Logos by Brandfetch ``` ### Type variants Request different types of logos by using the `type` path parameter. Available variants are: `icon`, `symbol`, and `logo`. ```html theme={null} Logos by Brandfetch ``` ### Dark and light themes Ensure the logo looks great regardless of the background color of your application. ```html theme={null} Logos by Brandfetch ``` ### Multiple fallbacks Specify a fallback option to be used when the a logo is not available. [See all fallbacks](/logo-api/parameters). ```html theme={null} Logos by Brandfetch ``` ## Usage guidelines **To use Logo API, you must include your client ID with every request.** Adding your client ID provides reliable access, supports fair usage, and keeps consistent performance across all requests. [Create a free account](https://developers.brandfetch.com/register) and access your client ID from the developer portal. Include your client ID in each request as shown in the example below: ```html theme={null} Logos by Brandfetch ``` **We require logo links to be directly embedded in your applications.** Embedding logo links directly within your HTML image tags guarantees that the logo remains up-to-date at all times. It also ensures a faster and more reliable implementation. When embedding a logo link, HTTP requests must include the `Referer` header with the request origin. Your HTTP `Referrer-Policy` header must be set to one of: `origin`, `origin-when-cross-origin`, `strict-origin`, `strict-origin-when-cross-origin` (browser default), or `unsafe-url`. Programmatic access to logo images is not permitted and may result in rate limiting or blocking. Scraping logos will also lead to a block. If your use case requires caching, please [contact us](https://brandfetch.com/developers/contact/sales) for a custom setup. **You cannot replicate the core user experience of Brandfetch.** The best way to ensure that your application doesn’t violate this guideline is by integrating Brandfetch into an existing app that offers more value than just the Brandfetch integration. Some examples: * ✅ The [Typeform integration](https://brandfetch.com/developers/customers/typeform) improves the user’s onboarding by presenting brand logos. Without this integration, the app still has a lot of value to its users. * ✅ The [Pitch integration](https://brandfetch.com/developers/customers/pitch) brings brand logos inside Pitch’s editor to streamline the creation of presentations. Without this integration, the app still has a lot of value to its users. * 🚫 A logo search that only returns logos from Logo API. Without the integration, the app has no content and no value to users. * 🚫 An unofficial Logo API that allows users to access brand logos via Logo API. Without the API, the app has no content and no value to users. If you're unsure about your use case, please [contact us](https://brandfetch.com/developers/contact). ## Rate limits We offer a fair use rate limit of 1,000,000 requests per month for free, which is designed to cover most small to medium applications, and paid plans include monthly volumes from 5 to 20 million requests — see the [pricing page](https://brandfetch.com/developers/pricing). These are soft limits and you won't immediately be blocked if you exceed yours. Traffic that runs far beyond your allowance can eventually be refused with a `429` carrying [`quota_exceeded`](#errors). If your usage approaches your limit, we’ll send you a friendly heads-up so you can adjust your usage or explore an upgrade. To maintain platform reliability, request throughput limits also apply: * 1,000 requests every 5 minutes per IP * 2,400 requests every 5 minutes per customer Exceeding these throughput limits returns an HTTP 429 status code, without an `x-bf-error` header. See [Errors](#errors) for how to tell a throughput block from the other reasons a request can be refused. Let us know if your application requires higher throughput. For enterprises, we provide custom solutions, including SLA agreements, custom terms, and flexible caching options to ensure optimal performance at scale. These plans are tailored to meet the needs of high-volume users. Feel free to [contact us](https://brandfetch.com/developers/contact/sales) to discuss the right plan for your use case. ## Errors When the Logo CDN refuses a request, the response carries an `x-bf-error` header naming the exact reason. A Logo API URL usually lives inside an `` tag, where no response body ever reaches your page, so read that header in your browser's network panel. `403` responses also return a JSON body with an `error` code, a `message` written for a human, and a `docs` link. The other statuses are header-only. Some refusals are answered with a `302` redirect to our [usage guidelines](#usage-guidelines) instead of an error status; inside an `` tag, that renders as a broken image. The throughput limits under [rate limits](#rate-limits) are enforced separately, so those responses carry no `x-bf-error` header. The presence of the header is what tells you the CDN refused the request for one of the reasons below. | `x-bf-error` | Status | What happened | What to do | | ----------------------------- | ------ | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `client_id_invalid_signature` | `403` | The `?c=` client ID is present but doesn't verify. This is almost always a transcription error. | Copy the client ID from your [developer dashboard](https://developers.brandfetch.com) instead of reading it off a screenshot. The message names the characters that get confused most often: lowercase `l` against capital `I` and the digit `1`, and the digit `0` against capital `O`. | | `client_id_disabled` | `403` | The client ID has been disabled. | [Contact us](https://brandfetch.com/developers/contact). | | `region_unavailable` | `403` | The Logo CDN isn't available in the viewer's country. | Nothing you can change in the request. | | `client_id_expired` | `410` | The client ID carries an expiry that has passed. | Use a client ID from your [developer dashboard](https://developers.brandfetch.com). | | `quota_exceeded` | `429` | Your organization has served far beyond its monthly Logo CDN allowance. | Raise your allowance and the block lifts within seconds. It also lifts on its own when your next billing period starts. | | `rate_limited` | `429` | The request was refused as abusive traffic. | Stop the source of the traffic, or [contact us](https://brandfetch.com/developers/contact) if you believe your traffic was caught by mistake. | | `client_id_required` | `302` | The request carried no `?c=` client ID and no usable `Referer`. | Add `?c=YOUR_CLIENT_ID` to the URL. | | `user_agent_required` | `302` | The request sent no `User-Agent` header at all. This applies whether or not you send a client ID. | Send a `User-Agent` header. | | `hotlink_blocked` | `302` | The `Referer` is one we don't serve logo traffic for, including `cdn.brandfetch.io` itself. | Embed the URL in your own pages with your own client ID, and check the `Referrer-Policy` requirements under [usage guidelines](#usage-guidelines). | | `automated_traffic` | `302` | The request looks programmatic rather than a logo embedded in a page. | Embed the URL in an `` tag. If your use case needs server-side access or caching, [contact us](https://brandfetch.com/developers/contact/sales) for a custom setup. | A valid client ID does not exempt a request from the `automated_traffic` check. A command-line fetch with a working client ID is still redirected, because Logo API URLs are meant to be embedded in your pages rather than fetched by a script. ### Once a request is accepted Anything past the checks above reaches the image itself. None of these responses carry an `x-bf-error` header. | Status | When | What you get | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | | `200` | A logo was found. | The image, with `ETag` and `Last-Modified` headers. WebP unless you asked for another format. | | `200` | The brand is unknown, the identifier doesn't resolve, the brand has no matching asset, or the URL itself can't be parsed (for example a malformed domain such as `brandfetch..com`). | A fallback image rather than an error status. Which one you get is set by the [`fallback`](/logo-api/parameters#fallback) value in the URL. | | `404` | You asked for `fallback/404` and no logo could be produced. | An empty body. The `404` is cached for up to 7 days, so it can keep coming back for a while after a logo becomes available. | | `503` | A temporary failure on our side, not something your request caused. | Retry. There's nothing to change in the request. | There's no `4xx` for an unsupported `format` or an out of range size either: an unrecognized `format` falls back to WebP, a `w` or `h` value that isn't a positive integer is ignored, and an unrecognized `fallback` value becomes the default. You can see all of these responses for your own traffic under **Usage History** in your [developer dashboard](https://developers.brandfetch.com), filtered by status class. # Parameters Source: https://docs.brandfetch.com/logo-api/parameters Detailed reference of all Logo API parameters ## URL Structure The Logo API uses a structured URL format that allows you to customize logo retrieval through path and query parameters: #### Short version ```html Domain theme={null} Logo by Brandfetch ``` ```html Ticker theme={null} Logo by Brandfetch ``` ```html ISIN theme={null} Logo by Brandfetch ``` ```html Crypto theme={null} Logo by Brandfetch ``` ```html Auto-detection (legacy) theme={null} Logo by Brandfetch ``` #### Full version with all parameters ```html Domain theme={null} Logo by Brandfetch ``` ```html Ticker theme={null} Logo by Brandfetch ``` ```html ISIN theme={null} Logo by Brandfetch ``` ```html Crypto theme={null} Logo by Brandfetch ``` ```html Auto-detection (legacy) theme={null} Logo by Brandfetch ``` To use Logo API, you must include your client ID with every request. To get your client ID, register for free from our [Developer Portal](https://developers.brandfetch.com/register). *** ## identifier **Type:** `string` **Required** Identifier to retrieve brand assets. Accepted formats: * **Domain:** `nike.com` * **Brand ID:** `id_0dwKPKT` * **ISIN:** `US6541061031` * **Stock or ETF ticker:** `NKE` * **Crypto symbol:** `BTC`, `ETH` (uppercase preferred) To avoid potential naming collisions between identifier types, you can use explicit type routes with the pattern `{type}/{identifier}`: * `domain/nike.com` - Query by domain name * `ticker/NKE` - Query by Stock or ETF ticker * `isin/US6541061031` - Query by ISIN code * `crypto/BTC` - Query by Crypto symbol **Examples:** ```html Domain theme={null} Logo by Brandfetch ``` ```html Ticker theme={null} Logo by Brandfetch ``` ```html ISIN theme={null} Logo by Brandfetch ``` ```html Crypto theme={null} Logo by Brandfetch ``` ```html Auto-detection (legacy) theme={null} Logo by Brandfetch ``` If you omit the type prefix (e.g., `nike.com` instead of `domain/nike.com`), the API will auto-detect the identifier type. The detection order is: Domain → Stock or ETF ticker → ISIN → Crypto symbol. However, **we recommend using explicit type routes** to prevent collisions and ensure accurate results. ## theme **Type:** `enum` * `light`: The light version of the logo * `dark`: The dark version of the logo ## fallback **Type:** `enum` * `brandfetch`: The Brandfetch logo * `transparent`: A see-through placeholder for custom background options * `lettermark`: A square icon featuring the first letter of the brand's name (applies only to type=icon) * `404`: HTTP status 404 and a see-through placeholder for custom background options **Default:** Varies by type * `brandfetch` for `icon` * `transparent` for `logo` and `symbol` ## h **Type:** `number` Height of the logo. The ratio of the logo is always respected. ## w **Type:** `number` Width of the logo. The ratio of the logo is always respected. ## type **Type:** `enum` * `icon`: (default) The icon used on social profiles (e.g., Tesla's social icon) * `logo`: The horizontal logo, usually seen on large surfaces (e.g., Tesla's logo) * `symbol`: The universal mark that abstractly represents the brand (e.g., Tesla's T symbol) # Brandfetch MCP Source: https://docs.brandfetch.com/mcp/overview Connect Brandfetch to AI assistants The Brandfetch MCP server exposes Brandfetch's brand data tools to any AI assistant that supports the [Model Context Protocol](https://modelcontextprotocol.io) (MCP), including Claude, Cursor, Windsurf, Gemini CLI, and others. Once configured, the assistant can search for brands, retrieve logos, brand assets, and firmographics data. The MCP server is available at: ``` https://mcp.brandfetch.io/mcp ``` ## Authentication The Brandfetch MCP server uses OAuth. When you add the server, your MCP client opens a browser window where you sign in with your Brandfetch account. If you don't have an account yet, [sign up for free](https://developers.brandfetch.com/register); the free plan includes 100 requests per month. If your MCP client doesn't support OAuth, or you're running in a non-interactive environment (CI, scripted agents), you can generate an MCP token in the [Keys and MCP section of the Developer Dashboard](https://developers.brandfetch.com/dashboard/keys) and send it as a bearer token: ```json theme={null} { "url": "https://mcp.brandfetch.io/mcp", "headers": { "Authorization": "Bearer YOUR_MCP_TOKEN" } } ``` Treat the token like a password: don't share or commit it. ## Setup In Claude Desktop or [claude.ai](https://claude.ai), go to **Settings → Connectors → Add custom connector** and enter: * **Name**: `Brandfetch` * **URL**: `https://mcp.brandfetch.io/mcp` Click **Add**, then **Connect** — a browser window opens to sign in with your Brandfetch account. To download or embed logos and other brand assets, Claude's code execution environment needs network access to Brandfetch's CDN. If your plan offers it, go to **Settings → Capabilities**, enable network egress for code execution, and add `*.brandfetch.io` to the domain allowlist. Availability of this setting varies by Claude plan. See [Downloading brand assets](#downloading-brand-assets) for what happens without it. Run the following command to add the Brandfetch MCP server: ```bash theme={null} claude mcp add brandfetch --transport http https://mcp.brandfetch.io/mcp ``` Then run `/mcp` inside Claude Code, select **brandfetch**, and follow the authentication prompt to sign in. Use the Command Palette and look for **MCP: Add Server**, choose **HTTP**, then use the URL above. Or create or open `.vscode/mcp.json` in your project and add: ```json theme={null} { "servers": { "brandfetch": { "type": "http", "url": "https://mcp.brandfetch.io/mcp" } } } ``` When the server starts, VS Code prompts you to sign in to Brandfetch. Add the following to `~/.codex/config.toml` (or `.codex/config.toml` inside your project): ```toml theme={null} [mcp_servers.brandfetch] url = "https://mcp.brandfetch.io/mcp" ``` Or run the CLI command: ```bash theme={null} codex mcp add brandfetch --url https://mcp.brandfetch.io/mcp ``` Then sign in with: ```bash theme={null} codex mcp login brandfetch ``` Open **Cursor Settings → MCP** and add a new server: ```json theme={null} { "mcpServers": { "brandfetch": { "url": "https://mcp.brandfetch.io/mcp" } } } ``` Click **Login** next to the server entry to sign in with your Brandfetch account. Open your Windsurf MCP configuration file and add: ```json theme={null} { "mcpServers": { "brandfetch": { "url": "https://mcp.brandfetch.io/mcp" } } } ``` Windsurf prompts you to sign in to Brandfetch when the server connects. ## The interactive brand card On MCP Apps hosts — [claude.ai](https://claude.ai) and Claude Desktop — `get_brand` renders a full brand profile directly in the conversation. Ask about a brand and the answer arrives as an interactive card: Interactive brand card in Claude showing the Logos tab: search bar, brand header, tab row, logo preview with format metadata, variant grid, and download actions * **Six tabs.** About (description, company facts, social links), Logos, Colors, Fonts, Images, and Brand voice — the same profile the [Developer Playground](https://brandfetch.com/developers/playground) shows, adapted to chat. * **Assets you can use immediately.** Pick any logo variant, switch between its available formats, and download the file or copy a ready-to-use URL. Each asset shows its format, file size, and dimensions. Downloads from the card are handed straight to Claude — no network allowlist required. * **Search without leaving the card.** Look up another brand from inside the card; the conversation follows, so "add that logo to the deck" always means the brand on screen. * **Opens on the right tab.** Ask for a specific aspect — "Okta's brand voice", "Nike's colors" — and the card opens directly on that tab. * **Native to Claude.** The card follows Claude's light and dark themes and typography, so it reads as part of the conversation. Text-only MCP clients are unaffected: `get_brand` returns the same brand data everywhere, and the card is a layer on top for hosts that support it. Already-connected clients pick up new capabilities after removing and re-adding the connector, since hosts cache a server's tool list. ## Available tools | Tool | Description | | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `brand_search` | Search for brands by name. Useful when the domain is unknown or ambiguous. | | `get_brand` | Retrieve full brand data (logos, colors, fonts, company info) by domain, email address, ticker, ISIN, or crypto symbol. On MCP Apps hosts it renders the [interactive brand card](#the-interactive-brand-card); an optional `view` argument opens the card on a specific tab. | | `get_brand_context` | Get LLM-ready brand context for a domain or email address: voice, audience, positioning, and style. Use when generating content or reasoning about brand fit. | | `enrich_transaction` | Identify a merchant brand from a raw credit card or bank statement string. | | `build_logo_urls` | Construct Brandfetch CDN logo URLs for one or more brands without making an API call. | | `send_feedback` | Send feedback about the MCP server (bugs, data quality, feature requests) to the Brandfetch team. | ## Downloading brand assets Downloading an asset for yourself is built into the [interactive brand card](#the-interactive-brand-card): the Download button hands the file straight to Claude, with no network configuration needed. When your assistant needs actual image bytes — embedding a logo in a generated document (PPTX, DOCX, PDF), saving files to disk, or processing pixels — the reliable path is to fetch the credentialed `src` URLs returned by `get_brand` directly from its code-execution environment (curl, requests, fetch). That keeps image bytes out of the conversation entirely. **Using Claude? Allowlist `cdn.brandfetch.io` first.** On [claude.ai](https://claude.ai) (web, desktop, and mobile apps) sandboxed code execution can only reach domains permitted by your network-egress settings. By default the Brandfetch CDN is blocked, so downloading logos, icons, and other assets is not possible. To enable direct downloads, go to **Settings → Capabilities**, enable network egress for code execution, and add `*.brandfetch.io` to the domain allowlist. On Pro and Max plans you can do this yourself; on Team and Enterprise plans the setting is org-level, so ask an Owner or Admin. We strongly recommend this for any workflow that downloads or embeds brand assets. Note that URLs from `build_logo_urls` are display-only under the hotlinking policy and can't be downloaded programmatically — always use the `src` URLs from `get_brand`, whose `?c=` token carries per-request credentials. If a generated document only needs to display a logo, it doesn't need the bytes at all: reference the credentialed `src` URL directly (a linked image in PPTX, an `` tag in HTML) and let the viewer fetch it. Clients that support MCP resource reads can also stream asset bytes out-of-band via the `bf://asset/{domain}/{type}` resource links returned by `get_brand`. ## Usage and quotas MCP requests count against your Brand API quotas. You can monitor your usage in the [Developer Dashboard](https://developers.brandfetch.com). # Explore dataset Source: https://docs.brandfetch.com/playground/index Try the Brandfetch APIs interactively in the Playground. Visit the [Playground](https://brandfetch.com/developers/playground) to try the Brandfetch APIs interactively. Experiment with the Brand API, Brand Context API, Logo API, and more. # Brand API (auto-detect) Source: https://docs.brandfetch.com/reference/brand-api GET /v2/brands/{identifier} Get brand data using a Domain, Email address, Brand ID, ISIN, Stock/ETF ticker, or Crypto symbol This endpoint auto-detects the identifier type. To prevent naming collisions, we recommend using one of the explicit type routes: * [By domain](/reference/brand-api-domain): `GET /v2/brands/domain/{domain}` * [By stock or ETF ticker](/reference/brand-api-ticker): `GET /v2/brands/ticker/{ticker}` * [By ISIN](/reference/brand-api-isin): `GET /v2/brands/isin/{isin}` * [By crypto symbol](/reference/brand-api-crypto): `GET /v2/brands/crypto/{symbol}` When using auto-detect, the identifier is resolved in the following order: domain → stock/ETF ticker → ISIN → crypto symbol. The API reads an identifier that contains `@` (or the percent-encoded `%40`) as an email address. It resolves the address to its registrable domain. `john@example.brandfetch.com` returns the same response as `brandfetch.com`. A mailbox provider's address resolves like any other address: a gmail.com address returns the brand of gmail.com. The API does not tell you whether the domain is the contact's company. A malformed address returns `400`, and the API does not bill the request. The API does not store the address. Your request logs show only the resolved domain. This endpoint and the [Brand Context API](/reference/brand-context-api) accept email addresses. The explicit type routes refuse an email address with a `400`. # Brand API by crypto Source: https://docs.brandfetch.com/reference/brand-api-crypto GET /v2/brands/crypto/{symbol} Get brand data using a crypto symbol # Brand API by domain Source: https://docs.brandfetch.com/reference/brand-api-domain GET /v2/brands/domain/{domain} Get brand data using a domain name # Brand API by ISIN Source: https://docs.brandfetch.com/reference/brand-api-isin GET /v2/brands/isin/{isin} Get brand data using an ISIN code # Brand API prefetch (HEAD) Source: https://docs.brandfetch.com/reference/brand-api-prefetch HEAD /v2/brands/{identifier} A `HEAD` request is the availability check: `200` when Brandfetch already holds the brand, `202` when it does not and a crawl has been queued, `404` when nothing can be fetched for the identifier — including a brand that has been removed. `HEAD` takes no `allowNsfw` parameter: a held brand answers `200` however a later `GET` is filtered. It never consumes a credit, and it is available on paid plans only — a free plan receives `403` with the header `x-bf-error: paid_plan_required`. A `503` with `x-bf-error: temporarily_unavailable` means the crawl could not be queued; retry later. Use it to warm a brand ahead of time — for example at signup, with the new user's email address — so the `GET` that renders your brand screen is answered from our store instead of waiting on a live crawl. See [Prefetching brands](/brand-api/overview#prefetching-brands). The same check works on the explicit domain route, [`HEAD /v2/brands/domain/{domain}`](/reference/brand-api-prefetch-domain). # Brand API prefetch by domain (HEAD) Source: https://docs.brandfetch.com/reference/brand-api-prefetch-domain HEAD /v2/brands/domain/{domain} The same availability check as [`HEAD /v2/brands/{identifier}`](/reference/brand-api-prefetch), on the explicit domain route: `200` held, `202` crawl queued, `404` nothing to fetch, `403` on a free plan, `503` when the crawl could not be queued. Like the other explicit type routes it accepts a domain only and refuses an email address with a `400`. # Brand API by ticker Source: https://docs.brandfetch.com/reference/brand-api-ticker GET /v2/brands/ticker/{ticker} Get brand data using a Stock or ETF ticker # Brand Context API Source: https://docs.brandfetch.com/reference/brand-context-api GET /v2/context/{domain} Get a structured, narrative-rich brand context for a domain — including identity, positioning, voice, and visual style. # Brand Search API Source: https://docs.brandfetch.com/reference/brand-search-api GET /v2/search/{name}?c={clientId} Search for brands by name, login to get a clientId Read our [guidelines](/brand-search-api/overview#usage-guidelines) before using the Brand Search API. # Transaction API Source: https://docs.brandfetch.com/reference/transaction-api POST /v2/brands/transaction Turn payment transactions into merchant data # Viewer API Source: https://docs.brandfetch.com/reference/viewer-api GET /v2/viewer Returns the identity of the credential used to authenticate the request: an API key or a user session token (JWT). Use it to verify a credential during integration setup (a `200` response means the credential is valid; `401`/`403` means it is missing, unknown, or revoked) and to display which API key and organization are connected. Requests to this endpoint are free: they never consume API credits. Calling this endpoint is **free**. It never consumes API credits, so you can use it to verify a credential during integration setup or on a health check. API key responses include the key's current credit `usage`, matching the `x-api-key-quota` and `x-api-key-approximate-usage` headers returned by billable endpoints. # Getting help Source: https://docs.brandfetch.com/support/getting-help Our support team is always available and willing to assist you. ## Technical Support If you come across any questions or encounter any issues, do not hesitate to [contact us](https://brandfetch.com/developers/contact). To help us quickly identify and fix the issue, kindly provide us with the following details: * The email address of your account. * The URL of the call you were making when the error occurred. * The brand you were accessing. * The status error you were facing. ## Contact sales If you want to ask for new features, buy additional API requests, unlock premium endpoints, or gain insights on how to make the most out of the API, [contact sales](https://brandfetch.com/developers/contact/sales) with us! # Report inaccuracies Source: https://docs.brandfetch.com/support/report-inaccuracies Report incorrect or missing brand info. We run an internal QA process to keep our brand library accurate and complete. If you spot missing or incorrect information in our index, you can let us know through [this form](https://brandfetch.com/update?mode=dev). Every submission is manually reviewed and, if verified, the update will be reflected in our index within 1-7 days, and we'll notify you once it's live. # Security & SOC2 Source: https://docs.brandfetch.com/support/security-soc2 Our commitment to secure data handling and best-in-class practices. Brandfetch is SOC 2 Type 2 certified. You can access our report and security documentation at our [Trust Center](https://trust.brandfetch.com). ## Overview Brandfetch is SOC 2 Type 2 compliant, having completed an independent audit covering the Security trust service category. Our enterprise customers, including leading multinational banks, trust our platform for its security posture and our commitment to best-in-class data handling practices. ### User Data & PII * **Minimal PII Storage**: Brandfetch does not collect or store Personally Identifiable Information (PII) beyond login email addresses for passwordless authentication. * **Logging**: We retain logs for up to 90 days for operational purposes. These may include IP addresses and User-Agent strings, which typically reflect server infrastructure rather than individual users. * **Zero Data Retention**: Enterprise customers can additionally enable [zero data retention](/support/zero-data-retention), which excludes queried identifiers, IP addresses, User-Agent strings, and other identifying request metadata from retained records. What remains — counts, timestamps, status codes, and the credential that made each request — attributes usage to the organization for billing without revealing what was queried or by whom. ### API Data Handling * **Public Data Only**: The Brandfetch API strictly processes publicly available data tied to domain names. It does not access, store, or interact with any private or customer-owned data. * **Data Processing Workflow**: Our API indexes, processes, and enhances publicly available brand data, making it accessible for our customers. At no point does the API interact with private data. ### Security Measures * **Data Encryption**: We utilize AES-256 encryption for data at-rest and TLS for data in-transit, ensuring end-to-end security. * **Secure Infrastructure**: Our development, staging, and production environments are hosted on Amazon Web Services (AWS), which offers secure, resilient hosting with 24x7 security and compliance certifications. * **Best Development Practices**: Our software development lifecycle adheres to OWASP best practices, incorporating human review processes enhanced by AI to maintain high quality standards. ## Contact sales Have questions about security, want to discuss enterprise usage, or need help optimizing your API integration?\ [Contact sales](https://brandfetch.com/developers/contact/sales) with our team to get started. # Service status Source: https://docs.brandfetch.com/support/service-status Check the status of Brandfetch services. For real-time updates and incident reports, please visit our [status page](https://status.brandfetch.io). If you're experiencing issues not reflected in our [status page](https://status.brandfetch.io), please don't hesitate to contact our support team. Get in touch with our support team for assistance # Terms and Conditions Source: https://docs.brandfetch.com/support/terms-and-conditions You can view our complete [Terms and Conditions](https://brandfetch.com/terms?mode=dev) for all the details. If you have specific legal questions about them, don't hesitate to reach out to our team Get in touch with our sales team for assistance # Zero data retention Source: https://docs.brandfetch.com/support/zero-data-retention An enterprise feature that keeps request metadata — the brands you query and the users behind the requests — out of Brandfetch's records. Zero data retention is an enterprise feature. [Contact sales](https://brandfetch.com/developers/contact/sales) to enable it for your organization. ## Overview Some customers — banks and other regulated businesses among them — must be able to show that their vendors keep no record of what their systems look up. Zero data retention is an enterprise feature built for exactly that, enabled for your organization by your account representative — [reach out](https://brandfetch.com/developers/contact/sales) if you would like it turned on. Once enabled, the following are excluded from all retained request records — request logs, usage analytics, and internal events: * Queried domains and brand identifiers (tickers, ISINs, crypto symbols, brand IDs) * IP addresses * User-Agent strings * Referer headers * Query parameters It applies to every request made with your organization's credentials: [Brand API](/brand-api/overview), [Brand Context API](/brand-context-api/overview), and [Transaction API](/transaction-api/overview) requests authenticated with an API key, and [Logo API](/logo-api/overview) and [Brand Search API](/brand-search-api/overview) requests carrying a client ID. ## What is retained For the covered APIs, billing and quota enforcement still count your usage, so records that attribute usage to your organization — but not what was queried or by whom — are kept: * Request counts, timestamps, and response status codes * The API key or client ID that made each request The request logs in your [developer portal](https://developers.brandfetch.com) reflect this too: identifying fields are empty, and queried identifiers appear as the placeholder `redacted.invalid`. ## Scope * Zero data retention applies from the moment it is enabled. It does not retroactively purge data recorded before then — talk to us if you also need historical records removed. * Short-lived operational logs involved in serving and metering requests are purged automatically within days. * Your own account activity — signing in, managing keys in the developer portal — is unaffected; the feature covers your API traffic's metadata, not your use of the dashboard. ## Why isn't this on for everyone? Request data makes the product better, and most customers benefit from contributing it. We use it to: * **Keep brand data fresh.** The domains and identifiers customers query tell us which brands to refresh first and which to elevate for manual curation and review — frequently requested brands get the most attention. * **Expand coverage.** Queries for brands we don't know yet are the strongest signal for what to index next. * **Maintain quality of service.** Traffic patterns drive caching, capacity planning, and performance work, and retained request records let us investigate abuse and enforce fair use — all of which keep the APIs fast and reliable for everyone. * **Help you debug.** The request logs in your developer portal — and the ones our support team reads when you report a problem — show exactly what a failing request looked up. With zero data retention enabled, your traffic stops contributing those signals: your queries no longer influence refresh and curation priority, and troubleshooting is limited to what you can share with us, since neither you nor our support team can see what a past request queried. That trade-off is the right one for regulated workloads and the wrong one for most — which is why it's opt-in per organization rather than the default. # Overview Source: https://docs.brandfetch.com/transaction-api/overview Turn payment transactions into merchant data The Transaction API identifies merchant brands from raw transaction data in a single call. It processes unstructured payment text, maps it to a domain, and returns brand details (e.g., name, logo, domain, industry, etc). For more details, refer to our [API Reference](/reference/transaction-api). Transaction API works in real-time to recognize merchants worldwide. If a brand is not part of our dataset, it will index the information live, providing data for brands of every size, geography, or sector. ## Implementation guide You’ll need to create an account on our [Developer Portal](https://developers.brandfetch.com/register). Creating an account is quick and easy, and will give you access to your dashboard where you’ll find your API key. Implement or run the code below to make your first API request. ```curl curl theme={null} curl --request POST \ --url https://api.brandfetch.io/v2/brands/transaction \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "transactionLabel": "STARBUCKS 1523 OMAHA NE", "countryCode": "US" }' ``` Authentication is done by passing your API key as a [Bearer Authentication](https://swagger.io/docs/specification/authentication/bearer-authentication/). The Transaction API can be accessed through the following structure: All requests for the domain brandfetch.com are free and will not count towards your usage/quotas. You can make as many requests to the Brandfetch’s brand as you need while you iterate on and test your integration. Once you are ready to go live, simply replace brandfetch.com with the domain name, Stock/ETF ticker, ISIN or Crypto symbol you want to look up. ## Transaction input The primary input for querying the Transaction API is a raw transaction descriptor (the line-item text on a bank or credit card statement). You provide this as the `transactionLabel` in the request body, along with a `countryCode` to narrow down the merchant’s locale. For example, a transaction label like `"STARBUCKS 1523 OMAHA NE"` with country code `"US"` can be resolved to starbucks.com. ## Quotas and usage Requests to the Transaction API count as **Brand fetches**, the shared usage unit across the Brand API, Brand Context API, and Transaction API. A single quota pool covers all three, so requests are deducted from the same balance regardless of which endpoint you call. ## API Reference For more details, refer to our [API Reference](/reference/transaction-api). # Company autocomplete Source: https://docs.brandfetch.com/use-cases/company-autocomplete Find your company as you type, with a logo on every result, powered by the Brand Search API "Type your company name" fields fail quietly: typos, subsidiaries, brands whose trading name doesn't match the legal one. The [Brand Search API](/brand-search-api/overview) turns that field into a type-ahead: a partial name goes in, matching brands come out, each with its name, domain, and logo. ## Match brand names to their domain and logo The classic type-ahead: debounced live search with each result showing the brand's icon, name, and domain. Selecting a result hands you the `domain` and `brandId`, the keys you pass to Brandfetch's other APIs. ```tsx BrandAutocomplete.tsx theme={null} import { useState, useEffect, useRef, type ChangeEvent } from "react"; const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register type BrandResult = { brandId: string; name: string; domain: string; icon: string }; export function BrandAutocomplete() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [selected, setSelected] = useState(null); const [open, setOpen] = useState(false); const reqId = useRef(0); useEffect(() => { const q = query.trim(); if (!q) { setResults([]); setLoading(false); return; } setLoading(true); const id = ++reqId.current; const t = setTimeout(async () => { try { const res = await fetch(`https://api.brandfetch.io/v2/search/${encodeURIComponent(q)}?c=${CLIENT_ID}`); const data = await res.json(); if (reqId.current === id) { setResults(Array.isArray(data) ? data.slice(0, 5) : []); setLoading(false); } } catch { if (reqId.current === id) { setResults([]); setLoading(false); } } }, 250); return () => clearTimeout(t); }, [query]); return (
setOpen(true)} onChange={(e: ChangeEvent) => { setQuery(e.target.value); setSelected(null); setOpen(true); }} />
{open && query.trim() && !selected && (
{results.length === 0 ? (
{loading ? "Searching…" : `No brands found for “${query.trim()}”`}
) : ( results.map((r) => ( )) )}
)} {selected && (
{`${selected.name
{selected.name || selected.domain}
{selected.domain} · {selected.brandId}
)}
); } ```
Build a brand search autocomplete input. As the user types, query Brandfetch's Brand Search API directly from the browser, it's free and needs only a client ID (get one at `https://developers.brandfetch.com/register`): ``` GET https://api.brandfetch.io/v2/search/{query}?c=YOUR_CLIENT_ID ``` The response is a JSON array of matches, each with `name`, `domain`, `brandId`, and `icon` (a ready-to-use logo URL). Render a dropdown under the input where each row shows the brand's icon, name, and domain. Hotlink the returned `icon` URL as-is (the URLs expire after 24 hours, so don't persist them). Don't render the response's `claimed` or `verified` fields as a badge, they're not meant to be surfaced as a trust signal in your UI. Debounce keystrokes by \~250-300ms, search from the first character, discard out-of-order responses, and show nothing until the user types (no default result list). When the user selects a result, keep its `domain` and `brandId`, those are the identifiers you pass to Brandfetch's Logo API and Brand API for logos and full brand data. Use the Search API the intended way: call it straight from the browser with your client ID (not a secret key), debounce input between keystrokes, and hotlink the returned `icon` URLs as-is without caching them (they expire after 24h). It should enhance a larger app, not replicate Brandfetch. ## Implementation Fire a search after a short pause in typing (\~200 ms). Requests can go straight from the browser, the API is free and authenticates with your client ID as a query parameter. ```text theme={null} GET https://api.brandfetch.io/v2/search/{name}?c=YOUR_CLIENT_ID ``` Each match carries the brand's `name`, `domain`, and `icon`, exactly the three things an autocomplete row needs. Show a skeleton row while the request is in flight. The selected `domain` is the stable key for everything that follows, store it, and chain into the [Brand API](/brand-api/overview) for colors, fonts, and company data when you need more than the logo. Review the [usage guidelines and rate limits](/brand-search-api/overview#usage-guidelines) before going live, search requests should come from your users' browsers, debounced between keystrokes. ## Pricing The Brand Search API is free. Create a client ID on the [Developer Portal](https://developers.brandfetch.com/register), no attribution required. ## Measuring impact Track the search-to-select rate on the field and completion of the flow it lives in. [Pitch reported a 3× increase in activation](https://brandfetch.com/developers/customers/pitch) after building company search into their product. ## Going further Match brand names to their domain and logo. Fetch full brand data once a user selects a result. Create a free account and start building. # Logo picker Source: https://docs.brandfetch.com/use-cases/logo-picker Let users search a brand and drop the right logo asset into the document, powered by the Brand Search API and Brand API Presentation, design, and document editors all need the same thing: a way for users to find a brand and insert its logo without leaving the canvas. The [Brand Search API](/brand-search-api/overview) powers the autocomplete, a partial name goes in, matching brands come out with a ready-to-use logo. And once a brand is selected, the [Brand API](/brand-api/overview) returns all of its available logos, logo, symbol, and icon, in light and dark themes, so users can view every variant and insert the one that fits. ## Instantly insert logos to your tool The same API powering an "insert logo" dialog, like a presentation or design editor where users search a brand and drop its logo into the document. This is the pattern behind the [Pitch integration](https://brandfetch.com/developers/customers/pitch). ```tsx LogoPicker.tsx theme={null} import { useState, useEffect, useRef, type ChangeEvent } from "react"; const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register type BrandResult = { brandId: string; name: string; domain: string; icon: string }; export function LogoPicker() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [picked, setPicked] = useState(null); const reqId = useRef(0); useEffect(() => { const q = query.trim(); if (!q) { setResults([]); setLoading(false); return; } setLoading(true); const id = ++reqId.current; const t = setTimeout(async () => { try { const res = await fetch(`https://api.brandfetch.io/v2/search/${encodeURIComponent(q)}?c=${CLIENT_ID}`); const data = await res.json(); if (reqId.current === id) { setResults(Array.isArray(data) ? data.slice(0, 4) : []); setLoading(false); } } catch { if (reqId.current === id) { setResults([]); setLoading(false); } } }, 250); return () => clearTimeout(t); }, [query]); return (
Insert brand logo
) => { setQuery(e.target.value); setPicked(null); }} />
{results.map((r) => { const isPicked = picked?.brandId === r.brandId; return ( ); })} {results.length === 0 && (
{loading ? "Searching…" : query.trim() ? `No brands found for “${query.trim()}”` : "Search for a brand to see its logo"}
)}
); } ```
Build an "insert brand logo" picker dialog for an editor. It has a search input at the top; as the user types, query Brandfetch's Brand Search API from the browser (free, client ID only; get one at `https://developers.brandfetch.com/register`): ``` GET https://api.brandfetch.io/v2/search/{query}?c=YOUR_CLIENT_ID ``` Render the results as a vertical list of selectable rows (limit to \~4), each showing the brand's `icon` image, `name`, and `domain` from the response. Clicking a row selects it (accent border and a checkmark) and enables an "Insert" button that places the logo into the document. Debounce keystrokes by \~300ms and hotlink the returned `icon` URLs as-is. For the inserted asset, render a high-resolution or themed variant from the Logo API using the selected result's `domain`: `https://cdn.brandfetch.io/domain/{domain}?c=YOUR_CLIENT_ID` (add `/type/logo`, `/theme/light`, or size segments as needed). Use the Search API the intended way: call it straight from the browser with your client ID (not a secret key), debounce input between keystrokes, and hotlink the returned `icon` URLs as-is without caching them (they expire after 24h). It should enhance a larger app, not replicate Brandfetch. ## Implementation Fire a search after a short pause in typing (\~250 ms). Requests can go straight from the browser, the API is free and authenticates with your client ID as a query parameter. ```text theme={null} GET https://api.brandfetch.io/v2/search/{name}?c=YOUR_CLIENT_ID ``` Each match carries the brand's `name`, `domain`, and `icon`. Lay the results out as selectable rows and hotlink the returned `icon` URLs as-is, don't cache them, they expire after 24 hours. On selection, fetch the full brand record with the [Brand API](/brand-api/overview) (server-side, so the API key stays secret) using the picked `domain`. Its `logos` array carries every variant the brand has, `type` (logo, symbol, icon), `theme` (light, dark), and `formats` (SVG, PNG, WebP), so you can display them all and let the user pick the exact asset to insert. ```bash theme={null} curl "https://api.brandfetch.io/v2/brands/domain/{domain}" \ --header "Authorization: Bearer YOUR_API_KEY" ``` Place the chosen variant's `src` into the document. For a lighter setup without the Brand API call, you can also render a single asset straight from the [Logo API](/logo-api/overview), choosing the size, type, and theme that fit the canvas. ```text theme={null} https://cdn.brandfetch.io/domain/{domain}/type/logo?c=YOUR_CLIENT_ID ``` Review the [usage guidelines and rate limits](/brand-search-api/overview#usage-guidelines) before going live, search requests should come from your users' browsers, debounced between keystrokes. ## Pricing The Brand Search API is free, and the Logo API is free with a client ID. Create one on the [Developer Portal](https://developers.brandfetch.com/register), no attribution required. Listing every available logo variant costs one [Brand API](/brand-api/overview) brand fetch per selected brand, and domain-level caching means each brand is fetched once. See [plans](https://brandfetch.com/developers/pricing) for quotas. ## Going further Match brand names to their domain and logo. The `logos` array: every variant, theme, and format. Create a free account and start building. # On-brand AI Source: https://docs.brandfetch.com/use-cases/on-brand-ai Ground LLMs and agents with real brand context using the Brand Context API and Brandfetch MCP Ask a model about a company and you get its training data: often stale, sometimes wrong, never on-brand. The [Brand Context API](/brand-context-api/overview) returns a structured, narrative-rich brand profile, identity, positioning, products, and visual style, built to drop straight into a model's context so answers are accurate and grounded, with a real logo attached. ## Ground AI in real brand data The profile the API returns is already grounded: tagline, mission, value proposition, products, target audiences, and voice guidance, verified brand data in one document. Using it is one call and one prompt: fetch it as Markdown, put it in the system prompt, and the model answers from the brand's verified facts instead of training data. The example uses Claude, but the pattern is identical for any model. ```ts grounded-answer.ts theme={null} import Anthropic from "@anthropic-ai/sdk"; const anthropic = new Anthropic(); // reads ANTHROPIC_API_KEY async function answerAboutBrand(domain: string, question: string) { // 1. Fetch the brand context; Markdown drops straight into a prompt const context = await fetch(`https://api.brandfetch.io/v2/context/${domain}`, { headers: { Authorization: `Bearer ${process.env.BRANDFETCH_API_KEY}`, Accept: "text/markdown", }, }).then((res) => res.text()); // 2. Ground the model: the brand profile becomes the system prompt const message = await anthropic.messages.create({ model: "claude-opus-4-8", max_tokens: 1024, system: `You answer questions about the company behind ${domain}. ` + `Ground every answer in the brand profile below; if the profile doesn't cover the question, say so.\n\n${context}`, messages: [{ role: "user", content: question }], }); return message.content .filter((block) => block.type === "text") .map((block) => block.text) .join(""); } console.log(await answerAboutBrand("patagonia.com", "What does Patagonia sell, and to whom?")); ``` ### Why not just ask the model? A good LLM can describe famous brands from memory, so it's fair to ask what the API adds. Five things: * **Long-tail coverage.** Models are weak on small businesses, regional companies, and brands that launched or rebranded after their training cutoff. Brand Context resolves domains live when they're not yet in the dataset, so coverage extends to brands no model's memory holds. * **Consistent structure at scale.** Run enrichment over 10,000 companies and you need the same fields back every time. Request `Accept: application/json` and every response follows the same schema: no reformatting between calls, no invented fields, no phrasing drift. At scale, that consistency is the product. * **Cost and latency.** A cached, deterministic API call is faster and cheaper than an LLM inference per lookup, and the difference compounds when you're personalizing 50,000 landing pages by visitor domain. * **Freshness.** Taglines, audiences, and messaging get updated by marketing teams all the time. A live-resolved profile reflects this month's positioning; a model reflects whatever was true when it was trained. * **Auditability.** Every response is tied to a fetchable source rather than a model's recollection, and for compliance-sensitive tools in sales or finance, "the model guessed" isn't good enough. Both calls run on your server, so both API keys stay secret. Cache the context by domain on your side too: the profile changes rarely, and repeat questions about the same company shouldn't cost a brand fetch each time. ## Implementation One call returns the brand profile, in Markdown by default, ready for a prompt. Keep it server-side so the API key stays secret, and cache by domain. ```bash theme={null} curl "https://api.brandfetch.io/v2/context/stripe.com" \ --header "Authorization: Bearer YOUR_API_KEY" ``` Add the profile to the system prompt or retrieval context before the model answers. Prefer structured fields over Markdown? Request `Accept: application/json`, see [content negotiation](/brand-context-api/overview#content-negotiation). ## Brandfetch MCP Already building with an AI assistant or agent framework? The Brandfetch MCP server exposes brand lookups as tools your model can call directly, so an agent can fetch a company's logo, colors, and profile mid-conversation without you wiring up the APIs by hand. Connect the MCP server and give your agent brand lookups as ready-made tools. ## Pricing Requests to the Brand Context API count as brand fetches, the shared usage unit across the Brand API, Brand Context API, and Transaction API, one quota pool covers all three. Caching by domain keeps repeat questions about the same company free. ## Measuring impact Grounding is easiest to judge on answer quality: track how often the model returns accurate, on-brand facts instead of stale or invented ones, and watch guesses give way to grounded answers for brands the model previously got wrong. [Synthesia generates an entire brand kit](https://brandfetch.com/developers/customers/synthesia) from nothing but a company URL this way, and the same grounding works for any generation flow. ## Going further The exact response shape: identity, positioning, products, and style. Brand lookups as ready-made tools for AI assistants and agents. Create a free account and start building. # Overview Source: https://docs.brandfetch.com/use-cases/overview Common use cases for brand data, each with a working example Every page in this section walks through a common use case and shows it running live, with a copyable prompt you can hand to your AI coding tool (or open straight in Cursor) to rebuild it in your own stack. ## Sales & ABM Client logos in decks, proposals, and white-label apps ## Product & PLG Sign users up and personalize the app from a work email Find your company as you type, with a logo on every result Brand data and logos on every company record Let users search a brand and drop in its logo ## Finance Identify merchants and enrich raw transactions Company logos in portfolios, watchlists, and trading apps ## AI Workflows Ground LLMs and agents with real brand context ## Build with Brandfetch Pick the use case closest to yours, copy its prompt into your AI coding tool, and ship it in your own stack. [Create a free account](https://developers.brandfetch.com/register) to start building in minutes. # Populate onboarding Source: https://docs.brandfetch.com/use-cases/populate-onboarding Boost conversion and activation by personalizing your users' onboarding from their email domain A new workspace shouldn't start empty. When someone signs up with their work email, you already know their company from the email domain. Instead of asking them to upload a logo, choose colors, or describe their business, you can populate the workspace automatically with a single [Brand API](/brand-api/overview) request. The result is an onboarding experience that feels like home, and this increases conversion and activation. ## Prefill brand for a faster onboarding As the user types a work email, extract the domain, look up the brand, and personalize the form. And it's more than a logo and a name: the same record carries the company's description, industry, size, founded year, and full color palette, enough to pre-fill a whole workspace profile. That's only a slice of the record, run any domain through the [Playground](https://brandfetch.com/developers/playground) to see everything the Brand API returns. ```tsx OnboardingEmailStep.tsx theme={null} import { useState, type ChangeEvent } from "react"; const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register // In production this comes from the Brand API; hardcoded here for the demo. type Brand = { name: string; color: string; description: string; founded: number; employees: string; industry: string; colors: string[]; }; const BRANDS: Record = { "stripe.com": { name: "Stripe", color: "#635BFF", description: "Financial infrastructure platform for the internet.", founded: 2010, employees: "8,000+", industry: "Fintech", colors: ["#635BFF", "#0A2540", "#00D4FF"] }, "dropbox.com": { name: "Dropbox", color: "#0061FF", description: "One place to keep life organized and keep work moving.", founded: 2007, employees: "2,600+", industry: "File storage", colors: ["#0061FF", "#1E1919", "#B4DC19"] }, "shopify.com": { name: "Shopify", color: "#95BF47", description: "The commerce platform powering millions of businesses.", founded: 2006, employees: "12,000+", industry: "E-commerce", colors: ["#95BF47", "#002E25", "#FBF7ED"] }, "linear.app": { name: "Linear", color: "#5E6AD2", description: "The purpose-built tool for planning and building products.", founded: 2019, employees: "60+", industry: "Dev tools", colors: ["#5E6AD2", "#222326", "#F4F5F8"] }, }; export function OnboardingEmailStep() { const [email, setEmail] = useState("sarah@stripe.com"); const domain = email.includes("@") ? email.split("@")[1].trim().toLowerCase() : ""; const brand = BRANDS[domain]; return (
) => setEmail(e.target.value)} placeholder="you@company.com" /> {brand ? (
{`${brand.name}
We found your company
{brand.name}
{brand.colors.map((c) => ( ))}
{brand.description}
{[brand.industry, `Founded ${brand.founded}`, `${brand.employees} employees`].map((t) => ( {t} ))}
) : (
Enter a work email to personalize your workspace.
)}
); } ```
Build a signup step with a work-email field that personalizes itself. When the user enters an email, take the part after the `@` as the domain, then look the company up and show a "We found your company" card with its logo, name, short description, quick-fact chips (industry, founded year, employee count), and a row of its brand-color swatches, and tint the primary button with the brand's accent color. Fetch the brand record from Brandfetch's Brand API (server-side, so the key stays secret; get one at `https://developers.brandfetch.com/register`): ``` GET https://api.brandfetch.io/v2/brands/domain/{domain} Authorization: Bearer YOUR_API_KEY ``` Use `brand.name` and `brand.description` for the card, `brand.company` for the facts (`industries`, `foundedYear`, `employees`, `location`), the `brand.colors` array for the swatches, and `brand.colors.find(c => c.type === "accent").hex` for the button. Render the logo with the Logo API (no key needed client-side): `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID` Skip free/personal email domains (gmail.com, outlook.com, etc.) so you only personalize for real company domains. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Welcome users with their brand Careers sites and talent marketplaces need a polished profile header for every employer. Instead of asking each company to upload assets, generate the header from its domain, a banner cover image, the logo, tagline, and firmographics, all from Brandfetch. A company header with the brand's own banner as the cover, the icon overlapping it, tagline, and quick facts, plus a call-to-action into open roles. ```tsx EmployerProfile.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const DOMAIN = "stripe.com"; const ACCENT = "#635BFF"; // brand.colors accent in production export function EmployerProfile() { return (
Stripe banner
Stripe logo
Stripe
Financial infrastructure for the internet
🌐 stripe.com 👥 8,000 employees 📍 San Francisco
); } ```
Build a company profile header for a careers or directory page. Show the brand's banner as a full-width cover image, the company icon overlapping its bottom edge with rounded corners and a thin border ring matching the card background (so it reads as a cutout), then the company name, tagline/description, and a row of quick facts (website, employee count, location), with a primary call-to-action button linking to open roles. Render the banner and icon straight from Brandfetch's Logo API (get a free client ID at `https://developers.brandfetch.com/register`): * Banner cover: `https://cdn.brandfetch.io/domain/{domain}/banner/w/760?c=YOUR_CLIENT_ID` * Icon: `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/128/h/128/fallback/lettermark?c=YOUR_CLIENT_ID` For the tagline, firmographics, and an accent color for the button, fetch the full record from the Brand API (server-side, `GET https://api.brandfetch.io/v2/brands/domain/{domain}` with `Authorization: Bearer YOUR_API_KEY`) and read `brand.description`, `brand.company`, and `brand.colors.find(c => c.type === "accent").hex`. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Implementation The whole flow is three steps: extract the domain, request the brand, populate the workspace, with a fallback when there's nothing to apply. Take what comes after the `@`, and filter out personal email providers so you only personalize for real company domains. Only the domain is sent to the API, the email address itself never leaves your system. ```ts theme={null} const FREE_PROVIDERS = new Set([ "gmail.com", "outlook.com", "hotmail.com", "yahoo.com", "icloud.com", "proton.me", ]); function domainFromEmail(email: string): string | null { const domain = email.split("@")[1]?.trim().toLowerCase(); if (!domain || FREE_PROVIDERS.has(domain)) return null; // → default onboarding return domain; } ``` Look the domain up with the [Brand API](/brand-api/overview). Keep this call on your server so the API key stays secret, and fire it as soon as the email field validates, the response is ready by the time onboarding begins. Since many users from the same company sign up over time, cache the response by domain. ```bash theme={null} curl "https://api.brandfetch.io/v2/brands/domain/stripe.com" \ --header "Authorization: Bearer YOUR_API_KEY" ``` The response carries the company's name, logos, colors, fonts, description, and firmographics. Explore the full record for any domain in the [Playground](https://brandfetch.com/developers/playground), or see the [Brand API reference](/reference/brand-api-domain). In most cases that means the company name and logo, plus the accent color if your UI supports theming. If the domain can't be resolved or the user signed up with a personal email, fall back to your default onboarding flow, personalization is a layer on top, never a blocker. > "We capture the domain from the user's email, hit the Brand API, cache the result, and we're done." > > **Haris Ali**, Head of Product, LottieFiles If you're generating onboarding content with AI, you can also call the [Brand Context API](/brand-context-api/overview) to retrieve the company's positioning, tone of voice, products, and target audience. ## Pricing This flow typically requires one Brand API request per signup, or two if [Brand Context](/brand-context-api/overview) is also used. Domain-level caching reduces usage further for larger teams. Self-serve plans support up to 10,000 requests per month. Higher volumes are available through [enterprise plans](https://brandfetch.com/developers/enterprise), with SOC 2 and DPA documentation available during procurement. ## Measuring impact The simplest experiment is an A/B test comparing a personalized first session with your existing onboarding. [Typeform measured free-to-paid conversion](https://brandfetch.com/developers/customers/typeform) and reported a 5% improvement after introducing branded onboarding. You can also measure activation metrics such as workspace completion, first project created, or time to first value. ## Going further The full record: name, logo, colors, description, and firmographics. Add positioning and tone of voice for AI-generated onboarding copy. Create a free account and start building. # Profiles & directory Source: https://docs.brandfetch.com/use-cases/profiles-and-directory Put verified logos and brand data on every company record, in account lists, CRM contacts, job listings, and logo walls A list full of gray placeholder avatars reads as unfinished. The same list with every company's real logo reads as authoritative, and it's the difference between a text database and a product people trust. Whether the records are CRM accounts, job listings, or a wall of customer logos, the pattern is the same two tiers: the [Logo API](/logo-api/overview) covers every list view with a plain `` tag, and the [Brand API](/brand-api/overview) fills detail views with colors, descriptions, and firmographics. ## Company directory CRMs and B2B directories are easier to scan when every account shows the company's real logo instead of a generic placeholder. For a list of accounts, an `` pointed at the Logo API is enough, no fetch, no loading state. ```tsx AccountList.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const ACCOUNTS = [ { domain: "shopify.com", name: "Shopify", meta: "shopify.com · 12,000 employees" }, { domain: "stripe.com", name: "Stripe", meta: "stripe.com · 8,000 employees" }, { domain: "dropbox.com", name: "Dropbox", meta: "dropbox.com · 2,600 employees" }, { domain: "linear.app", name: "Linear", meta: "linear.app · 60 employees" }, ]; export function AccountList() { return (
{ACCOUNTS.map((acc) => (
{`${acc.name}
{acc.name}
{acc.meta}
))}
); } ```
Build an account list for a CRM or company directory: a vertical list of rows, each showing the company's logo, name, and a secondary line (domain, employee count, etc.) in a compact horizontal layout. Fetch each logo via Brandfetch's Logo API `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Add a subtle background color highlight on hover. No fetch or loading state is needed since it's a direct image URL. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Card grid with hover lift On grid-based boards, wrap the same data in a card and add a subtle lift on hover so the grid feels responsive to the cursor. ```tsx JobCardGrid.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const JOBS = [ { domain: "dropbox.com", title: "Product Designer", company: "Dropbox · SF" }, { domain: "vercel.com", title: "DevRel Engineer", company: "Vercel · Remote" }, { domain: "shopify.com", title: "Growth Marketer", company: "Shopify · NYC" }, { domain: "stripe.com", title: "Backend Engineer", company: "Stripe · Remote" }, { domain: "linear.app", title: "Product Manager", company: "Linear · Remote" }, { domain: "airbnb.com", title: "Data Scientist", company: "Airbnb · Dublin" }, ]; export function JobCardGrid() { return (
{JOBS.map((job) => (
{`${job.domain}
{job.title}
{job.company}
))}
); } ```
Build a responsive grid of job cards for a job board. Each card shows the employer's logo (fetched via `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID`, get a free client ID at `https://developers.brandfetch.com/register`), the job title, and company/location. Use CSS Grid with `repeat(auto-fill, minmax(220px, 1fr))` for the layout. Add a subtle hover interaction: lift the card 4px with translateY and add a soft box-shadow, animated with a 150ms ease transition. Adapt the styling to match my project's existing design system. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Customer logos The trick to a tidy wall is a uniform grid: each logo sits centered in an equal-size cell and is capped to the same height, so brands with very different aspect ratios still line up. A fixed column count keeps every row full, no stray logo stranded on its own. ```tsx CustomerLogos.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const DOMAINS = [ "airbnb.com", "github.com", "google.com", "intel.com", "okta.com", "canva.com", "attio.com", "linkedin.com", ]; export function CustomerLogos() { return (
{DOMAINS.map((domain) => (
{/* theme/dark returns the dark-on-light logo; invert it to white in dark mode */} {`${domain}
))}
); } ```
Build a "trusted by" wall of customer or partner logos as a uniform grid. Fetch each logo from Brandfetch's Logo API using the horizontal wordmark variant `https://cdn.brandfetch.io/domain/{domain}/h/56/w/120/type/logo?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Lay them out with CSS Grid using a fixed column count (e.g. 4 columns, responsive down to 2 on mobile) so every row stays full and no logo is left stranded. Give each grid cell a fixed height and center the logo inside it with `object-contain` and a capped max-height/max-width, so brands with different aspect ratios all render at a consistent visual size. Add a subtle hover treatment (a faint background tile). Pick a logo count that fills the grid evenly. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Animated logos A 6×3 grid where every tile flips in 3D on its Y axis to reveal a second brand on the back face, staggered on a diagonal so the wall ripples rather than flipping in unison. ```tsx FlipWall.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const POOL = [ "framer.com", "netflix.com", "airbnb.com", "uber.com", "lyft.com", "doordash.com", "tiktok.com", "snapchat.com", "producthunt.com", "reddit.com", "twitch.tv", "linkedin.com", "discord.com", "medium.com", "google.com", "microsoft.com", "apple.com", "amazon.com", "meta.com", "adobe.com", "salesforce.com", "nvidia.com", "samsung.com", "sony.com", "x.com", "slack.com", "vimeo.com", "dribbble.com", "stripe.com", "github.com", "gitlab.com", "dropbox.com", "zoom.us", "asana.com", "trello.com", "atlassian.com", ]; const src = (d: string) => `https://cdn.brandfetch.io/domain/${d}/type/icon/w/112/h/112/fallback/lettermark?c=${CLIENT_ID}`; export function FlipWall() { const tiles = Array.from({ length: 18 }, (_, i) => { const row = Math.floor(i / 6); const col = i % 6; return { a: POOL[i], b: POOL[i + 18], d: -((row + col) * 0.35), i }; }); return (
{tiles.map(({ a, b, d, i }) => (
{a} {b}
))}
); } ```
Build an animated logo wall as a grid (e.g. 6×3) of square icon tiles that flip in 3D to reveal a second brand, so the wall shows twice as many brands as it has slots. Each tile is a card with a front face (brand A) and a back face (brand B) that rotates on its Y axis. Set `perspective` on the tile wrapper, `transform-style: preserve-3d` on the rotating inner element, and `backface-visibility: hidden` on both faces (the back face pre-rotated `rotateY(180deg)`). Animate the inner element's `rotateY` with a CSS `@keyframes` (0° → 180° → 360°, with holds so each face stays readable), and stagger the `animation-delay` by grid position (row + column) so the flips ripple diagonally across the wall. Render each face from Brandfetch's Logo API `icon` variant: `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/56/h/56/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Use `fallback/lettermark` so a tile never shows a broken image. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Infinite scroll marquee An auto-scrolling row loops seamlessly, letting you show two or three times as many logos in the same footprint, useful for long partner lists. Using the square `icon` variant keeps every mark colorful and the same size, so the row reads as one clean band. ```tsx LogoMarquee.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const DOMAINS = [ "shopify.com", "airbnb.com", "nike.com", "discord.com", "slack.com", "stripe.com", "dropbox.com", "reddit.com", "medium.com", "meta.com", ]; export function LogoMarquee() { const track = [...DOMAINS, ...DOMAINS]; // duplicate so the loop has no seam return (
{track.map((domain, i) => ( {`${domain} ))}
); } ```
Build an auto-scrolling logo marquee that loops seamlessly. Render a row of partner logos twice back-to-back (so the loop has no visible seam), each fetched as a square `icon` from `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/80/h/80/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Icons are colorful and all the same size, so the band stays even and vivid. Animate the track horizontally from `translateX(0)` to `translateX(-50%)` on an infinite linear loop (about 15-25s), pause the animation on hover, and fade the edges with a `mask-image` gradient so logos don't appear abruptly. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Inline logo swap A single rotating slot works inline too, drop it into a headline or a "trusted by" line to cycle a marquee brand through the sentence. ```tsx InlineLogoSwap.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const DOMAINS = ["airbnb.com", "slack.com", "discord.com", "linear.app", "stripe.com"]; const src = (d: string) => `https://cdn.brandfetch.io/domain/${d}/type/icon/w/96/h/96/fallback/lettermark?c=${CLIENT_ID}`; export function InlineLogoSwap() { return (
Trusted by {DOMAINS.map((d, i) => ( {d} ))} and 20,000+ teams
); } ```
Build an inline animated logo slot that rotates through several company icons, sized to sit inside a line of text (e.g. "Trusted by \[logo] and 20,000+ teams"). Stack the icons absolutely in a small fixed-size inline-block span and crossfade them with a CSS `@keyframes` animation. With N icons, give each the same keyframe (visible for \~1/N of the cycle, then hidden) and offset each one's `animation-delay` by cycle/N so they rotate one after another. Fetch each icon from `https://cdn.brandfetch.io/domain/{domain}/type/icon/w/48/h/48/fallback/lettermark?c=YOUR_CLIENT_ID` (get a free client ID at `https://developers.brandfetch.com/register`). Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Implementation The domain is the identifier that makes everything else work. If your data only has company names, match them to domains first with the [Brand Search API](/brand-search-api/overview). For rows, cards, and avatars, point an `` at the CDN, no fetch, no loading state, and `fallback/lettermark` guarantees a clean monogram for brands not yet in the dataset. ```text theme={null} https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID ``` When a user opens a record, fetch the full brand server-side for the description, accent color, and firmographics, and cache it by domain so repeat visits are free. ```bash theme={null} curl "https://api.brandfetch.io/v2/brands/domain/stripe.com" \ --header "Authorization: Bearer YOUR_API_KEY" ``` ## Pricing List views cost nothing, the [Logo API](/logo-api/overview) is free with a client ID. Detail views cost one Brand API brand fetch per company, and domain-level caching means each company is fetched once, not once per viewer. See [plans](https://brandfetch.com/developers/pricing) for quotas. ## Going further Sizing, type, theme, and fallback options for every logo. The full record: logos, colors, images, and firmographics for detail views. Create a free account and start building. # Sales personalization Source: https://docs.brandfetch.com/use-cases/sales-personalization Auto-brand decks, proposals, and emails with your prospect's logo and colors Generic sales collateral gets generic attention. A deck that opens in the prospect's colors, an email header carrying their mark, that's collateral that feels made for them, because it was. All of it hangs off a single lookup: resolve the prospect's domain, fetch the brand, apply it to the template. ## Personalize decks and presentations Presentation tools can make any deck instantly on-brand by pulling a company's logo, colors, and fonts from its domain. The [Brand API](/brand-api/overview) returns all three in one call, so a template restyles itself the moment a user types a domain. ```tsx SlideThemeSwitcher.tsx theme={null} import { useState } from "react"; const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register // Palettes come from the Brand API in production (brand.colors); hardcoded here. const BRANDS = [ { name: "Claude", domain: "claude.ai", palette: ["#D97757", "#191919", "#F0EEE6"] }, { name: "Airbnb", domain: "airbnb.com", palette: ["#FF385C", "#222222", "#FFFFFF"] }, { name: "Linear", domain: "linear.app", palette: ["#5E6AD2", "#08090A", "#8A8F98"] }, { name: "Attio", domain: "attio.com", palette: ["#266DF0", "#232529", "#5C5E63"] }, ]; export function SlideThemeSwitcher() { const [active, setActive] = useState(BRANDS[0]); const [accent, second, third] = active.palette; const logo = (theme: "light" | "dark") => `https://cdn.brandfetch.io/domain/${active.domain}/h/48/theme/${theme}/type/logo/fallback/lettermark?c=${CLIENT_ID}`; return (
{BRANDS.map((b) => ( ))}
{`${active.name} {`${active.name} 01
2026 · All hands
Q3 Business Review
{active.name} · Confidential
{active.domain} {active.palette.map((c) => ( ))}
); } ```
Build a presentation title slide (16:9) that themes itself from a company's brand. Show a brand picker; when a brand is selected, restyle the slide. Make it look like a real deck slide: the company logo top-left with a page number top-right, an uppercase kicker line in the brand's accent color, a large bold title with a muted subtitle, and a footer rule with the domain on the left and the brand's palette as small dots on the right. Use the brand's full color palette, not just one color: the accent leads (kicker, main bar), and the secondary colors drive the bottom edge strip split into palette-colored segments. For the decorative circles bleeding off the slide corners, use only the accent color (palettes often carry near-white or near-black secondaries that wash out): one soft filled circle at low opacity and one thin outlined ring, so the corner reads as a pattern rather than flat blobs. Fetch the brand record from Brandfetch's Brand API (server-side, so the API key stays secret; get one at `https://developers.brandfetch.com/register`): ``` GET https://api.brandfetch.io/v2/brands/domain/{domain} Authorization: Bearer YOUR_API_KEY ``` From the response use: the full `brand.colors` array for the palette (the accent is `brand.colors.find(c => c.type === "accent").hex`), and `brand.fonts[0].name` for the heading font. Render the logo with the Logo API: `https://cdn.brandfetch.io/domain/{domain}/type/logo?c=YOUR_CLIENT_ID` Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Convert with branded emails Email builders and transactional-email systems can theme every message to the sender's brand, logo in the header, accent color on the call-to-action, without designers hand-editing templates. The [Brand API](/brand-api/overview) supplies the logo and colors from a single domain. Pick a brand and the whole email retheme, header logo, accent bar, and the call-to-action button all update from one brand record. ```tsx BrandedEmail.tsx theme={null} import { useState } from "react"; const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register // Accent colors come from the Brand API (brand.colors) in production. const BRANDS = [ { name: "Claude", domain: "claude.ai", color: "#D97757" }, { name: "Linear", domain: "linear.app", color: "#5E6AD2" }, { name: "Dropbox", domain: "dropbox.com", color: "#0061FF" }, { name: "Shopify", domain: "shopify.com", color: "#95C049" }, ]; export function BrandedEmail() { const [active, setActive] = useState(BRANDS[0]); const logo = (theme: "light" | "dark") => `https://cdn.brandfetch.io/domain/${active.domain}/h/52/theme/${theme}/type/logo/fallback/lettermark?c=${CLIENT_ID}`; return (
{BRANDS.map((b) => ( ))}
{`${active.name} {`${active.name}
Welcome to {active.name} 👋
Thanks for signing up. Let's get your account set up, it only takes a minute to send your first request.
Sent by {active.name} · You can unsubscribe at any time.
); } ``` Build a responsive HTML email template that themes itself from a company's brand: a thin accent-color bar at the very top, a white header containing the company logo, a body with a heading and paragraph, a call-to-action button filled with the brand's accent color, and a muted footer. Fetch the brand record from Brandfetch's Brand API (server-side so the key stays secret; get one at `https://developers.brandfetch.com/register`): ``` GET https://api.brandfetch.io/v2/brands/domain/{domain} Authorization: Bearer YOUR_API_KEY ``` Use `brand.colors.find(c => c.type === "accent").hex` for the accent bar and button, and render the header logo with the Logo API so it hotlinks and stays current: `https://cdn.brandfetch.io/domain/{domain}/type/logo?c=YOUR_CLIENT_ID` Keep the markup email-client-safe (table-based layout, inline styles). Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Implementation You usually have it already, the website on the CRM record, or the domain of a contact's email. If reps only have a company name, resolve it with [company autocomplete](/use-cases/company-autocomplete). One [Brand API](/brand-api/overview) call returns the logos, colors, and fonts for the domain. Keep the call on your server so the API key stays secret, and cache the response by domain, the same account gets pitched more than once. ```bash theme={null} curl "https://api.brandfetch.io/v2/brands/domain/stripe.com" \ --header "Authorization: Bearer YOUR_API_KEY" ``` Render logos straight from the [Logo API](/logo-api/overview) in an `` tag, and use the accent color for headers, buttons, and highlights. If a domain can't be resolved, fall back to your default template, personalization is a layer, never a blocker. ## Pricing Logos alone are free via the [Logo API](/logo-api/overview). Pulling colors and fonts costs one Brand API brand fetch per company, cached by domain, so a pipeline of hundreds of accounts means hundreds of requests, not thousands. See [plans](https://brandfetch.com/developers/pricing) for quotas. ## Measuring impact Personalization is a conversion play, so measure branded collateral against generic templates: reply and meeting-booked rates on outreach, and engagement on decks and proposals that open in the prospect's brand. Teams like [CyberRisk use this](https://brandfetch.com/developers/customers/cyberrisk) to carry client logos across decks, proposals, and white-label apps. ## Going further The full response shape: logos, colors, fonts, and company data. Hotlink logos and banners straight into decks and emails. Create a free account and start building. # Stock ticker logos Source: https://docs.brandfetch.com/use-cases/stock-ticker-logos Show company logos in stock watchlists and portfolio cards using the Logo API's ticker route Investing apps feel instantly familiar when every holding shows the company's real logo. The [Logo API](/logo-api/overview) resolves a logo directly from a **stock or ETF ticker**, no separate ticker-to-domain mapping to build or maintain. ## Ticker watchlist A ticker watchlist with logo, symbol, name, and a color-coded daily change, the core of any brokerage or portfolio screen. ```tsx TickerWatchlist.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register const HOLDINGS = [ { symbol: "AAPL", name: "Apple Inc.", price: "227.52", change: "+1.24%", up: true }, { symbol: "NVDA", name: "NVIDIA Corp.", price: "138.07", change: "+3.45%", up: true }, { symbol: "TSLA", name: "Tesla, Inc.", price: "251.44", change: "-2.10%", up: false }, { symbol: "AMZN", name: "Amazon.com, Inc.", price: "201.16", change: "+0.62%", up: true }, ]; export function TickerWatchlist() { return (
{HOLDINGS.map((h) => (
{`${h.name}
{h.symbol}
{h.name}
${h.price}
{h.change}
))}
); } ```
Build a stock watchlist: a vertical list of rows, each showing the company's logo, its ticker symbol, company name, current price, and a color-coded daily change (green when up, red when down). Fetch each logo from Brandfetch's Logo API using the ticker route (get a free client ID at `https://developers.brandfetch.com/register`): `https://cdn.brandfetch.io/ticker/{SYMBOL}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID` The ticker route maps a stock or ETF symbol (e.g. `AAPL`, `TSLA`, `QQQ`) straight to the company's logo, so no domain lookup is needed. Use `fallback/lettermark` so a row never shows a broken image. Add a subtle background highlight on row hover. Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Portfolio holding card A single holding rendered as a card, with the logo, position value, and daily change, for a portfolio or position-detail view. ```tsx TickerPortfolioCard.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register export function TickerPortfolioCard() { return (
NVIDIA logo
NVDA
NVIDIA Corp.
$4,142.10
▲ $103.50 (3.45%) today
30 shares Avg $130.24
); } ```
Build a portfolio holding card for a single position. Show the company's logo and ticker at the top, the current position value in large bold text, a color-coded daily change (green up / red down) with a directional arrow, and a footer row with shares held and average cost. Fetch the logo from Brandfetch's Logo API ticker route (get a free client ID at `https://developers.brandfetch.com/register`): `https://cdn.brandfetch.io/ticker/{SYMBOL}/w/44/h/44/fallback/lettermark?c=YOUR_CLIENT_ID` Use the Logo API the intended way: hotlink the CDN URL directly in the image `src`, don't download, cache, or re-host the file. Requests are free with a client ID and always return the brand's current logo. ## Implementation Register on the [Developer Portal](https://developers.brandfetch.com/register), the Logo API is free and requires no attribution. Swap the usual `domain` segment for `ticker`, the CDN resolves the symbol to the company for you. The same route also accepts `isin/{ISIN}` and `crypto/{SYMBOL}`. ```text theme={null} https://cdn.brandfetch.io/ticker/{SYMBOL}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID ``` Keep `fallback/lettermark` so delisted or unrecognized symbols still render a clean monogram instead of a broken image. ## Pricing The Logo API is free, including the ticker, ISIN, and crypto routes. Create a client ID on the [Developer Portal](https://developers.brandfetch.com/register), no attribution required. ## Measuring impact Logos on holdings are a recognition and trust signal, so watch for engagement lifts on list and detail screens: taps into holdings, watchlist adds, and time spent on portfolio views. [GBM uses this pattern](https://brandfetch.com/developers/customers/gbm) across portfolios, watchlists, and trading screens. ## Going further All identifier routes and sizing, type, and theme options. Company name, exchange, and sector alongside the logo. Create a free account and start building. # Transaction enrichment Source: https://docs.brandfetch.com/use-cases/transaction-enrichment Turn raw payment descriptors into clean merchant identity, category, and logo using the Transaction API Bank and card statements arrive as unstructured line-item text, `SQ *BLUE BOTTLE COFFEE OAKLAND`, `AMZN MKTP US*2X4B1QT0`, `UBER *EATS 8005928996 CA`. Users don't recognize the charge, support tickets follow, and spend categorization breaks. The [Transaction API](/transaction-api/overview) resolves that text to the real merchant in a single call, returning the company's name, domain, industry, and logo, so banking, spend-tracking, and accounting apps can categorize spend and show a feed people actually recognize. ## Show merchants, not codes Raw transaction descriptors like `SQ *BLUE BOTTLE COFFEE OAKLAND` are unreadable. The [Transaction API](/transaction-api/overview) resolves that line-item text to a real merchant, name, domain, industry, and logo, in a single call, so banking and spend-tracking apps can show a clean, recognizable feed. ### Transaction feed A statement-style feed where each charge shows the recognized merchant and logo, with the original bank descriptor kept underneath for reference. ```tsx TransactionFeed.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register // merchant + domain come from the Transaction API; the raw descriptor is the input. const TXNS = [ { domain: "starbucks.com", merchant: "Starbucks", raw: "STARBUCKS 1523 OMAHA NE", amount: "6.45", date: "Jul 3" }, { domain: "amazon.com", merchant: "Amazon", raw: "AMZN MKTP US*2X4B1QT0", amount: "42.99", date: "Jul 2" }, { domain: "uber.com", merchant: "Uber Eats", raw: "UBER *EATS 8005928996 CA", amount: "23.10", date: "Jul 1" }, { domain: "netflix.com", merchant: "Netflix", raw: "NETFLIX.COM 866-579-7172", amount: "15.49", date: "Jun 30" }, ]; export function TransactionFeed() { return (
{TXNS.map((t) => (
{`${t.merchant}
{t.merchant}
{t.raw}
-${t.amount}
{t.date}
))}
); } ```
Build a transaction feed for a banking or spend-tracking app. Each row shows the merchant's logo, the recognized merchant name, the original raw bank descriptor underneath in a smaller monospaced muted font, and the amount and date on the right. Resolve each raw descriptor to a merchant with Brandfetch's Transaction API (get an API key at `https://developers.brandfetch.com/register`): ``` POST https://api.brandfetch.io/v2/brands/transaction Authorization: Bearer YOUR_API_KEY Content-Type: application/json { "transactionLabel": "STARBUCKS 1523 OMAHA NE", "countryCode": "US" } ``` The response includes the merchant's `name`, `domain`, and `industry`. Render its logo from the domain via the Logo API: `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID` Call the Transaction API from your server so the API key stays secret, then hotlink the returned merchant logo URL directly on the client rather than downloading or re-hosting it. ### Descriptor enrichment Show the raw-to-recognized transformation directly, useful in a transaction detail view or when confirming a match. ```tsx TransactionEnrichment.tsx theme={null} const CLIENT_ID = "YOUR_CLIENT_ID"; // free client ID from developers.brandfetch.com/register export function TransactionEnrichment() { return (
Raw descriptor
SQ *BLUE BOTTLE COFFEE OAKLAND
Recognized merchant
Blue Bottle Coffee logo
Blue Bottle Coffee
bluebottlecoffee.com · Food & Beverage
); } ```
Build a transaction detail card that shows the enrichment visually: at the top, the raw bank descriptor in a monospaced pill; below it a downward arrow; then the recognized merchant in a bordered row with its logo, name, domain, and industry. Resolve the descriptor with Brandfetch's Transaction API (get an API key at `https://developers.brandfetch.com/register`): ``` POST https://api.brandfetch.io/v2/brands/transaction Authorization: Bearer YOUR_API_KEY Content-Type: application/json { "transactionLabel": "SQ *BLUE BOTTLE COFFEE OAKLAND", "countryCode": "US" } ``` Use the returned `domain` to render the merchant logo from the Logo API: `https://cdn.brandfetch.io/domain/{domain}/w/36/h/36/fallback/lettermark?c=YOUR_CLIENT_ID` Call the Transaction API from your server so the API key stays secret, then hotlink the returned merchant logo URL directly on the client rather than downloading or re-hosting it. ## Implementation POST the raw line-item text as `transactionLabel`, with a `countryCode` to disambiguate merchants that share a name across regions. Keep the call on your server so the API key stays secret. ```bash theme={null} curl --request POST "https://api.brandfetch.io/v2/brands/transaction" \ --header "Authorization: Bearer YOUR_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "transactionLabel": "SQ *BLUE BOTTLE COFFEE OAKLAND", "countryCode": "US" }' ``` The identified merchant comes back as a full brand record, use `name` as the display label, `industry` as the spend category, and render the logo from `domain` via the [Logo API](/logo-api/overview): `https://cdn.brandfetch.io/domain/{domain}/w/40/h/40/fallback/lettermark?c=YOUR_CLIENT_ID`. The same descriptor recurs across statements, cache resolutions by normalized descriptor text. When a descriptor can't be resolved, keep showing the raw text rather than guessing. ## Pricing The Transaction API is an [enterprise product](https://brandfetch.com/developers/contact/sales). Requests count as brand fetches, the shared usage unit across the Brand API, Brand Context API, and Transaction API, so a single quota pool covers all three. ## Measuring impact Enrichment works when people recognize their charges, so track the merchant match rate on incoming descriptors and the drop in "what is this charge?" support tickets and disputes. [Envestnet | Yodlee used this pattern to improve merchant identification](https://brandfetch.com/developers/customers/yodlee) across its network. ## Going further Request and response shape, including countryCode. The response is a full brand record: colors, socials, and company details. Create a free account and start building.