API y MCP de Studio Tank

Crea personajes a partir del catálogo, mira la vista previa y descarga archivos con esqueleto y animaciones directo desde tu código, tu pipeline de juego o tu asistente de IA. Las mismas reglas del estudio: la cuota y la licencia siguen el plan de tu cuenta.

Empieza en 3 pasos

  1. Entra al estudio, abre el menú de la cuenta y crea una clave de API. Se muestra una sola vez: guárdala en un gestor de secretos o una variable de entorno. Crear clave en el estudio →
  2. Sortea un personaje (o arma la receta con ids del catálogo):
    curl -s https://avatar.tankpvp.com/api/v1/avatars/random \
      -H "Authorization: Bearer $AVATAR_KEY" \
      -H "Content-Type: application/json" \
      -d '{"style": "mago"}'
  3. Pide el archivo y espera a que esté listo; la respuesta trae un enlace de descarga válido por 15 minutos:
    curl -s https://avatar.tankpvp.com/api/v1/exports \
      -H "Authorization: Bearer $AVATAR_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: meu-pedido-001" \
      -d '{"code": "<code>", "format": "glb", "fps": 24, "clips": ["Walk","Run","Attack"]}'
    
    curl -s "https://avatar.tankpvp.com/api/v1/exports/<id>?wait=20" -H "Authorization: Bearer $AVATAR_KEY"
    # → download.url (15 min)

Especificación OpenAPI 3.1 para Postman, Insomnia o generadores de SDK: https://avatar.tankpvp.com/api/v1/openapi.json

Autenticación

Envía la clave en la cabecera Authorization: Bearer avs_… en cada llamada. La API no acepta la cookie del sitio y no tiene CORS: usa la clave solo en tu servidor, nunca en JavaScript de página. Cada cuenta puede tener hasta 5 claves activas con alcances, y revocar una corta el acceso al instante.

AlcancePermite
catalog:readcatálogo y validación de recetas
avatars:writepersonajes aleatorios y vistas previas en imagen
exports:writecrear archivos (usa la cuota), estado, descarga e historial

Límites y cuota

La cuota es de la cuenta: lo que descargas por el estudio, la API y el MCP suma en el mismo contador. Las cabeceras RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset muestran el límite por minuto; al superarlo recibes 429 con Retry-After.

GratisPro
Descargas por mes5ilimitadas
Licencia de los archivospersonal, no comercialcomercial
Solicitudes por minuto (por clave)60300
Vistas previas por hora30300
Aleatorios por día20ilimitados
Spriteshasta 128 px, 4 direcciones256 px, 8 direcciones
Lote de personajesnohasta 50 GLB en un .zip
Exportaciones por hora / a la vez60 / 160 / 1

Archivos, idempotencia y licencia

  • Cola: POST /exports responde 202 con el id. Consulta GET /exports/{id}?wait=20: la respuesta espera hasta 25 s y evita muchas consultas.
  • Idempotencia: envía Idempotency-Key en POST /exports. Repetir con la misma clave y el mismo cuerpo en 24 h devuelve el mismo archivo sin gastar cuota otra vez.
  • Descarga: el archivo queda 15 minutos en el servidor. Descárgalo con tu clave o por el download.url firmado (no necesita clave; ideal para entregarlo a quien lo pidió).
  • Licencia: cada archivo lleva un número AS-XXXXX-XXXXX (en el GLB, el PNG y el LICENCA.txt de los .zip). Cualquiera lo verifica en GET /licenses/{id} sin ver al dueño.
  • Recetas: envía config (piezas y colores) o code (el código corto del enlace del estudio). Los ids incorrectos vuelven al valor por defecto; /avatars/validate explica qué cambió.

Errores

Todo error tiene el mismo formato: { "error": { "code", "message", "docs" } }. Usa el code en tu código (no cambia); el mensaje es para personas.

