/minecraft-api?username=Notch&type=all
application/json: java | bedrock | cached
Quick Start
Get UUID, skin, cape, and name history for any Minecraft player. One URL, JSON response. No sign-up.
Minecraft API
Send one HTTPS GET request with a username or gamertag. Ask for Java, Bedrock or both, then check which edition object is present before reading its identifiers and assets.
GET https://vrc.lol/minecraft-api?username=Notch&type=all
Accept: application/jsonGET + HTTPS
Use the profile endpoint for JSON data and the asset endpoints for ready-to-display PNG files.
https://vrc.lol
/minecraft-api?username=Notch&type=allapplication/json: java | bedrock | cached
/head?username=Notch&type=java&size=128image/png: 8-512 px
/skin?username=Notch&type=javaimage/png: Java | Bedrock
/cape?hash=HASHimage/png: cape
/minecraft-api?suggest=Notch&limit=25application/json: [{ username, types }]
/skin_body?username=Notch&type=java&size=160image/png: 40-200 px
Choose the identifier and edition explicitly when your application needs predictable results.
usernamename | gamertag | UUID | XUID
typeall | java | bedrock
suggestsearch text + limit 1-100
updatetrue · 3600s profile cooldown
These requests use the Minecraft-specific endpoint and require no API key.
const response = await fetch('https://vrc.lol/minecraft-api?username=jeb_&type=all');
const profile = await response.json();
console.log(profile.java?.uuid);import requests
profile = requests.get('https://vrc.lol/minecraft-api', params={'username': 'jeb_', 'type': 'all'}).json()
print(profile.get('java', {}).get('uuid'))curl -sS 'https://vrc.lol/minecraft-api?username=jeb_&type=all'{
"success": true,
"cached": true,
"java": { "username": "jeb_", "uuid": "...", "skin_url": "...", "cape_url": "..." },
"bedrock": { "username": "...", "xuid_decimal": "...", "floodgate_uuid": "..." }
}java | bedrock: optional object; fields may be null
200 OKapplication/json | image/png
400 Bad Requestcode: MISSING_PARAMETER | INVALID_INPUT_FORMAT | INVALID_TYPE_FILTER
404 Not Foundcode: CACHE_PROFILE_NOT_FOUND | TEXTURE_NOT_FOUND | CAPE_NOT_FOUND
429 Too Many RequestsRetry-After
500 Internal Server Error{ "success": false, "error": "..." }
limit: ~180 / 60s / IPuncached_limit: 45 / 60s / IPupdate_cooldown: 3600s / profileHTTP 429 + Retry-AfterREQUEST CONTRACT
All public URLs use HTTPS. Profile lookups return JSON; texture endpoints return PNG on success. You do not need an account or API key.
| Parameter | Accepted values | How to use it |
|---|---|---|
username | Java name, Bedrock gamertag, Java UUID, Bedrock XUID | Required for profile lookup. URL-encode spaces and other characters in gamertags. UUIDs may be dashed or compact; keep XUIDs as strings to preserve their digits. |
type | all (default), java, bedrock | Choose the edition explicitly when names could refer to different people. Read the corresponding edition object instead of assuming both exist. |
suggest | 2–16 characters: letters, digits, underscore | Search cached usernames by prefix. The response is an array, including an empty array when there are no matches. This is not a full scan of all Minecraft accounts. |
limit | 1–100; default 10 | Maximum suggestion results. Values outside the range are clamped. |
update | true | Requests a fresh profile lookup and is subject to an hour-long profile cooldown. Use ordinary cached requests for routine page loads; do not refresh on every render. |
size | Head: 8–512; skin body: 40–200 | Pixel size for rendered images. Original skin and cape downloads retain their source dimensions. |
hash / view | Cape texture hash / optional front | /cape?hash=HASH returns the atlas. Add view=front for a 100×160 front-face thumbnail. |
RESPONSE CONTRACT
These are the principal profile fields. An unavailable edition may be omitted, and optional values can be null. The response timestamp is the time the response was built; it is not proof that every upstream field was refreshed then.
| Field | Type | Meaning |
|---|---|---|
success, status | boolean, integer | Application success and HTTP status. Check the actual HTTP status as well. |
cached | boolean | The profile was served from cached records. Cached data can be older than the player's current appearance. |
java.uuid, java.uuid_formatted | string or null | Compact and dashed Java account identifiers. Prefer a stable identifier over a mutable username. |
bedrock.xuid_decimal, bedrock.xuid_hex | string or null | Decimal and hexadecimal Bedrock identifiers. Never convert an XUID into a JavaScript Number. |
bedrock.floodgate_uuid | string or null | Floodgate-style identifier for Bedrock integration; it is distinct from a Java account UUID. |
skin_url, cape_url | string or null | Texture URLs inside an edition object. Resolve relative paths against https://vrc.lol. A missing cape is normal. |
skin_is_default, is_slim | boolean | Default-skin indication and slim-arm model flag. Use the correct arm model in your renderer. |
java.name_history | array | Recorded history from cached data; do not assume it is a complete Mojang name-history record. |
bedrock.is_linked, bedrock.linked_java_uuid | boolean, string or null | Cached linking information when available. Matching display names alone do not prove the accounts are linked. |
WORKING PATTERN
This browser example performs one cached lookup. It reports failures and returns a resolved image URL only when the edition provides one.
async function lookupPlayer(identifier, edition = 'java') {
const url = new URL('/minecraft-api', 'https://vrc.lol');
url.search = new URLSearchParams({ username: identifier, type: edition });
const response = await fetch(url, { headers: { Accept: 'application/json' } });
const data = await response.json();
if (!response.ok || !data.success) {
const retryAfter = response.headers.get('Retry-After');
throw new Error([data.code || response.status, data.error,
retryAfter ? 'Retry after ' + retryAfter + ' seconds' : ''].filter(Boolean).join(': '));
}
const player = data[edition];
if (!player) return null;
return {
player,
skinURL: player.skin_url ? new URL(player.skin_url, url.origin).href : null,
capeURL: player.cape_url ? new URL(player.cape_url, url.origin).href : null
};
}client := &http.Client{Timeout: 10 * time.Second}
endpoint := "https://vrc.lol/minecraft-api?" + url.Values{
"username": {"Notch"}, "type": {"java"},
}.Encode()
response, err := client.Get(endpoint)
if err != nil { return err }
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return fmt.Errorf("lookup HTTP %d; retry-after=%s",
response.StatusCode, response.Header.Get("Retry-After"))
}
var profile struct {
Success bool `json:"success"`
Java *struct { UUID string `json:"uuid"` } `json:"java"`
}
if err := json.NewDecoder(response.Body).Decode(&profile); err != nil { return err }
if !profile.Success || profile.Java == nil { return fmt.Errorf("Java profile unavailable") }The Go snippet belongs inside a function returning an error and uses net/http, net/url, time, fmt and encoding/json.
Error responses contain success: false, status, a readable error, and a machine-readable code. Optional usage explains a valid request.
{
"success": false,
"status": 400,
"code": "MISSING_PARAMETER",
"error": "Missing required parameter: username"
}MISSING_PARAMETER, INVALID_INPUT_FORMAT, INVALID_TYPE_FILTER, INVALID_CAPE_HASH and INVALID_CAPE_VIEW.CACHE_PROFILE_NOT_FOUND, TEXTURE_NOT_FOUND, CAPE_NOT_FOUND. Do not retry in a tight loop.Retry-After. RATE_LIMITED, MISS_RATE_LIMITED and UPDATE_COOLDOWN describe different limits.Retry-After when present.No. The public Minecraft lookup and image endpoints are accessible without an account or API key. They are rate limited, so cache successful responses and avoid polling the same player repeatedly.
Use https://vrc.lol as the base URL with /minecraft-api, /head, /skin, and /cape.
Yes. Pass the identifier in username and choose type=java or type=bedrock. Java UUIDs can be compact or dashed. Keep decimal and hexadecimal XUIDs as strings; JavaScript numbers cannot safely represent every XUID.
The response only includes available profiles for the selected edition. A name can exist in one edition without a cached match in the other. Check the selected edition object before accessing uuid, xuid_decimal or skin_url.
No. Image URLs can be paths such as /skin?username=Notch&type=java. Resolve them against https://vrc.lol, for example with new URL(player.skin_url, 'https://vrc.lol').href.
Cached means the record was served from the local profile cache, so appearance or linking details may be older than the current account state. Use update=true only when you need a refresh. Profile refreshes have an hour-long cooldown and can fail when edition services are unavailable.
Check HTTP 429 and wait for Retry-After before another request. The standard profile limit is 180 requests per minute per IP and the uncached lookup budget is 45 per minute. Limits can be configured; read the returned headers instead of hardcoding an exact remaining budget.
The public API supports cross-origin requests. Use fetch with HTTPS, check response.ok and success, and handle missing optional fields. Keep image and JSON requests separate: a failed PNG endpoint may return a JSON error instead of image bytes.
No. Suggestions search cached usernames by prefix. Pass 2–16 letters, digits or underscores, and optionally limit=1 through 100. The response is an array of username and types records; no matches is an empty array.
/minecraft-api | /head
fetch() | application/json
permissions.json | cache
VRC.LOL · Discord
Ask for help, share feedback, and meet the VRC.LOL community.