@unavatar/core 3.25.6 → 3.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -9
- package/package.json +2 -2
- package/src/providers/index.js +2 -0
- package/src/providers/thingiverse.js +16 -0
package/README.md
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
- [Introduction](#introduction)
|
|
6
6
|
- [Quick start](#quick-start)
|
|
7
|
+
- [Attribution](#attribution)
|
|
8
|
+
- [How to add attribution](#how-to-add-attribution)
|
|
9
|
+
- [Remove attribution](#remove-attribution)
|
|
7
10
|
- [Authentication](#authentication)
|
|
8
11
|
- [Pricing](#pricing)
|
|
9
12
|
- [Cache](#cache)
|
|
@@ -62,29 +65,95 @@
|
|
|
62
65
|
- [Response Format](#response-format)
|
|
63
66
|
- [Response Headers](#response-headers)
|
|
64
67
|
- [Response Errors](#response-errors)
|
|
68
|
+
- [Contact](#contact)
|
|
65
69
|
|
|
66
70
|
---
|
|
67
71
|
|
|
72
|
+
Last updated on April 29, 2026
|
|
73
|
+
|
|
68
74
|
## Introduction
|
|
69
75
|
|
|
70
76
|
Welcome to **unavatar.io**, the ultimate avatar service that offers everything you need to easily retrieve user avatars:
|
|
71
77
|
|
|
78
|
+
- **Versatile**: A wide range of platforms and services including [TikTok](https://unavatar.io/docs#tiktok), [Instagram](https://unavatar.io/docs#instagram), [YouTube](https://unavatar.io/docs#youtube), [X/Twitter](https://unavatar.io/docs#xtwitter), [Gravatar](https://unavatar.io/docs#gravatar), etc., meaning you can rule all of them just querying against unavatar.
|
|
79
|
+
|
|
80
|
+
- **Speed**: Designed to be fast and efficient with a 91% cache hit rate, serving 12.5 TB of data across 382M requests.
|
|
81
|
+
|
|
82
|
+
- **Optimize**: All the images are not only compressed on-the-fly to reduce their size and save bandwidth, but also optimized to maintain a high-quality ratio. They are ready for immediate use, enhancing the overall optimization of your website or application.
|
|
83
|
+
|
|
84
|
+
- **Integration**: The service seamlessly incorporates into your current applications or websites with ease. We offer straightforward documentation and comprehensive support to ensure a quick and effortless onboarding experience.
|
|
85
|
+
|
|
72
86
|
It's proudly powered by [microlink.io](https://microlink.io/), the headless browser API that handles all the heavy lifting behind the scenes to ensure your avatars are always ready.
|
|
73
87
|
|
|
74
88
|
## Quick start
|
|
75
89
|
|
|
76
|
-
The service is exposed in **unavatar.io** via
|
|
90
|
+
The service is exposed in **unavatar.io** via endpoints.
|
|
77
91
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
An endpoint determines how the avatar is looked up and what parameters are required.
|
|
93
|
+
|
|
94
|
+
For example, you can get an avatar for:
|
|
95
|
+
|
|
96
|
+
- an **email**: [unavatar.io/email/hello@microlink.io](https://unavatar.io/email/hello@microlink.io)
|
|
82
97
|
- an **username**: [unavatar.io/github/kikobeats](https://unavatar.io/github/kikobeats)
|
|
83
|
-
- a **domain**: [unavatar.io/
|
|
98
|
+
- a **domain**: [unavatar.io/domain/reddit.com](https://unavatar.io/domain/reddit.com)
|
|
99
|
+
|
|
100
|
+
Read [providers](https://unavatar.io/docs#providers) to know more. Each provider can accept different parameters.
|
|
101
|
+
|
|
102
|
+
## Attribution
|
|
103
|
+
|
|
104
|
+
Free plans require attribution. Upgrade to any paid plan to remove this requirement.
|
|
105
|
+
|
|
106
|
+
Attribution ensures proper domain verification and helps us keep unavatar.io free for the community.
|
|
107
|
+
|
|
108
|
+
Your attribution link:
|
|
109
|
+
|
|
110
|
+
- Must be on your production site (not staging or localhost).
|
|
111
|
+
- Must be publicly accessible and viewable in browsers.
|
|
112
|
+
- Must not use rel="nofollow", redirects, or obfuscation.
|
|
113
|
+
|
|
114
|
+
### How to add attribution
|
|
115
|
+
|
|
116
|
+
Add this link on any page or surface displaying unavatar.io avatars:
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
[Avatars provided by Unavatar](https://unavatar.io)
|
|
120
|
+
```
|
|
84
121
|
|
|
85
|
-
|
|
122
|
+
**Example**
|
|
86
123
|
|
|
87
|
-
|
|
124
|
+
```html
|
|
125
|
+
|
|
126
|
+

|
|
127
|
+
|
|
128
|
+

|
|
129
|
+
|
|
130
|
+
<p class="attribution">
|
|
131
|
+
|
|
132
|
+
[Avatars provided by Unavatar](https://unavatar.io)
|
|
133
|
+
|
|
134
|
+
</p>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Valid placements**
|
|
138
|
+
|
|
139
|
+
Site footer, about page, credits page, or any page that renders avatars.
|
|
140
|
+
|
|
141
|
+
**Mobile apps and non-web products**
|
|
142
|
+
|
|
143
|
+
If avatars are displayed in a mobile app, desktop app, browser extension, email, or any non-web surface, add the attribution link on your app's marketing site, app store listing description, or credits screen.
|
|
144
|
+
|
|
145
|
+
**Requirements for attribution to be valid**
|
|
146
|
+
|
|
147
|
+
We reserve the right to revoke free-tier access for any website or product that does not comply with the attribution requirements described in this document:
|
|
148
|
+
|
|
149
|
+
- Double-check the href. It must point to [https://unavatar.io](https://unavatar.io/) directly — no redirects, no URL shorteners, no tracking wrappers.
|
|
150
|
+
- Make sure it's crawlable. The link must be present in the rendered HTML and not blocked by robots.txt, authentication, or region gating.
|
|
151
|
+
- Avoid nofollow or noindex. We need a standard, followable link.
|
|
152
|
+
- target="\_blank" is allowed.
|
|
153
|
+
|
|
154
|
+
### Remove attribution
|
|
155
|
+
|
|
156
|
+
Attribution is only required on the free plan. [Upgrade to the PRO plan](https://unavatar.io/checkout) to remove the requirement.
|
|
88
157
|
|
|
89
158
|
## Authentication
|
|
90
159
|
|
|
@@ -98,9 +167,13 @@ curl "https://unavatar.io/github/kikobeats" -H "x-api-key: YOUR_API_KEY"
|
|
|
98
167
|
|
|
99
168
|
```javascript
|
|
100
169
|
await fetch('https://unavatar.io/github/kikobeats', {
|
|
170
|
+
|
|
101
171
|
headers: {
|
|
172
|
+
|
|
102
173
|
'x-api-key': 'YOUR_API_KEY'
|
|
174
|
+
|
|
103
175
|
}
|
|
176
|
+
|
|
104
177
|
})
|
|
105
178
|
```
|
|
106
179
|
|
|
@@ -108,8 +181,11 @@ await fetch('https://unavatar.io/github/kikobeats', {
|
|
|
108
181
|
import requests
|
|
109
182
|
|
|
110
183
|
response = requests.get(
|
|
184
|
+
|
|
111
185
|
'https://unavatar.io/github/kikobeats',
|
|
186
|
+
|
|
112
187
|
headers={'x-api-key': 'YOUR_API_KEY'}
|
|
188
|
+
|
|
113
189
|
)
|
|
114
190
|
```
|
|
115
191
|
|
|
@@ -119,24 +195,33 @@ package main
|
|
|
119
195
|
import "net/http"
|
|
120
196
|
|
|
121
197
|
func main() {
|
|
198
|
+
|
|
122
199
|
req, _ := http.NewRequest("GET", "https://unavatar.io/github/kikobeats", nil)
|
|
200
|
+
|
|
123
201
|
req.Header.Set("x-api-key", "YOUR_API_KEY")
|
|
124
202
|
|
|
125
203
|
resp, _ := http.DefaultClient.Do(req)
|
|
204
|
+
|
|
126
205
|
defer resp.Body.Close()
|
|
206
|
+
|
|
127
207
|
}
|
|
128
208
|
```
|
|
129
209
|
|
|
130
210
|
```ruby
|
|
131
211
|
require 'net/http'
|
|
212
|
+
|
|
132
213
|
require 'uri'
|
|
133
214
|
|
|
134
215
|
uri = URI('https://unavatar.io/github/kikobeats')
|
|
216
|
+
|
|
135
217
|
request = Net::HTTP::Get.new(uri)
|
|
218
|
+
|
|
136
219
|
request['x-api-key'] = 'YOUR_API_KEY'
|
|
137
220
|
|
|
138
221
|
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
|
222
|
+
|
|
139
223
|
http.request(request)
|
|
224
|
+
|
|
140
225
|
end
|
|
141
226
|
```
|
|
142
227
|
|
|
@@ -144,11 +229,15 @@ end
|
|
|
144
229
|
$ch = curl_init('https://unavatar.io/github/kikobeats');
|
|
145
230
|
|
|
146
231
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
232
|
+
|
|
147
233
|
'x-api-key: YOUR_API_KEY',
|
|
234
|
+
|
|
148
235
|
]);
|
|
236
|
+
|
|
149
237
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
150
238
|
|
|
151
239
|
$response = curl_exec($ch);
|
|
240
|
+
|
|
152
241
|
curl_close($ch);
|
|
153
242
|
```
|
|
154
243
|
|
|
@@ -166,7 +255,9 @@ Rate limit status can be verified using these response headers:
|
|
|
166
255
|
$ curl -I https://unavatar.io/github/kikobeats
|
|
167
256
|
|
|
168
257
|
x-rate-limit-limit: 25
|
|
258
|
+
|
|
169
259
|
x-rate-limit-remaining: 24
|
|
260
|
+
|
|
170
261
|
x-rate-limit-reset: 1744243200
|
|
171
262
|
```
|
|
172
263
|
|
|
@@ -196,7 +287,9 @@ The proxy tier used is returned in the `x-proxy-tier` response header, and the t
|
|
|
196
287
|
$ curl -I -H "x-api-key: YOUR_API_KEY" https://unavatar.io/instagram/kikobeats
|
|
197
288
|
|
|
198
289
|
x-pricing-tier: pro
|
|
290
|
+
|
|
199
291
|
x-proxy-tier: origin
|
|
292
|
+
|
|
200
293
|
x-unavatar-cost: 1
|
|
201
294
|
```
|
|
202
295
|
|
|
@@ -230,6 +323,7 @@ To check the cache status in real requests, inspect these response headers:
|
|
|
230
323
|
$ curl -I -H "x-api-key: YOUR_API_KEY" "https://unavatar.io/github/kikobeats?ttl=1h"
|
|
231
324
|
|
|
232
325
|
cache-control: public, max-age=3600
|
|
326
|
+
|
|
233
327
|
x-cache-status: HIT
|
|
234
328
|
```
|
|
235
329
|
|
|
@@ -469,6 +563,10 @@ Available inputs:
|
|
|
469
563
|
- SHA-256 hash, e.g., [unavatar.io/gravatar/b1f507c7a29adfa84eaa521036774b0577c58f23f2f3f42e068d6ac256cffae2](https://unavatar.io/gravatar/b1f507c7a29adfa84eaa521036774b0577c58f23f2f3f42e068d6ac256cffae2)
|
|
470
564
|
- MD5 hash, e.g., [unavatar.io/gravatar/3f293df98a473eae038deabe430a1e30](https://unavatar.io/gravatar/3f293df98a473eae038deabe430a1e30)
|
|
471
565
|
|
|
566
|
+
When you pass an email address directly in the URL, it is visible in plain text — both in server logs and to any intermediary that inspects the request.
|
|
567
|
+
|
|
568
|
+
To avoid this, pass a pre-computed `MD5` or `SHA256` hash of the email instead. Unavatar detects the hash automatically and routes it to Gravatar, which natively supports both hash formats.
|
|
569
|
+
|
|
472
570
|
### Instagram
|
|
473
571
|
|
|
474
572
|
Get any Instagram user's profile picture by their username. No authentication or API tokens needed — just pass the username.
|
|
@@ -725,11 +823,17 @@ These headers help you understand pricing, limits, and request diagnostics.
|
|
|
725
823
|
$ curl -I -H "x-api-key: YOUR_API_KEY" https://unavatar.io/github/kikobeats
|
|
726
824
|
|
|
727
825
|
x-pricing-tier: pro
|
|
826
|
+
|
|
728
827
|
x-timestamp: 1744209600
|
|
828
|
+
|
|
729
829
|
x-unavatar-cost: 1
|
|
830
|
+
|
|
730
831
|
x-proxy-tier: origin
|
|
832
|
+
|
|
731
833
|
x-rate-limit-limit: 50
|
|
834
|
+
|
|
732
835
|
x-rate-limit-remaining: 49
|
|
836
|
+
|
|
733
837
|
x-rate-limit-reset: 1744243200
|
|
734
838
|
```
|
|
735
839
|
|
|
@@ -770,4 +874,4 @@ Expected errors are known operational cases returned with stable codes.
|
|
|
770
874
|
|
|
771
875
|
## Contact
|
|
772
876
|
|
|
773
|
-
If you have
|
|
877
|
+
If you have a suggestion or need to report a bug, contact us at <hello@unavatar.io>.
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@unavatar/core",
|
|
3
3
|
"description": "Get unified user avatar from social networks, including Instagram, SoundCloud, Telegram, Twitter, YouTube & more.",
|
|
4
4
|
"homepage": "https://unavatar.io",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.26.0",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./src/index.js",
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
"devDependencies": {
|
|
158
158
|
"@commitlint/cli": "latest",
|
|
159
159
|
"@commitlint/config-conventional": "latest",
|
|
160
|
-
"ava": "
|
|
160
|
+
"ava": "7",
|
|
161
161
|
"c8": "latest",
|
|
162
162
|
"cheerio": "latest",
|
|
163
163
|
"ci-publish": "latest",
|
package/src/providers/index.js
CHANGED
|
@@ -35,6 +35,7 @@ const providersBy = {
|
|
|
35
35
|
'steam',
|
|
36
36
|
'substack',
|
|
37
37
|
'telegram',
|
|
38
|
+
'thingiverse',
|
|
38
39
|
'threads',
|
|
39
40
|
'tiktok',
|
|
40
41
|
'tumblr',
|
|
@@ -85,6 +86,7 @@ module.exports = ctx => {
|
|
|
85
86
|
steam: require('./steam')(ctx),
|
|
86
87
|
substack: require('./substack')(ctx),
|
|
87
88
|
telegram: require('./telegram')(ctx),
|
|
89
|
+
thingiverse: require('./thingiverse')(ctx),
|
|
88
90
|
threads: require('./threads')(ctx),
|
|
89
91
|
tiktok: require('./tiktok')(ctx),
|
|
90
92
|
tumblr: require('./tumblr')(ctx),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const getProfileUrl = input => `https://www.thingiverse.com/${input}`
|
|
4
|
+
|
|
5
|
+
const getAvatarUrl = ({ getOgImage, $ }) =>
|
|
6
|
+
new URL(getOgImage($)).searchParams.get('url')
|
|
7
|
+
|
|
8
|
+
module.exports = ({ createHtmlProvider, getOgImage }) =>
|
|
9
|
+
createHtmlProvider({
|
|
10
|
+
name: 'thingiverse',
|
|
11
|
+
url: getProfileUrl,
|
|
12
|
+
getter: $ => getAvatarUrl({ getOgImage, $ })
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
module.exports.getAvatarUrl = getProfileUrl
|
|
16
|
+
module.exports.getAvatarUrlFromMarkup = getAvatarUrl
|