Quick Start

Minecraft Profile API

Get UUID, skin, cape, and name history for any Minecraft player. One URL, JSON response. No sign-up.

Minecraft API

Make your first profile request

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/json
JSONJava + BedrockCache statusNo API key

GET + HTTPS

All Endpoints

Use the profile endpoint for JSON data and the asset endpoints for ready-to-display PNG files.

https://vrc.lol

GET

/minecraft-api?username=Notch&type=all

application/json: java | bedrock | cached

GET

/head?username=Notch&type=java&size=128

image/png: 8-512 px

GET

/skin?username=Notch&type=java

image/png: Java | Bedrock

GET

/cape?hash=HASH

image/png: cape

GET

/minecraft-api?suggest=Notch&limit=25

application/json: [{ username, types }]

GET

/skin_body?username=Notch&type=java&size=160

image/png: 40-200 px

Request options

Choose the identifier and edition explicitly when your application needs predictable results.

username

name | gamertag | UUID | XUID

type

all | java | bedrock

suggest

search text + limit 1-100

update

true · 3600s profile cooldown

Code Examples

These requests use the Minecraft-specific endpoint and require no API key.

JavaScript

const response = await fetch('https://vrc.lol/minecraft-api?username=jeb_&type=all');
const profile = await response.json();
console.log(profile.java?.uuid);

Python

import requests
profile = requests.get('https://vrc.lol/minecraft-api', params={'username': 'jeb_', 'type': 'all'}).json()
print(profile.get('java', {}).get('uuid'))

cURL

curl -sS 'https://vrc.lol/minecraft-api?username=jeb_&type=all'

Response Format

{
  "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

HTTP Status Codes & Common Errors

200 OK

application/json | image/png

400 Bad Request

code: MISSING_PARAMETER | INVALID_INPUT_FORMAT | INVALID_TYPE_FILTER

404 Not Found

code: CACHE_PROFILE_NOT_FOUND | TEXTURE_NOT_FOUND | CAPE_NOT_FOUND

429 Too Many Requests

Retry-After

500 Internal Server Error

{ "success": false, "error": "..." }

Rate Limiting

REQUEST CONTRACT

Choose an identifier and edition

All public URLs use HTTPS. Profile lookups return JSON; texture endpoints return PNG on success. You do not need an account or API key.

ParameterAccepted valuesHow to use it
usernameJava name, Bedrock gamertag, Java UUID, Bedrock XUIDRequired 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.
typeall (default), java, bedrockChoose the edition explicitly when names could refer to different people. Read the corresponding edition object instead of assuming both exist.
suggest2–16 characters: letters, digits, underscoreSearch 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.
limit1–100; default 10Maximum suggestion results. Values outside the range are clamped.
updatetrueRequests 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.
sizeHead: 8–512; skin body: 40–200Pixel size for rendered images. Original skin and cape downloads retain their source dimensions.
hash / viewCape texture hash / optional front/cape?hash=HASH returns the atlas. Add view=front for a 100×160 front-face thumbnail.

RESPONSE CONTRACT

Read the fields safely

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.

FieldTypeMeaning
success, statusboolean, integerApplication success and HTTP status. Check the actual HTTP status as well.
cachedbooleanThe profile was served from cached records. Cached data can be older than the player's current appearance.
java.uuid, java.uuid_formattedstring or nullCompact and dashed Java account identifiers. Prefer a stable identifier over a mutable username.
bedrock.xuid_decimal, bedrock.xuid_hexstring or nullDecimal and hexadecimal Bedrock identifiers. Never convert an XUID into a JavaScript Number.
bedrock.floodgate_uuidstring or nullFloodgate-style identifier for Bedrock integration; it is distinct from a Java account UUID.
skin_url, cape_urlstring or nullTexture URLs inside an edition object. Resolve relative paths against https://vrc.lol. A missing cape is normal.
skin_is_default, is_slimbooleanDefault-skin indication and slim-arm model flag. Use the correct arm model in your renderer.
java.name_historyarrayRecorded history from cached data; do not assume it is a complete Mojang name-history record.
bedrock.is_linked, bedrock.linked_java_uuidboolean, string or nullCached linking information when available. Matching display names alone do not prove the accounts are linked.

WORKING PATTERN

Handle errors, missing editions and relative URLs

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
  };
}

Go client: bound the request time

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.

Errors and retry behaviour

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"
}

Build a reliable integration

  1. URL-encode identifiers and specify the edition.
  2. Check HTTP status, JSON success and the selected edition before reading fields.
  3. Store UUIDs and XUIDs as strings; resolve relative image URLs.
  4. Cache successful responses and textures. Use the response cache headers rather than a fixed refresh loop.
  5. Respect rate-limit headers and Retry-After. The standard profile budget is 180 requests per minute per IP, with a separate 45 uncached lookups per minute budget; these limits can be configured.
  6. Keep account permissions separate from public appearance data. A texture, cached owner list or matching name is not authentication.

Frequently Asked Questions

Does the API require an account or API key?

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.

What is the base URL?

Use https://vrc.lol as the base URL with /minecraft-api, /head, /skin, and /cape.

Can I look up a Java UUID or a Bedrock XUID?

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.

Why is the Java or Bedrock object missing?

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.

Are returned texture URLs always absolute?

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.

What does cached mean, and when should I use update=true?

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.

How should I handle rate limits?

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.

Can I use the API from a browser?

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.

Does the suggestion endpoint return all Minecraft players?

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.

Use Cases

Discord

/minecraft-api | /head

CORS + JSON

fetch() | application/json

UUID + XUID

permissions.json | cache

Next Steps

VRC.LOL · Discord

Join our Discord

Ask for help, share feedback, and meet the VRC.LOL community.

Join our Discord