API e MCP do Studio Tank

Crie personagens a partir do catálogo, veja a prévia e baixe arquivos com esqueleto e animações direto do seu código, do seu pipeline de jogo ou do seu assistente de IA. Mesmas regras do estúdio: a cota e a licença seguem o plano da sua conta.

Começar em 3 passos

  1. Entre no estúdio, abra o menu da conta e crie uma chave de API. Ela aparece uma única vez: guarde num cofre ou variável de ambiente. Criar chave no estúdio →
  2. Sorteie um personagem (ou monte a receita com ids do 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. Peça o arquivo e espere ficar pronto; a resposta traz um link de download que vale 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)

Especificação OpenAPI 3.1 para Postman, Insomnia ou geradores de SDK: https://avatar.tankpvp.com/api/v1/openapi.json

Autenticação

Envie a chave no cabeçalho Authorization: Bearer avs_… em toda chamada. A API não aceita o cookie do site e não libera CORS: use a chave só no servidor, nunca em JavaScript de página. Cada conta pode ter até 5 chaves ativas, com escopos, e revogar uma corta o acesso na hora.

EscopoLibera
catalog:readcatálogo e validação de receitas
avatars:writesortear e gerar prévias em imagem
exports:writecriar arquivos (usa a cota), status, download e histórico

Limites e cota

A cota é da conta: o que você baixa pelo estúdio, pela API e pelo MCP soma no mesmo contador. Os cabeçalhos RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset mostram o limite por minuto; ao estourar, a resposta é 429 com Retry-After.

GrátisPro
Downloads por mês5ilimitado
Licença dos arquivospessoal, não comercialcomercial
Requisições por minuto (por chave)60300
Prévias em imagem por hora30300
Aleatórios por dia20ilimitado
Spritesaté 128 px, 4 direções256 px, 8 direções
Lote de personagensnãoaté 50 GLB num .zip
Exportações por hora / ao mesmo tempo60 / 160 / 1

Arquivos, idempotência e licença

  • Fila: POST /exports responde 202 com o id. Consulte GET /exports/{id}?wait=20: a resposta espera até 25 s e evita várias consultas.
  • Idempotência: mande Idempotency-Key no POST /exports. Repetir com a mesma chave e o mesmo corpo em 24 h devolve o mesmo arquivo, sem gastar cota de novo.
  • Download: o arquivo fica 15 minutos no servidor. Baixe com a sua chave ou pelo download.url assinado (não precisa de chave; ideal para entregar a quem pediu).
  • Licença: todo arquivo leva um número AS-XXXXX-XXXXX (no GLB, no PNG e no LICENCA.txt dos .zip). Qualquer pessoa confere em GET /licenses/{id}, sem ver o dono.
  • Receitas: mande config (peças e cores) ou code (o código curto do link do estúdio). Ids errados viram o padrão; /avatars/validate explica o que mudou.

Erros

Todo erro vem no mesmo formato: { "error": { "code", "message", "docs" } }. Use o code no seu código (ele não muda); a mensagem é para pessoas.

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: conecte o Claude e outros assistentes

O servidor MCP em /mcp deixa um assistente de IA montar personagens com você: ele consulta o catálogo, mostra a prévia em imagem e, quando você aprovar, exporta e entrega o link. Usa a mesma chave, a mesma cota e a mesma licença da 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 e outros clientes com MCP por HTTP (arquivo de configuração):

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

Claude Desktop (via mcp-remote, precisa do Node instalado):

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

Ferramentas disponíveis

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.

Console MCP (testar aqui)

Referência

Conta, plano e cota

GET/me

Conta, plano e cota

Mostra o plano, os downloads usados no mês, os aleatórios restantes do dia, os limites e a chave usada.

  • 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).

Peças, estilos, animações e cores

GET/catalogcatalog:read

Catálogo de peças, estilos e animações

Tudo o que pode entrar numa receita: ids de peça por categoria, estilos, zonas de cor, paletas, animações, presets e opções de exportação. Nomes no 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 e pré-visualizar

POST/avatars/validatecatalog:read

Validar receita

Normaliza a receita (ids e cores conferidos), devolve o código curto e explica o que foi trocado, o que ficou no padrão e o que fica escondido (ex.: elmo esconde cabelo). Não gasta cota.

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

Sortear personagens

Gera de 1 a 10 receitas coerentes com o estilo (ou de qualquer estilo). Com `seed` o resultado se repete. No grátis conta no limite diário de aleatórios.

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

Prévia em imagem

Retrato PNG de 128 ou 256 px renderizado no servidor. Não gasta download; tem limite por hora (grátis 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.

Arquivos (usam a cota de downloads)

POST/exportsexports:write

Criar arquivo (GLB, OBJ, sprites, PNG)

Valida, desconta 1 download da cota (lote: N) e coloca o arquivo na fila. Responde 202 com o id; acompanhe em GET /exports/{id}. Use o cabeçalho Idempotency-Key para repetir com segurança.

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

Status do arquivo

Status, progresso, licença e, quando pronto, um link assinado de download (15 min). Com `wait` (até 25 s) a resposta espera terminar.

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

Baixar o arquivo

O arquivo pronto (fica 15 min no servidor). Com a chave no cabeçalho, ou sem chave usando o `token` do link assinado.

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

Histórico de downloads

Downloads da conta (estúdio, API e MCP) com número e tipo da licença, do mais novo ao mais antigo. Pagine com `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).

Criação por IA (usa créditos de IA)

GET/creditsavatars:write

Saldo de créditos de IA

Saldo (comprados + do Pro no mês), custo de cada tipo de geração e se a IA está disponível.

  • 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

Criar personagem com IA

A IA (Claude) escolhe peças e cores do catálogo a partir de uma descrição, de uma foto de referência (data URL JPEG/PNG/WebP, até ~1,2 MB) ou ajusta uma receita (mode: refine). Custa 2, 3 ou 1 crédito, cobrado antes e devolvido se falhar. Espera até 20 s; se não terminou, responde 202 com o id para GET /ai/generations/{id}. Pessoas reais e marcas viram traços 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

Histórico da criação por IA

Tudo o que a conta pediu à IA e o que saiu (código da receita para reabrir sem custo). A foto de referência nunca é guardada.

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 da criação por IA

Status de uma geração (só do dono); com `wait` (até 25 s) espera terminar. Fica disponível 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).

Conferência pública de licença

GET/licenses/{id}Público (sem chave)

Conferir uma licença

Público (sem chave): diz se a licença existe, o tipo (pessoal ou comercial), a data e o formato. Não revela o dono.

id *pathstring
  • 200 OK