API Reference
A small HTTP API for rendering Minecraft skins and browsing public scene templates. Everything returns either an image or JSON — no SDK, no auth, no client library required.
Base URL: https://minecraftrender.com
Authentication: none. All public endpoints are open. Rate limits apply per IP (see Rate limits).
Supported players: Java (usernames, UUIDs) and Bedrock (gamertags, XUIDs). Bedrock Persona / Character Creator characters render with their real geometry, not as a classic skin.
Conventions
Response formats
Render endpoints return binary image data. Everything else returns JSON. Image format is controlled by the ?format= query parameter:
webp(default) — smaller files, modern browsers.png— lossless, widest compatibility. Both formats preserve the transparent background.
Useful headers on render responses
| Header | Values | Meaning |
|---|---|---|
X-Cache | HIT / MISS | Whether the response came from the render cache. |
X-Template | 6-char shortcode | Which template produced the render (template endpoint only). |
Cache-Control | public, max-age=3600 | Safe for CDN / browser caching for an hour. |
Retry-After | seconds | Sent with 503 when the render pipeline is full. |
CORS
CORS headers are not currently sent, so direct fetches from other origins via fetch() or XMLHttpRequest will be blocked by the browser. <img src="...">, background-image, server-side requests, Discord embeds, and similar non-CORS-bound contexts work fine — which covers nearly every real use case. If you need JSON endpoints from a browser on another origin, proxy them server-side.
Error shape
All error responses are JSON with an error string:
{ "error": "Player 'NotARealName' not found" }
Render a template
GET /api/render/:gamertags/:shortcode
Renders the gallery template identified by shortcode, filling the template's player slots with the players you supply. This is the main integration endpoint.
Path parameters
| Param | Required | Notes |
|---|---|---|
gamertags | Yes | Comma-separated list. Number must match the template's playerCount. See Player identifiers. |
shortcode | Yes | 6 lowercase alphanumeric characters ([a-z0-9]{6}). |
Query parameters
| Param | Default | Values |
|---|---|---|
format | webp | webp or png |
Response
A binary image. Content-Type is image/webp or image/png depending on the format.
Example
GET https://minecraftrender.com/api/render/Dinnerbone/abc123
GET https://minecraftrender.com/api/render/Dinnerbone,.MyGen/xyz789?format=png
Resolution
Public renders are locked to 720p. If the template was saved at 1080p in the Studio, the scale is stripped before rendering — the 1080p option is Studio-only, to keep public render costs predictable.
Errors
| Status | When |
|---|---|
400 | Shortcode malformed, or the number of gamertags doesn't match the template's playerCount. |
404 | Template not found, or one of the players couldn't be resolved. |
429 | Rate-limited (60/min/IP). |
503 | Render pipeline is full. Retry after the Retry-After interval. |
List templates
GET /api/templates
Paginated list of gallery-published templates.
Query parameters
| Param | Default | Notes |
|---|---|---|
limit | 20 | 1–100. |
offset | 0 | For pagination. |
sort | newest | newest or popular. |
tag | — | Filter to templates with this tag. |
Response
{
"total": 142,
"templates": [
{
"shortcode": "abc123",
"name": "Hero pose",
"description": "Classic heroic stance with a sword.",
"tags": ["hero", "sword"],
"playerCount": 1,
"createdAt": "2026-03-14T09:22:11.000Z",
"renders": 1287
}
]
}
Cached for 60 seconds at the edge (Cache-Control: public, max-age=60).
Template metadata
GET /api/templates/:shortcode
Returns the public metadata for a single template. The underlying pose data isn't exposed.
Response
{
"shortcode": "abc123",
"name": "Hero pose",
"description": "Classic heroic stance with a sword.",
"tags": ["hero", "sword"],
"playerCount": 1,
"createdAt": "2026-03-14T09:22:11.000Z",
"renders": 1287
}
Errors
| Status | When |
|---|---|
400 | Shortcode format invalid. |
404 | Template not found. |
Template thumbnail
GET /api/templates/:shortcode/thumbnail
Returns the template's pre-baked preview image (≈360p). Used by the Studio gallery, social unfurls, and anywhere you want a quick preview without triggering a full render.
Response
A binary image — WebP for new templates, PNG for legacy ones. The server sniffs the content type from the file's magic bytes and sets Content-Type accordingly. Cached aggressively: Cache-Control: public, max-age=86400 (24 hours).
Errors
| Status | When |
|---|---|
400 | Shortcode format invalid. |
404 | Thumbnail not found (either the shortcode doesn't exist, or its thumbnail hasn't been generated yet). |
Player identifiers
Identifiers can be Java or Bedrock; the platform is auto-detected from the format. Bedrock identifiers are typically prefixed with a . to disambiguate them from Java usernames (though pure-numeric Bedrock XUIDs are detected without the prefix).
| Example | Platform | Kind |
|---|---|---|
Dinnerbone | Java | Username (1–16 chars, letters/digits/underscore) |
069a79f4-44e9-4726-a5be-fca90e38aaf5 | Java | UUID (dashed) |
069a79f444e94726a5befca90e38aaf5 | Java | UUID (undashed) |
.MyGen | Bedrock | Gamertag (prefixed) |
.2533274793548956 | Bedrock | XUID (prefixed, explicit) |
2533274793548956 | Bedrock | XUID (numeric, auto-detected) |
Canonicalisation
Internally, identifiers are resolved to a canonical form (undashed lowercase UUID for Java, XUID for Bedrock) and cached for 1 hour. That means Dinnerbone and the matching UUID share a render cache entry — two requests for "same player, same template" hit cache together regardless of which form you used.
Multiple players
For templates with more than one player slot, pass identifiers comma-separated in the order the template expects:
GET /api/render/Dinnerbone,.MyGen,Notch/shortc
The number of identifiers must match the template's playerCount exactly — pass too many or too few and you'll get a 400.
Not found
If a player can't be resolved (nonexistent Java username, unknown gamertag), the render endpoint returns 404 with an error message naming which player failed. Bedrock players using a classic skin are still resolvable — the renderer falls back to the classic skin via GeyserMC when no Persona model is available.
Rate limits
Rate limits are applied per client IP over a 1-minute rolling window.
| Endpoint | Limit |
|---|---|
GET /api/render/:gamertags/:shortcode | 60 / min |
GET /api/templates | Unlimited |
GET /api/templates/:shortcode | Unlimited |
GET /api/templates/:shortcode/thumbnail | Unlimited |
When you exceed a limit the server responds with 429 Too Many Requests. If you're rendering a lot of the same player + template, those hit the cache and don't count against your budget — see Caching.
Caching
Render cache
Completed renders are stored on disk, keyed by the canonical player ID, the pose hash, and the requested format. Identical requests are served straight from disk — cache entries live for 6 hours by default. The X-Cache: HIT / MISS response header tells you which path you got.
Because the cache keys on canonical IDs, Dinnerbone and the matching UUID share an entry. Changing format (webp → png) is a separate cache entry.
Client-side caching
Renders come back with Cache-Control: public, max-age=3600, so browsers and CDNs can safely cache them for an hour. Template thumbnails have a 24-hour max-age. Template metadata and the template list use a 60-second max-age so gallery changes propagate quickly.
Player-resolution cache
Player identifier lookups (username → UUID, gamertag → XUID) are cached in memory for 1 hour. The first request for a new player is slower; subsequent renders of the same player skip the lookup entirely.
Errors
All error responses are JSON with an error string describing what went wrong. Common status codes:
| Status | Meaning | Retry? |
|---|---|---|
400 | Bad request — malformed shortcode, wrong player count, invalid params. | Fix the request. |
404 | Template not found, or player not found. | Check the shortcode/identifier. |
429 | Rate limit exceeded. | Wait until the 1-minute window resets. |
500 | Render failed internally. | Retry with exponential backoff; if it persists, report it. |
503 | Render pipeline full. | Yes — respect Retry-After (typically 5 seconds). |
If you're integrating the API into a production system, the most important codes to handle gracefully are 429 (slow down) and 503 (retry with the suggested interval). 404 on a player lookup usually means the player genuinely doesn't exist — fail the request and move on rather than retrying.