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:| Favicon | File | Size | Resolution |
|---|---|---|---|
x.com/favicon.ico | PNG | 549 B | 32×32 |
apple.com/favicon.ico | ICO | 22 KB | 64×64 |
cloudflare.com/favicon.ico | PNG | 908 B | 99×96 |
adobe.com/favicon.ico | ICO | 15 KB | 48×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.Mailbox providers already publish the logo
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:
| Domain | Favicon | BIMI | Size | Title |
|---|---|---|---|---|
| x.com | 520 B | X Corp. | ||
| apple.com | 1.1 KB | Apple | ||
| cloudflare.com | 1.4 KB | Cloudflare Inc. | ||
| adobe.com | 474 B | Adobe: 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:| Set | Publishes a logo |
|---|---|
| Top 100 | 19 / 100 (19%) |
| Top 500 | 97 / 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&metacURL 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.bodyPHP 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))
}import createClient from 'microlink.io'
const microlink = createClient()
const data = await microlink.metadata('https://www.cloudflare.com')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=BIMI1is 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.