HTTPcodemessage
401missing_keySend your API key in the header: Authorization: Bearer avs_...
401invalid_keyAPI key not found or revoked.
403not_verifiedConfirm the account e-mail before using the API.
403scopeThis API key does not have the scope this endpoint needs.
429rate_limitedToo many requests. Retry after the seconds in the Retry-After header.
400invalid_jsonThe request body is not valid JSON.
413too_largeThe request body is too large.
400config_requiredSend the avatar as `config` (object) or `code` (recipe code).
400invalid_codeThe recipe code could not be decoded.
400invalid_styleUnknown style. See `styles` in GET /api/v1/catalog.
400invalid_familyUnknown family. See `families` in GET /api/v1/catalog (chibi, voxel).
400invalid_count`count` must be an integer in the allowed range.
400invalid_seed`seed` must be an integer from 0 to 4294967295.
400invalid_size`size` must be one of the allowed values.
400format`format` must be glb, obj, sprites or png.
400fps`fps` must be one of 12, 24, 30, 36 or 60.
400clipsGLB and sprites need at least one valid clip id in `clips`.
400sprites`dirs` must be 1, 4 or 8 and `size` 64, 128 or 256.
402pro_onlyThis option is available on the Pro plan.
400too_bigToo many sprite frames. Use fewer clips, directions, a lower fps or a smaller size.
400batch`batch.count` must be 1 to 50 and batches are GLB only.
429busyAn export is already running for this account. Wait for it to finish.
402quotaMonthly download quota reached. The Pro plan has unlimited downloads.
402random_limitDaily random limit reached on the free plan.
402quota_outThe free plan's monthly downloads are used up, so random avatars are paused until next month. The Pro plan has no limits.
503queue_fullThe export queue is full. Try again in a minute.
404not_foundNot found (or it belongs to another account, or it already expired).
403expired_linkThis download link is invalid or expired. Ask GET /api/v1/exports/{id} for a new one.
400idempotency_key`Idempotency-Key` must have 1 to 255 visible ASCII characters.
422idempotency_mismatchThis Idempotency-Key was already used with a different request body.
409idempotency_in_progressA request with this Idempotency-Key is still being processed.
402creditsNot enough AI credits. Buy a credit pack in the studio.
503ai_offAI generation is not available right now.
429ai_busyAn AI generation is already running for this account.
429ai_dailyDaily AI generation limit reached for this account.
503ai_pausedAI generation is paused for today. Try again tomorrow.
400ai_prompt`prompt` must have 3 to 1000 characters (or send an image).
400ai_image`image` must be a data URL of a JPEG, PNG or WebP image.
413ai_image_sizeThe image is too large (max ~1.2 MB). Resize it and try again.
200ai_refusedThe AI declined this request. Describe the character differently.
200ai_incompleteThe AI could not finish this character. Try a simpler description.
200ai_bad_outputThe AI answer was invalid. Your credits were returned; try again.
200ai_failedThe AI service failed. Your credits were returned; try again.
500genericSomething went wrong on our side. Try again.

MCP: conecta Claude y otros asistentes

El servidor MCP en /mcp permite que un asistente de IA cree personajes contigo: consulta el catálogo, muestra la vista previa en imagen y, cuando apruebes, exporta y te entrega el enlace. Usa la misma clave, cuota y licencia que la API.

POSThttps://avatar.tankpvp.com/mcp

Claude Code (terminal):

claude mcp add --transport http avatar-studio https://avatar.tankpvp.com/mcp \
  --header "Authorization: Bearer $AVATAR_KEY"

Cursor, VS Code, Windsurf y otros clientes con MCP por HTTP (archivo de configuración):

{
  "mcpServers": {
    "avatar-studio": {
      "type": "http",
      "url": "https://avatar.tankpvp.com/mcp",
      "headers": {
        "Authorization": "Bearer avs_..."
      }
    }
  }
}

Claude Desktop (vía mcp-remote, necesita Node instalado):

{
  "mcpServers": {
    "avatar-studio": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://avatar.tankpvp.com/mcp",
        "--header",
        "Authorization:Bearer avs_..."
      ]
    }
  }
}

Herramientas disponibles

get_catalogPart ids by category (with styles and rules), styles, color zones, palettes, style presets, animation clips and export options. Call this first.
validate_avatarNormalizes a recipe and explains problems (unknown ids, wrong category, invalid colors), defaults and hidden categories. Free.
random_avatar1 to 5 random recipes, optionally of one style. A seed makes it reproducible. Counts toward the daily random limit on the free plan.
preview_avatarRenders a PNG portrait (128 or 256 px) of the recipe so you and the user can see it. Does not use the download quota (hourly limit).
export_avatarCreates the downloadable file: glb (rigged + animations), obj (zip), sprites (zip of sheets) or png (1024 px portrait). Uses 1 download from the monthly quota. Waits up to ~25 s and returns a download link valid for 15 minutes plus the license. Ask the user before calling.
get_exportStatus of an export by id; waits up to `wait` seconds (max 25). When done, returns a fresh 15-minute download link.
account_statusPlan, license kind, downloads used and left this month, random rolls left today and limits.

