MinecraftRender / Docs / API
Open Studio →

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.

The endpoints documented here are the stable public surface. Other routes exist (scene publishing, Studio-side state) but they're used by the in-browser editor and aren't considered a stable interface for external integrations.

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

HeaderValuesMeaning
X-CacheHIT / MISSWhether the response came from the render cache.
X-Template6-char shortcodeWhich template produced the render (template endpoint only).
Cache-Controlpublic, max-age=3600Safe for CDN / browser caching for an hour.
Retry-AftersecondsSent 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

ParamRequiredNotes
gamertagsYesComma-separated list. Number must match the template's playerCount. See Player identifiers.
shortcodeYes6 lowercase alphanumeric characters ([a-z0-9]{6}).

Query parameters

ParamDefaultValues
formatwebpwebp 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

StatusWhen
400Shortcode malformed, or the number of gamertags doesn't match the template's playerCount.
404Template not found, or one of the players couldn't be resolved.
429Rate-limited (60/min/IP).
503Render pipeline is full. Retry after the Retry-After interval.

List templates

GET /api/templates

Paginated list of gallery-published templates.

Query parameters

ParamDefaultNotes
limit201–100.
offset0For pagination.
sortnewestnewest or popular.
tagFilter 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

StatusWhen
400Shortcode format invalid.
404Template 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

StatusWhen
400Shortcode format invalid.
404Thumbnail 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).

ExamplePlatformKind
DinnerboneJavaUsername (1–16 chars, letters/digits/underscore)
069a79f4-44e9-4726-a5be-fca90e38aaf5JavaUUID (dashed)
069a79f444e94726a5befca90e38aaf5JavaUUID (undashed)
.MyGenBedrockGamertag (prefixed)
.2533274793548956BedrockXUID (prefixed, explicit)
2533274793548956BedrockXUID (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.

EndpointLimit
GET /api/render/:gamertags/:shortcode60 / min
GET /api/templatesUnlimited
GET /api/templates/:shortcodeUnlimited
GET /api/templates/:shortcode/thumbnailUnlimited

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.

If your use case needs higher limits (e.g. a large public site displaying lots of unique players), get in touch on Discord rather than sharding requests across IPs.

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 (webppng) 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:

StatusMeaningRetry?
400Bad request — malformed shortcode, wrong player count, invalid params.Fix the request.
404Template not found, or player not found.Check the shortcode/identifier.
429Rate limit exceeded.Wait until the 1-minute window resets.
500Render failed internally.Retry with exponential backoff; if it persists, report it.
503Render 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.