Note to self: Setting up BIMI for a personal domain
BIMI puts your logo in the sender avatar slot in supporting email clients. Setup looks simple — one DNS record, one SVG — but the SVG requirements will waste your afternoon if you go in blind.
Prerequisites you actually need
SPF, DKIM, and DMARC must all be passing, and DMARC must be at p=quarantine or p=reject. p=none does not count. Check all three before touching anything else.
dig TXT scott.seely.io # SPF record
dig TXT _dmarc.scott.seely.io # DMARC policy
If DMARC isn’t at quarantine or reject, stop here. BIMI won’t activate.
The SVG is the hard part
BIMI requires SVG Tiny PS (Portable/Secure), not regular SVG. Every SVG you’ve ever exported from Figma, Illustrator, or Inkscape will fail because those tools emit <defs> blocks, and <defs> is forbidden.
The forbidden list: <defs>, <clipPath>, clip-path attributes, <script>, <image>, <foreignObject>. Any of these and the validator rejects the file.
The <title> element is required and must be the first child of <svg>. This one trips everyone up. When you submit a file missing <title>, the validator returns an error like “Did not expect element path there.” It’s not complaining about path — it expected title first and everything after that point is wrong. The error message is genuinely misleading.
Minimal compliant structure:
<svg version="1.2" baseProfile="tiny-ps"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100">
<title>Your Brand Name</title>
<path d="..." fill="#000"/>
</svg>
Key attributes on the root element: version="1.2" and baseProfile="tiny-ps". Standard shape elements like <rect>, <circle>, and <polygon> are fine. <text> is technically allowed but unreliable — the receiving client renders with whatever font it has, which is probably not yours. Convert text to <path> data before submitting.
Converting an existing logo
If your source SVG has text or uses clip-path, you need to flatten it.
For text-to-path conversion, fonttools handles this well:
from fontTools.ttLib import TTFont
from fontTools.pens.svgPathPen import SVGPathPen
font = TTFont("/path/to/your-font.ttf")
glyph_set = font.getGlyphSet()
pen = SVGPathPen(glyph_set)
glyph_set["S"].draw(pen) # replace "S" with your glyph name
print(pen.getCommands())
That gives you the d attribute value for a <path> element. For clip-path shapes, compute the intersection geometry manually or use a tool like Inkscape’s “Path > Intersection” before stripping the resulting SVG clean of any <defs>.
Validate the final file at https://bimigroup.org/svg-conversion-tools-for-bimi/ before touching DNS.
The DNS record
default._bimi.scott.seely.io TXT "v=BIMI1; l=https://scott.seely.io/logo.svg; a="
l= points to the SVG served over HTTPS. The file must be accessible without redirects.
a= is for a Verified Mark Certificate (VMC). Leave it empty. For a personal domain you’re not getting a VMC.
VMC reality check
Gmail requires a VMC to show the logo. VMCs cost $1,000+/year and require a registered trademark. For a personal domain, that’s a non-starter.
Proton Mail, Apple Mail, and Yahoo Mail show the logo without a VMC. That’s enough. Most people reading your email use one of those or will eventually.
Skip the VMC. The a= field stays empty.
Timeline
DNS propagates in minutes to 48 hours. After that, each provider fetches the logo the first time it sees mail from your domain. Proton, Apple, and Yahoo typically show it within hours to a few days. Gmail with a VMC takes 1–4 weeks, which doesn’t apply here.
What breaks it later
Three things:
- DMARC policy drops back to
p=none - The SVG URL goes down or returns non-200
- VMC expires (not your problem without one)
Otherwise it’s set-and-forget.