unavatar-api
unavatar API
unavatar.io resolves user avatars from 25+ platforms via a single endpoint. Supports lookup by email, username, domain, or phone number.
Endpoint
https://unavatar.io
Quick Start
All lookups use the /:provider/:key format:
| Input | Pattern | Example |
|---|---|---|
/provider/user@example.com |
https://unavatar.io/gravatar/hello@microlink.io |
|
| username | /provider/username |
https://unavatar.io/github/kikobeats |
| domain | /provider/domain.com |
https://unavatar.io/google/reddit.com |
| phone | /provider/phonenumber |
https://unavatar.io/whatsapp/34612345678 |
Authentication
- Free: No auth required, 50 requests/day per IP
- Pro: Pass
x-api-keyheader, usage-based billing at $0.001/token
curl -H "x-api-key: YOUR_API_KEY" https://unavatar.io/instagram/kikobeats
Proxy Tiers & Token Cost
| Proxy tier | Tokens | Cost |
|---|---|---|
| Origin | 1 | $0.001 |
| Datacenter | +2 | $0.003 |
| Residential | +4 | $0.007 |
Response headers: x-proxy-tier, x-unavatar-cost, x-pricing-tier.
Key Management
- Usage:
curl -H "x-api-key: KEY" https://unavatar.io/key/usage - Rotate:
curl -H "x-api-key: KEY" https://unavatar.io/key/rotate
Query Parameters
ttl
- Type:
number|string - Default:
'24h' - Range:
'1h'to'28d'
Cache duration for the resolved avatar. The avatar is considered fresh until TTL expiration, then recomputed on next request.
e.g., https://unavatar.io/kikobeats?ttl=1h
fallback
- Type:
string|boolean
Custom fallback image when avatar can't be resolved. Accepts:
- URL to external avatar service (boringavatars.com, avatar.vercel.sh)
- URL to static image
- Base64 encoded image (e.g., transparent 1x1 pixel GIF)
falseto disable fallback (returns 404 instead)
https://unavatar.io/github/37t?fallback=https://avatar.vercel.sh/37t?size=400
https://unavatar.io/github/37t?fallback=false
https://unavatar.io/github/37t?fallback=data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==
json
- Type:
boolean
Returns JSON payload instead of image content.
e.g., https://unavatar.io/kikobeats?json
Response Format
When json=true is passed, responses follow a predictable shape:
| Field | Type | Present in | Description |
|---|---|---|---|
| status | string | all JSON responses | One of: success, fail, error. |
| message | string | all JSON responses | Human-readable summary for display/logging. |
| data | object | success | Response payload for successful requests. |
| code | string | fail, error | Stable machine-readable error code. |
| more | string (URL) | most fail/error responses | Documentation URL with troubleshooting details. |
| report | string | some error responses | Support contact channel (e.g., mailto:). |
Response Headers
| Header | Purpose |
|---|---|
| x-pricing-tier | free or pro — the plan used for this request |
| x-timestamp | Server timestamp when request was received |
| x-unavatar-cost | Token cost of the request (avatar routes only) |
| x-proxy-tier | Proxy tier used: origin, datacenter, or residential |
| x-rate-limit-limit | Maximum requests allowed per window (free tier only) |
| x-rate-limit-remaining | Remaining requests in current window (free tier only) |
| x-rate-limit-reset | UTC epoch seconds when window resets (free tier only) |
| retry-after | Seconds until rate limit resets (only on 429 responses) |
Response Errors
Client-side issues return status: "fail" (HTTP 4xx). Service-side issues return status: "error" (HTTP 5xx).
| HTTP | Code | Typical trigger |
|---|---|---|
| 400 | ESESSIONID | Missing session_id in /checkout/success |
| 400 | ESESSION | Checkout session not paid or not found |
| 400 | ESIGNATURE | Missing stripe-signature header |
| 400 | EWEBHOOK | Invalid/failed Stripe webhook processing |
| 400 | EAPIKEYVALUE | Missing apiKey query parameter |
| 400 | EAPIKEYLABEL | Missing label query parameter |
| 401 | EEMAIL | Invalid or missing authenticated email |
| 401 | EUSERUNAUTHORIZED | Missing/invalid auth for protected routes |
| 401 | EAPIKEY | Invalid x-api-key |
| 403 | ETTL | Custom ttl requested without pro plan |
| 403 | EPRO | Provider restricted to pro plan |
| 404 | ENOTFOUND | Route not found |
| 404 | EAPIKEYNOTFOUND | API key not found |
| 409 | EAPIKEYEXISTS | Custom API key already exists |
| 409 | EAPIKEYLABELEXISTS | API key label already exists |
| 409 | EAPIKEYMIN | Attempt to remove last remaining key |
| 429 | ERATE | Free-tier daily rate limit exceeded |
| 500 | ECHECKOUT | Stripe checkout session creation failed |
| 500 | EAPIKEYFAILED | API key retrieval after checkout failed |
| 500 | EINTERNAL | Unexpected internal server failure |
Providers
Providers are grouped by input type.
| Provider | username | domain | phone | |
|---|---|---|---|---|
| Apple Music | ✓ | |||
| Bluesky | ✓ | |||
| DeviantArt | ✓ | |||
| Dribbble | ✓ | |||
| DuckDuckGo | ✓ | |||
| GitHub | ✓ | |||
| GitLab | ✓ | |||
| ✓ | ||||
| Gravatar | ✓ | |||
| ✓ | ||||
| Microlink | ✓ | |||
| OnlyFans | ✓ | |||
| OpenStreetMap | ✓ | |||
| Patreon | ✓ | |||
| ✓ | ||||
| SoundCloud | ✓ | |||
| Spotify | ✓ | |||
| Substack | ✓ | |||
| Telegram | ✓ | |||
| TikTok | ✓ | |||
| Twitch | ✓ | |||
| Vimeo | ✓ | |||
| ✓ | ||||
| X/Twitter | ✓ | |||
| YouTube | ✓ |
URI Format Providers
Apple Music supports type:id format. Without explicit type, it searches artist then song:
- by name:
/apple-music/daft%20punk artist:/apple-music/artist:daft%20punkor/apple-music/artist:5468295album:/apple-music/album:discoveryor/apple-music/album:78691923song:/apple-music/song:harder%20better%20faster%20strongeror/apple-music/song:697195787
Spotify supports type:id format (default type: user):
user:/spotify/kikobeatsartist:/spotify/artist:6sFIWsNpZYqbRiDnNOkZCAplaylist:/spotify/playlist:37i9dQZF1DXcBWIGoYBM5Malbum:/spotify/album:4aawyAB9vmqN3uQ7FjRGTyshow:/spotify/show:6UCtBYL29hRg064d4i5W2iepisode:/spotify/episode:512ojhOuo1ktJprKbVcKyQtrack:/spotify/track:11dFghVXANMlKmJXsNCbNl
WhatsApp supports type:id format (default type: phone):
phone:/whatsapp/34612345678channel:/whatsapp/channel:0029VaABC1234abcDEF56789chat:/whatsapp/chat:ABC1234DEFghigroup:/whatsapp/group:ABC1234DEFghi
YouTube accepts handle, legacy username, or channel ID. Input starting with UC and 24 characters long is treated as a channel ID:
- handle:
/youtube/caseyor/youtube/@casey - channel ID:
/youtube/UC_x5XG1OV2P6uZZ5FSM9Ttw
For individual provider examples, see providers.md.
More from kikobeats/skills
k8s-hpa-cost-tuning
Tune Kubernetes HPA scale-up/down behavior, topology spread, and resource requests to reduce idle cluster capacity. Use when users need to audit cluster costs on a schedule, analyze post-incident scaling behavior, investigate why replicas or nodes do not scale down, or reduce over-reservation and wasted compute resources.
14optimo
Optimize and convert images and videos using format-specific compression pipelines on top of ImageMagick and FFmpeg. Use when users need to reduce image or video file sizes, batch-optimize a media directory, convert between formats (JPEG, PNG, WebP, AVIF, HEIC, JXL, MP4, WebM, MOV), resize media by percentage/dimensions/target file size, strip audio tracks from videos, or output optimized images as data URLs.
1html-get
Retrieve normalized, render-ready HTML from any URL using fetch or headless prerender. Use when users need to get rendered HTML from JavaScript-heavy pages, normalize relative URLs to absolute for downstream parsing, prepare HTML for metadata extraction pipelines, or choose between fast fetch and full browser rendering per URL.
1keyvhq
Build and operate key-value caching with @keyvhq/core and official storage adapters. Use when users need to add a cache layer to a Node.js module, store data with TTL expiration, choose between storage backends (in-memory, Redis, Mongo, MySQL, PostgreSQL, SQLite), implement cache-aside patterns with namespace isolation, or memoize function results.
1use-pnpm
Always use pnpm as the package manager. Use when installing, adding, or removing dependencies, running scripts, or any npm/yarn/pnpm command. Replaces npm and yarn with pnpm equivalents.
1browserless
Automate headless Chrome with a high-level Puppeteer wrapper for screenshots, PDFs, and content extraction. Use when users need to capture web page screenshots or PDFs programmatically, extract rendered HTML or text from JavaScript-heavy pages, check URL status codes, run Lighthouse audits, or build reliable headless browser automation pipelines.
1