Skip to content

Developers

Avatars for every user, from one image URL

Turn an email address into a picture without storing a single image. Hash the address, drop the link into an img tag, and Visage handles sizes, fallbacks and ratings.

The whole integration
<img src="https://your-visage-address/avatar/HASH?s=80&d=identicon" width="80" height="80" alt="">

1. Hash the email address

Trim any spaces around the address, lowercase it, then take its SHA-256 hash as 64 hexadecimal characters. The hash identifies the person without revealing the address. Older MD5 hashes are accepted too.

Browser
async function avatarUrl(email, size = 80) {
  const data = new TextEncoder().encode(email.trim().toLowerCase())
  const digest = await crypto.subtle.digest('SHA-256', data)
  const hash = Array.from(new Uint8Array(digest))
    .map(byte => byte.toString(16).padStart(2, '0'))
    .join('')

  return `https://your-visage-address/avatar/${hash}?s=${size}&d=identicon`
}

2. Request the image

Add the hash to the avatar address. When someone has linked a picture to that email, you get their picture. When they have not, you get the fallback you ask for.

Avatar address
https://your-visage-address/avatar/HASH
A 200 pixel robot fallback, G rated only
https://your-visage-address/avatar/HASH?s=200&d=robohash&r=g

Parameters

Every parameter is optional and has a short and a long name. You can also add a .jpg or .png to the hash if your platform expects a file extension.

ParameterValuesDefaultWhat it does
s or size1 to 204880Width and height of the image in pixels. Avatars are always square.
d or defaultmp, identicon, monsterid, wavatar, retro, robohash, initials, color, blank, 404, or an image URLVisage logoWhat to show when the hash has no avatar, or when the avatar is rated above r. A custom URL must be public, use http or https, end in an image extension and have no query string.
r or ratingg, pg, r, xgThe highest rating your site allows. Pictures rated above it are replaced by the fallback.
f or forcedefaultyoffAlways return the fallback, even when an avatar exists. Useful for testing styles.
nameAny textProfile nameUsed by the initials style. Without it, Visage uses the public display name when there is one.
initials1 to 3 charactersNoneExact initials for the initials style. Takes priority over name.

Fallback styles

Generated styles are drawn from the hash, so the same address always gets the same picture. They come back as crisp SVG images that scale to any size.

  • Mystery person exampleMystery person exampleMystery person example

    Mystery person

    d=mp

    A calm, neutral silhouette that looks the same for everyone.

  • Identicon exampleIdenticon exampleIdenticon example

    Identicon

    d=identicon

    A geometric quilt pattern unique to every email.

  • Monster exampleMonster exampleMonster example

    Monster

    d=monsterid

    A friendly little monster with its own colors, eyes and horns.

  • Wavatar exampleWavatar exampleWavatar example

    Wavatar

    d=wavatar

    A cartoon face with its own expression and color scheme.

  • Retro exampleRetro exampleRetro example

    Retro

    d=retro

    An 8-bit, arcade-style pixel pattern.

  • Robot exampleRobot exampleRobot example

    Robot

    d=robohash

    A robot assembled from heads, eyes, antennas and grills.

  • Initials exampleInitials exampleInitials example

    Initials

    d=initials

    Initials from a name, set on a color picked from the hash.

  • Color exampleColor exampleColor example

    Color

    d=color

    A single solid color picked from the hash.

  • Blank

    d=blank

    A fully transparent image.

URL builder

Try any address and options. The hash is computed right here in your browser, and the email never leaves this page.

SHA-256: hashing

160px
Highest rating allowed (r)

Handy for previewing styles for a real address.

Preparing preview

Image URL
https://your-visage-address
HTML
<img src="https://your-visage-address" width="160" height="160" alt="" loading="lazy">

Profile API

Read a public profile by email hash or username. Responses are JSON, can be called from any website, and never include the email address. Hidden profiles and unknown hashes return a 404.

Request
GET https://your-visage-address/api/profiles/{hash or username}
JavaScript
const response = await fetch(`https://your-visage-address/api/profiles/${hash}`)

if (response.ok) {
  const profile = await response.json()
  console.log(profile.display_name, profile.avatar_url)
}
Response
{
  "hash": "b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514",
  "username": "maya-torres",
  "display_name": "Maya Torres",
  "profile_url": "https://your-visage-address/maya-torres",
  "avatar_url": "https://your-visage-address/avatar/b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514",
  "avatar_alt_text": "Maya smiling in front of a white wall",
  "pronouns": "she/her",
  "job_title": "Product designer",
  "company": "Northwind Studio",
  "location": "Lisbon, Portugal",
  "description": "I design calm, accessible interfaces.",
  "links": [
    { "label": "Portfolio", "url": "https://example.com/maya" }
  ]
}

Caching and privacy

Five minute cache

Responses can be cached for five minutes, so a new picture reaches every site shortly after it is chosen.

Served from a CDN

Uploaded pictures are stored in sizes from 64 to 1024 pixels and delivered from a global CDN. The closest larger size is returned.

Hashes, never emails

Avatar and profile links only carry the hash. Pictures go live only after the owner confirms the address with a code.

See it with your own email

Create an avatar, then paste your hash into the builder above.

Create your avatar
Made with Modulify