Consola MCP (pruébalo aquí)

Referencia

Cuenta, plan y cuota

GET/me

Cuenta, plan y cuota

Devuelve el plan, las descargas usadas en el mes, los aleatorios restantes del día, los límites y la clave en uso.

  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).

Piezas, estilos, animaciones y colores

GET/catalogcatalog:read

Catálogo de piezas, estilos y animaciones

Todo lo que puede ir en una receta: ids de pieza por categoría, estilos, zonas de color, paletas, animaciones, presets y opciones de exportación. Nombres en el idioma pedido.

langquerypt | en | es
categoryqueryhead | hair | eyes | mouth | beard | helmet | body | legs | boots | gloves | back | handR | handLOnly parts of this category.
familyquerychibi | voxelOnly parts of this family (chibi or voxel).
  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).

Validar, sortear y previsualizar

POST/avatars/validatecatalog:read

Validar receta

Normaliza la receta (ids y colores verificados), devuelve el código corto y explica qué se reemplazó, qué quedó por defecto y qué queda oculto (p. ej. el casco oculta el pelo). Gratis.

{
  "config": {
    "name": "Ana",
    "parts": {
      "helmet": "helm_wizard",
      "handR": "r_staff"
    },
    "palette": {
      "primary": "#5b3fc4"
    }
  }
}
  • 200 OK
  • 400 Neither config nor code, or an invalid code.
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
POST/avatars/randomavatars:write

Personajes aleatorios

Genera de 1 a 10 recetas coherentes con el estilo (o de cualquier estilo). Con `seed` el resultado se repite. En el plan gratis cuenta en el límite diario de aleatorios.

{
  "style": "mago",
  "count": 2,
  "seed": 42
}
  • 200 OK
  • 400 Invalid style, count or seed.
  • 401 Missing or invalid API key.
  • 402 Daily random limit reached (free plan).
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
POST/avatars/previewavatars:write

Vista previa en imagen

Retrato PNG de 128 o 256 px renderizado en el servidor. No gasta descarga; tiene límite por hora (gratis 30, Pro 300).

{
  "config": {
    "name": "Bomber",
    "parts": {
      "head": "head_round",
      "hair": "hair_short",
      "eyes": "eyes_big",
      "mouth": "mouth_open",
      "beard": "beard_none",
      "helmet": "helm_bomber",
      "body": "body_bomber",
      "legs": "legs_cargo",
      "boots": "boots_sneakers",
      "gloves": "gloves_cartoon",
      "back": "back_bombs",
      "handR": "r_bomb",
      "handL": "l_none"
    },
    "palette": {
      "skin": "#f2c39b",
      "hair": "#5a3a22",
      "eyes": "#2fb3c4",
      "primary": "#f07f2a",
      "secondary": "#2f4f8f",
      "detail": "#f2c534",
      "metal": "#b9c2cf",
      "leather": "#5a3a22",
      "glow": "#ff6b3d",
      "dark": "#1d1b26",
      "white": "#f7f7fb",
      "tongue": "#e2697c",
      "flash": "#ffd24a"
    }
  },
  "size": 256
}
  • 200 PNG image
  • 400 Invalid avatar or size.
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
  • 503 Render queue full.

Archivos (usan la cuota de descargas)

POST/exportsexports:write

Crear archivo (GLB, OBJ, sprites, PNG)

Valida, descuenta 1 descarga de la cuota (lote: N) y pone el archivo en la cola. Responde 202 con el id; síguelo con GET /exports/{id}. Usa la cabecera Idempotency-Key para reintentar con seguridad.

