Skip to content

Microlink now reads brand logos from DNS

Square vector logos for 97 of the top 500 sites

August 4, 2026

Microlink now resolves the logo property from a DNS TXT record, BIMI, before it looks at the page. That record is where brands publish the logo your mailbox shows next to an email, as a square SVG instead of a 32×32 favicon.
TL;DR
  • Brands publish their logo in DNS as a BIMI record, the standard behind the logo your mailbox shows next to an email.
  • Roughly one in five of the top 500 sites publish one (97 / 500). High precision, low recall, so it ships as an optional package, not a favicon replacement.
  • It ships as metascraper-logo-bimi, with the record logic split out as bimi-url.
HTML never standardized how a website exposes its primary logo. Most sites declare none, so extraction falls back to the favicon: a browser tab icon that is small, often simplified, and not necessarily the brand's official mark. The BIMI record has been sitting in DNS the whole time. It's always DNS.

HTML markup has no single logo field

Without one place to look, you probe a handful of optional markup conventions. metascraper does that for you: metascraper-logo walks og:logo, itemprop="logo", and the JSON-LD logo fields of brand, organization, place, product, service, and publisher, in this order:
// Resolve `logo` from HTML markup (metascraper-logo), first match wins.
logo: [
  toLogo($ => $('meta[property="og:logo"]').attr('content')),
  toLogo($ => $('meta[itemprop="logo"]').attr('content')),
  toLogo($ => $('img[itemprop="logo"]').attr('src')),
  toLogo($ => toLogoUrl($, 'brand.logo')),
  toLogo($ => toLogoUrl($, 'organization.logo')),
  toLogo($ => toLogoUrl($, 'place.logo')),
  toLogo($ => toLogoUrl($, 'product.logo')),
  toLogo($ => toLogoUrl($, 'service.logo')),
  toLogo($ => toLogoUrl($, 'publisher.logo')),
  toLogo($ => toLogoUrl($, 'logo.url')),
  toLogo($ => toLogoUrl($, 'logo'))
]
After every convention, many sites still expose no logo metadata. metascraper-logo-favicon covers the gap: almost every site serves a /favicon.ico, so it becomes the logo when markup is empty. Here is what that returns for four well-known domains:
FaviconFileSizeResolution
x.com/favicon.icoPNG549 B32×32
apple.com/favicon.icoICO22 KB64×64
cloudflare.com/favicon.icoPNG908 B99×96
adobe.com/favicon.icoICO15 KB48×48
Coverage is good, brand quality is poor. Favicons are designed for browser tabs, not metadata: x.com returns 32×32 pixels and cloudflare.com is not even square at 99×96.
The web never standardized logo discovery, but email did, through Gmail, Apple Mail, and the DNS record they read.
BIMI (Brand Indicators for Message Identification) lets a domain publish its official brand logo in DNS. Mail providers like Gmail and Apple Mail show it next to authenticated emails. One dig query returns it:
dig +short TXT default._bimi.microlink.io
"v=BIMI1; l=https://cdn.microlink.io/logo/logo.svg;"
That makes the default._bimi record a strong source of logo metadata:
  • DNS is fast. Resolving a TXT record is typically cheaper than downloading and parsing an HTML document, especially once the resolver is warm.
  • No HTML required. It still works when a page is JavaScript-rendered, rate-limited, or responds with a 403.
  • The logo is intentional. It's the same asset Gmail and Apple Mail use to represent the brand.
  • The format is constrained. BIMI requires a square SVG Tiny P/S image, which suits avatars far better than a favicon.

SVG Tiny P/S makes every logo safe and square

BIMI requires SVG Tiny P/S (Portable/Secure), a restricted SVG profile built for displaying brand logos inside email clients. Three constraints come with it:
  • No scripts: the SVG cannot run JavaScript, so mailbox clients can render it safely.
  • No external assets: no remote images, fonts, or stylesheets; the mark is self-contained.
  • Square by design: every logo fits a 1:1 aspect ratio, making it immediately usable as an avatar or application icon.
The same four domains from the favicon table, with each favicon next to its BIMI logo and the SVG size:
DomainFaviconBIMISizeTitle
x.comX faviconX Corp. BIMI logo520 BX Corp.
apple.comApple faviconApple BIMI logo1.1 KBApple
cloudflare.comCloudflare faviconCloudflare BIMI logo1.4 KBCloudflare Inc.
adobe.comAdobe faviconAdobe BIMI logo474 BAdobe: Creative, marketing…
Every BIMI logo is a vector of 1.4 KB or less. The Apple favicon alone is 22 KB.

One in five top sites publish a record

We ran dig TXT default._bimi.<domain> across the top 500 sites:
SetPublishes a logo
Top 10019 / 100 (19%)
Top 50097 / 500 (19%)
BIMI raises quality when present, but at 19% it cannot replace the existing discovery strategies. So it ships as its own package rather than folded into the favicon rule, and the order is the caller's choice:
const metascraper = require('metascraper')([
  require('metascraper-logo-bimi')(),
  require('metascraper-logo')(),
  require('metascraper-logo-favicon')()
])
With metascraper-logo-bimi first, the record wins whenever the domain publishes one, and the HTML and favicon rules stay unchanged for everyone else. On a warm resolver the lookup measured between 23 ms and 78 ms (median 52 ms). Results are memoized per domain, so that cost is typically paid once.

Try it on cloudflare.com

Run the request below. The logo field in the response is the BIMI SVG, not the favicon.

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://www.cloudflare.com' URL with 'meta' API parameter:

CLI Microlink API example

microlink https://www.cloudflare.com&meta

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://www.cloudflare.com" \
  -d "meta=true"

JavaScript Microlink API example

import createClient from 'microlink.io'

const microlink = createClient()

const data = await microlink.metadata('https://www.cloudflare.com')

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://www.cloudflare.com",
    "meta": "true"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://www.cloudflare.com",
  meta: "true"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://www.cloudflare.com",
    "meta" => "true"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "io"
)

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://www.cloudflare.com")
    q.Set("meta", "true")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
logo here comes from default._bimi.cloudflare.com, not from the page. The favicon path returns a 99×96 PNG for the same site.

Publish a BIMI record for your company

If you want metadata tools (and mailboxes) to pick up your real logo, publish it. Three pieces, in order:
1. Export the logo as SVG Tiny P/S. Start from your official brand mark, not a favicon. The export has to match the Portable/Secure profile covered above: square, no scripts, no linked assets, baseProfile="tiny-ps" on the root <svg>. A default Illustrator or Figma SVG usually fails that check, so convert and validate before you upload anything.
2. Host it over HTTPS. Serve the file as image/svg+xml. Stay on https through any redirects. Put the mark on a stable URL you control (or your CA's BIMI host if you buy a VMC).
3. Publish one TXT record at default._bimi.yourdomain.com:
dig +short TXT default._bimi.microlink.io
"v=BIMI1; l=https://cdn.microlink.io/logo/logo.svg;"
  • v=BIMI1 is the version.
  • l= is the HTTPS URL of the SVG.
  • a= is optional: a Verified Mark Certificate, if you want mailbox providers that require one (Gmail is the usual reason).
For inbox display you also need DMARC at enforcement (p=quarantine or p=reject). For metadata extraction, the DNS record alone is enough: that is the part metascraper-logo-bimi reads.

Join the community

All of these improvements or features are community driven: We listen to your feedback and act accordingly.
Whether you are building a product, an indie developer, or just interested in web technologies, come chat with us.