Edit this page on GitHubLast updated on

Introduction

Welcome to unavatar.io, the ultimate avatar service that offers everything you need to easily retrieve user avatars:

It's proudly powered by microlink.io, the headless browser API that handles all the heavy lifting behind the scenes to ensure your avatars are always ready.

Quick start

The service is exposed in unavatar.io via provider endpoints:

Use the /:provider/:key format for all lookups. You can read more about available providers in providers.

Query parameters

TTL

Type: number or string
Default: '24h'
Range: from '1h' to '28d'

It determines the maximum quantity of time an avatar is considered fresh.

e.g., unavatar.io/github/kikobeats?ttl=1h

When you look up for a user avatar for the very first time, the service will determine it and cache it respecting TTL value.

The same resource will continue to be used until reach TTL expiration. After that, the resource will be computed, and cache as fresh, starting the cycle.

Fallback

Type: string or boolean

When it can't be possible to get a user avatar, a fallback image is returned instead, and it can be personalized to fit better with your website or application style.

You can get one from boringavatars.com:

e.g., unavatar.io/github/37t?fallback=https://source.boringavatars.com/marble/120/1337_user?colors=264653r,2a9d8f,e9c46a,f4a261,e76f51

or avatar.vercel.sh:

e.g., unavatar.io/github/37t?fallback=https://avatar.vercel.sh/37t?size=400

or a static image:

e.g., unavatar.io/github/37t?fallback=https://avatars.githubusercontent.com/u/66378906?v=4

or even a base64 encoded image. This allows you to return a transparent, base64 encoded 1x1 pixel GIF, which can be useful when you want to use your own background colour or image as a fallback.

e.g., unavatar.io/github/37t?fallback=data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

You can pass fallback=false to explicitly disable this behavior. In this case, a 404 Not Found HTTP status code will returned when is not possible to get the user avatar.

JSON

The service returns media content by default.

This is in this way to make easier consume the service from HTML markup.

In case you want to get a JSON payload as response, just pass json=true:

e.g., unavatar.io/github/kikobeats?json

Pricing

The service is FREE for everyone, no registration required, with a daily rate limit of 50 requests per IP address.

For preventing abusive usage, the service has associated a daily rate limit based on requests IP address.

You can verify for your rate limit state checking the following headers in the response:

For higher usage, the PRO plan is a usage-based plan billed monthly that removes rate limits and unlocks custom TTL.

Every request has a cost in tokens ($0.001 per token) based on the proxy tier needed to resolve the avatar:

Proxy tierTokensCost
Origin1$0.001
Datacenter+2$0.003
Residential+4$0.007

The proxy tier used is returned in the x-proxy-tier response header, and the total cost in the x-unavatar-cost header.

$ curl -I -H "x-api-key: YOUR_API_KEY" https://unavatar.io/instagram/kikobeats

x-pricing-tier: pro
x-proxy-tier: origin
x-unavatar-cost: 1

To upgrade, visit unavatar.io/checkout. After completing the payment, you'll receive an API key.

Providers

Apple Music

Get artwork for any Apple Music artist, album, or song. Search by name or look up directly by numeric Apple Music ID.

e.g., unavatar.io/apple-music/daft%20punk

The endpoint supports explicit type as part of the input.

If explicit type is not provided, it searches artist and song (in that order).

Available URI format inputs:

  • artist
    • by artist name: unavatar.io/apple-music/artist:daft%20punk
    • by numeric artist ID: unavatar.io/apple-music/artist:5468295
  • album
    • by album name: unavatar.io/apple-music/album:discovery
    • by album ID: unavatar.io/apple-music/album:78691923
  • song
    • by song name: unavatar.io/apple-music/song:harder%20better%20faster%20stronger
    • by song ID: unavatar.io/apple-music/song:697195787

Bluesky

Get any Bluesky user's profile picture by their handle. Domain-style handles are supported.

Available inputs:

  • User handle, e.g., unavatar.io/bluesky/pfrazee.com
  • Domain handle, e.g., unavatar.io/bluesky/bsky.app

DeviantArt

Get any DeviantArt user's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/deviantart/spyed

Dribbble

Get any Dribbble designer's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/dribbble/omidnikrah

DuckDuckGo

Get the favicon or logo for any domain via DuckDuckGo's icon service. Useful as a fallback when a domain doesn't expose its favicon directly.

Available inputs:

  • Domain, e.g., unavatar.io/duckduckgo/gummibeer.dev

GitHub

Get any GitHub user or organization's profile picture by their username.

Available inputs:

  • User, e.g., unavatar.io/github/mdo
  • Organization, e.g., unavatar.io/github/vercel

GitLab

Get any GitLab user or group's profile picture by their username.

Available inputs:

  • User, e.g., unavatar.io/gitlab/sytses
  • Group, e.g., unavatar.io/gitlab/inkscape

Google

Get the favicon or logo for any domain using Google's favicon service.

Available inputs:

  • Domain, e.g., unavatar.io/google/netflix.com

Gravatar

Get any user's avatar by their email address via Gravatar. The most widely used global avatar service — if your users have a Gravatar set up, this is the fastest way to retrieve it.

Available inputs:

Instagram

Get any Instagram user's profile picture by their username. No authentication or API tokens needed — just pass the username.

Available inputs:

  • Username, e.g., unavatar.io/instagram/willsmith

Extract the logo or representative image from any URL. The page is rendered and the best available image is selected — useful for getting brand logos from any website.

Available inputs:

  • Domain, e.g., unavatar.io/microlink/microlink.io

OnlyFans

Get any OnlyFans creator's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/onlyfans/amandaribas

OpenStreetMap