Idempotency-KeyheaderstringSame key + same body within 24 h returns the same export without using quota again.
{
  "config": {
    "name": "Bomber",
    "parts": {
      "head": "head_round",
      "hair": "hair_short",
      "eyes": "eyes_big",
      "mouth": "mouth_open",
      "beard": "beard_none",
      "helmet": "helm_bomber",
      "body": "body_bomber",
      "legs": "legs_cargo",
      "boots": "boots_sneakers",
      "gloves": "gloves_cartoon",
      "back": "back_bombs",
      "handR": "r_bomb",
      "handL": "l_none"
    },
    "palette": {
      "skin": "#f2c39b",
      "hair": "#5a3a22",
      "eyes": "#2fb3c4",
      "primary": "#f07f2a",
      "secondary": "#2f4f8f",
      "detail": "#f2c534",
      "metal": "#b9c2cf",
      "leather": "#5a3a22",
      "glow": "#ff6b3d",
      "dark": "#1d1b26",
      "white": "#f7f7fb",
      "tongue": "#e2697c",
      "flash": "#ffd24a"
    }
  },
  "format": "glb",
  "fps": 24,
  "clips": [
    "Walk",
    "Run",
    "Attack"
  ]
}
  • 202 Queued
  • 400 Invalid request (format, fps, clips, sprites, batch).
  • 401 Missing or invalid API key.
  • 402 Quota reached or Pro-only option.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 409 Idempotency-Key still in progress.
  • 422 Idempotency-Key reused with another body.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
  • 503 Export queue full (quota returned).
GET/exports/{id}exports:write

Estado del archivo

Estado, progreso, licencia y, cuando está listo, un enlace firmado de descarga (15 min). Con `wait` (hasta 25 s) la respuesta espera a que termine.

id *pathstring
waitqueryinteger
  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 404 Unknown, expired or not yours.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
GET/exports/{id}/fileexports:write

Descargar el archivo

El archivo listo (queda 15 min en el servidor). Con la clave en la cabecera, o sin clave usando el `token` del enlace firmado.

id *pathstring
tokenquerystringFrom `download.url` (no API key needed).
  • 200 File (model/gltf-binary, application/zip or image/png)
  • 403 Invalid or expired signed link.
  • 404 Unknown, expired or not yours.
GET/downloadsexports:write

Historial de descargas

Descargas de la cuenta (estudio, API y MCP) con número y tipo de licencia, de la más nueva a la más antigua. Pagina con `before`.

limitqueryinteger
beforequeryintegerReturn downloads with id lower than this (use `next`).
  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).

Creación con IA (usa créditos de IA)

GET/creditsavatars:write

Saldo de créditos de IA

Saldo (comprados + del Pro en el mes), costo de cada tipo de generación y si la IA está disponible.

  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
POST/ai/generateavatars:write

Crear personaje con IA

La IA (Claude) elige piezas y colores del catálogo a partir de una descripción, una foto de referencia (data URL JPEG/PNG/WebP, hasta ~1,2 MB) o ajusta una receta (mode: refine). Cuesta 2, 3 o 1 crédito, cobrado antes y devuelto si falla. Espera hasta 20 s; si no terminó, responde 202 con el id para GET /ai/generations/{id}. Personas reales y marcas se vuelven rasgos genéricos.

{
  "prompt": "a tall rapper with braids, dark sunglasses and a blue jacket",
  "lang": "en"
}
  • 200 Done (status: done) or failed (status: error, credits refunded)
  • 202 Still running: poll GET /ai/generations/{id}
  • 400 Invalid prompt or image.
  • 401 Missing or invalid API key.
  • 402 Not enough AI credits.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
  • 503 AI unavailable or paused for today.
GET/ai/historyavatars:write

Historial de creación con IA

Todo lo que la cuenta pidió a la IA y lo que salió (código de la receta para reabrir sin costo). La foto de referencia nunca se guarda.

limitqueryinteger
beforequeryinteger
  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).
GET/ai/generations/{id}avatars:write

Resultado de la creación con IA

Estado de una generación (solo del dueño); con `wait` (hasta 25 s) espera a que termine. Disponible por 15 minutos.

id *pathinteger
waitqueryinteger
  • 200 OK
  • 401 Missing or invalid API key.
  • 403 The key lacks the scope, or the account e-mail is not confirmed.
  • 404 Unknown, expired or not yours.
  • 429 Rate limited (see Retry-After and RateLimit-* headers).

Verificación pública de licencia

GET/licenses/{id}Público (sin clave)

Verificar una licencia

Público (sin clave): indica si la licencia existe, su tipo (personal o comercial), la fecha y el formato. No revela al dueño.

id *pathstring
  • 200 OK