Gravatar for Developers — How It Works, the API, and the Privacy Problem Nobody Talks About

Gravatar is one of those bits of web infrastructure that quietly powers millions of user interfaces. If you've built a commenting system, a user profile page, or any kind of developer platform, you've probably used it. The API is dead simple. But there's a privacy implication baked into the design that's worth understanding before you ship it.

The Mechanic: MD5 Hash + Base URL

The entire Gravatar system works on one elegant trick: MD5 hash the user's email address, append it to the Gravatar URL, get an avatar image back. No API key, no authentication, no setup.

// Email: user@example.com // MD5: b58996c504c5638798eb6b511e6f49af // URL: https://www.gravatar.com/avatar/b58996c504c5638798eb6b511e6f49af

Query parameters let you control the output:

https://www.gravatar.com/avatar/HASH?s=80&d=identicon&r=g

• s= — Size in pixels, 1 to 2048. Default 80. • d= — Fallback image when no Gravatar exists: 404, mp, identicon, monsterid, wavatar, retro, robohash, blank • r= — Rating filter: g, pg, r, x. Filters explicit avatars.

Implementation in Practice

Node.js

const crypto = require('crypto');function gravatarUrl(email, size = 80) { const hash = crypto .createHash('md5') .update(email.trim().toLowerCase()) .digest('hex'); return `https://www.gravatar.com/avatar/${hash}?s=${size}&d=identicon`; }

Two things that trip people up: forgetting to trim whitespace from the email, and not lowercasing it before hashing. A trailing space or a capital letter produces a completely different MD5 hash. The lookup fails silently — you just get the default image with no indication why.

Checking if a Gravatar Actually Exists

Use the ?d=404 parameter and check the HTTP status code:

async function hasGravatar(email) { const hash = md5(email.trim().toLowerCase()); const res = await fetch( `https://www.gravatar.com/avatar/${hash}?d=404`, { method: 'HEAD' } ); return res.status === 200; }

The Privacy Problem

Here's the thing that usually doesn't make it into the Gravatar tutorials.

The MD5 hash of an email address is a stable, unique identifier for that user — and it's the same hash on every single site that uses Gravatar. Stack Overflow, your app, a random WordPress blog — if they all use Gravatar, the same hash appears in all of them.

Anyone with a database mapping emails to MD5 hashes (easy to build from breach data, or by simply hashing known email lists) can cross-reference users across every platform they appear on. This is not theoretical — researchers have documented this tracking vector.

Mitigations that actually work: • Cache Gravatar images server-side and serve them from your own CDN — this prevents direct browser requests to Gravatar entirely • Let users upload a local avatar as an alternative • For high-privacy contexts, use a generated avatar library like DiceBear instead of Gravatar

Check if any email has a Gravatar registered — useful for user onboarding flows

Try Gravatar Checker Free →

FAQs

Almost always one of three things: email not lowercased before hashing, whitespace in the email, or the user hasn't registered that address at gravatar.com. Test by constructing the URL manually and opening it in a browser. Append &d=404 and check the HTTP status to distinguish between a hash error and a missing Gravatar.
Yes, heavily in WordPress-adjacent ecosystems. WordPress.com, Jetpack, BuddyPress, and most WordPress comment systems use it by default. Common in developer tools too. Less common in consumer apps where privacy expectations are higher.
Technically you can hash any string and query it, but only email addresses map to real user profiles. For non-email identifiers, use DiceBear or a similar library that generates deterministic avatars from arbitrary strings without the Gravatar dependency.
Scroll to Top
Checker Tools