Get any OpenStreetMap contributor's profile picture. Accepts either a numeric user ID or a username.

Available inputs:

  • Numeric user ID, e.g., unavatar.io/openstreetmap/98672
  • Username, e.g., unavatar.io/openstreetmap/Terence%20Eden

Patreon

Get any Patreon creator's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/patreon/kikobeats

Reddit

Get any Reddit user's avatar by their username.

Available inputs:

  • Username, e.g., unavatar.io/reddit/kikobeats

SoundCloud

Get any SoundCloud artist's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/soundcloud/gorillaz

Spotify

Get artwork for any Spotify entity — users, artists, albums, playlists, shows, episodes, or tracks. Look up by username or Spotify ID.

e.g., unavatar.io/spotify/kikobeats

The endpoint supports explicit type as part of the input.

If explicit type is not provided, it defaults to user.

Available URI format inputs:

  • user: unavatar.io/spotify/kikobeats
  • artist: unavatar.io/spotify/artist:6sFIWsNpZYqbRiDnNOkZCA
  • playlist: unavatar.io/spotify/playlist:37i9dQZF1DXcBWIGoYBM5M
  • album: unavatar.io/spotify/album:4aawyAB9vmqN3uQ7FjRGTy
  • show: unavatar.io/spotify/show:6UCtBYL29hRg064d4i5W2i
  • episode: unavatar.io/spotify/episode:512ojhOuo1ktJprKbVcKyQ
  • track: unavatar.io/spotify/track:11dFghVXANMlKmJXsNCbNl

Substack

Get any Substack author's profile picture by their publication username.

Available inputs:

  • Publication username, e.g., unavatar.io/substack/bankless

Telegram

Get any Telegram user's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/telegram/drsdavidsoft

TikTok

Get any TikTok user's profile picture by their username. No authentication or API tokens needed — just pass the username.

Available inputs:

  • Username, e.g., unavatar.io/tiktok/carlosazaustre

Twitch

Get any Twitch streamer's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/twitch/midudev

Vimeo

Get any Vimeo user's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/vimeo/staff

WhatsApp

Get the profile picture for a WhatsApp phone number, channel, chat, or group.

The input supports a URI format type:id. When no type is provided, it defaults to phone.

Available URI format inputs:

  • phone (default): unavatar.io/whatsapp/34612345678
  • channel: unavatar.io/whatsapp/channel:0029VaABC1234abcDEF56789
  • chat: unavatar.io/whatsapp/chat:ABC1234DEFghi
  • group: unavatar.io/whatsapp/group:ABC1234DEFghi

X/Twitter

Get any X (formerly Twitter) user's profile picture by their username.

Available inputs:

  • Username, e.g., unavatar.io/x/kikobeats

YouTube

Get any YouTube channel's thumbnail by their handle, legacy username, or channel ID.

e.g., unavatar.io/youtube/casey

The endpoint supports specific input formats.

If the input starts with UC and has 24 characters, it is treated as a channel ID. Otherwise, it is treated as a handle.

Available inputs:

  • username: unavatar.io/youtube/casey or unavatar.io/youtube/@casey
  • channel: unavatar.io/youtube/UC_x5XG1OV2P6uZZ5FSM9Ttw

Response Format

A response is returning the user avatar by default.

However, you can get a json as response payload.

When an endpoint returns JSON, the shape is predictable so you can parse it reliably in your app:

FieldTypePresent inDescription
statusstringall JSON responsesOne of: success, fail, error.
messagestringall JSON responsesHuman-readable summary for display/logging.
dataobjectsuccessResponse payload for successful requests.
codestringfail, errorStable machine-readable error code.
morestring (URL)most fail/error responsesDocumentation URL with troubleshooting details.
reportstringsome error responsesSupport contact channel (for example mailto:).

Response Headers

These headers help you understand pricing, limits, and request diagnostics.

HeaderPurpose
x-pricing-tierfree or pro — the plan used for this request
x-timestampServer timestamp when request was received
x-unavatar-costToken cost of the request (avatar routes only)
x-proxy-tierProxy tier used: origin, datacenter, or residential
x-rate-limit-limitMaximum requests allowed per window (free tier only)
x-rate-limit-remainingRemaining requests in current window (free tier only)
x-rate-limit-resetUTC epoch seconds when window resets (free tier only)
retry-afterSeconds until rate limit resets (only on 429 responses)

Response Errors

Expected errors are known operational cases returned with stable codes.

HTTPCodeTypical trigger
400ESESSIONIDMissing session_id in /checkout/success
400ESESSIONCheckout session not paid or not found
400ESIGNATUREMissing stripe-signature header
400EWEBHOOKInvalid/failed Stripe webhook processing
400EAPIKEYVALUEMissing apiKey query parameter
400EAPIKEYLABELMissing label query parameter
401EEMAILInvalid or missing authenticated email
401EUSERUNAUTHORIZEDMissing/invalid auth for protected routes
401EAPIKEYInvalid x-api-key
403ETTLCustom ttl requested without pro plan
403EPROProvider restricted to pro plan
404ENOTFOUNDRoute not found
404EAPIKEYNOTFOUNDAPI key not found
409EAPIKEYEXISTSCustom API key already exists
409EAPIKEYLABELEXISTSAPI key label already exists
409EAPIKEYMINAttempt to remove last remaining key
429ERATEFree-tier daily rate limit exceeded
500ECHECKOUTStripe checkout session creation failed
500EAPIKEYFAILEDAPI key retrieval after checkout failed
500EINTERNALUnexpected internal server failure

Contact

If you have any suggestion or bug to report, please contact to ust mailing to [email protected].