Códigos de erro da API

Todas as falhas que este gateway retorna, medidas uma a uma contra o endpoint real em 2026-09-01. Das 8 falhas que ele retorna, 5 não significam o que o seu código de status sugere, e 2 delas os SDKs oficiais repetem antes de o seu programa chegar a vê-las.

Verificado em 2026-09-01

O código de status engana

Leia o error.code, não o código de status

Um nome de modelo errado volta como 503. Um campo messages ausente volta como 500. Os dois são erros permanentes da sua requisição — nenhuma retentativa resolve —, mas openai-python, openai-node e os SDKs da Anthropic repetem por padrão duas vezes os 408, 409, 429 e todos os 5xx, com backoff exponencial. Assim um erro de digitação se transforma em três idas e voltas e dezenas de segundos de espera antes de o motivo real aparecer. Esse motivo esteve o tempo todo no error.code, dentro do corpo: a parte que mente é o código de status.

Referência

Códigos de status

Ordenados pela frequência com que aparecem de verdade, não por número.

  • HTTP 401string vazia
    O que aconteceu de fato
    A chave não existe, foi revogada, ou o cabeçalho Authorization não veio.
    O que fazer
    Confirme na página "Chaves de API" do console que a chave continua lá, ou crie uma nova. Uma coisa que você já pode descartar: não é a falta do prefixo "Bearer " — o gateway aceita a chave sozinha também, então essa nunca é a causa.
    Os SDKs repetem
    Não, falha na hora
    Medido no endpoint real
    probes-errors.mjs: invalid-token / missing-auth
    Mensagem retornada
    Invalid token
  • HTTP 503model_not_foundO código de status engana
    O que aconteceu de fato
    Esse ID de modelo não está neste catálogo; quase sempre foi copiado da documentação de outro provedor (gpt-4o, claude-sonnet-4-5). Não há indisponibilidade nenhuma: simplesmente não existe rota para um modelo que aqui não existe.
    O que fazer
    Compare com GET /v1/models, que é a lista oficial. Aqui todo ID tem a forma provedor/modelo, por exemplo deepseek/deepseek-v4-flash.
    Os SDKs repetem
    Sim, duas vezes por padrão
    Medido no endpoint real
    probes-errors.mjs: unknown-model
    Mensagem retornada
    No available channel for model gpt-4o under group y-api (distributor)
  • HTTP 403insufficient_user_quotaO código de status engana
    O que aconteceu de fato
    O saldo da conta chegou a zero. A mensagem está em chinês e mostra o saldo restante com um $ de largura completa — é por isso que procurar em inglês não devolve nada.
    O que fazer
    Adicione crédito em https://y-api.bestvirtualgoods.com/app/billing. O saldo volta na hora, as chaves existentes continuam funcionando e não precisa mexer no código.
    Os SDKs repetem
    Não, falha na hora
    Confirmado no código do upstream, não reproduzido aqui
    service/billing_session.go:355-359
    Mensagem retornada
    用户额度不足, 剩余额度: $0.00
  • HTTP 403pre_consume_token_quota_failedO código de status engana
    O que aconteceu de fato
    A conta ainda tem saldo, mas esta chave específica bateu no limite definido quando ela foi criada. A mensagem mostra tanto o que resta na chave quanto o quanto a requisição precisava.
    O que fazer
    Aumente ou remova o limite dessa chave na página "Chaves de API", ou use uma chave sem limite. Adicionar crédito na conta não resolve: o limite é por chave.
    Os SDKs repetem
    Não, falha na hora
    Medido no endpoint real
    probes-errors.mjs: quota-exhausted
    Mensagem retornada
    token quota is not enough, token remain quota: $0.000002, need quota: $0.000074
  • HTTP 500invalid_requestO código de status engana
    O que aconteceu de fato
    Falta um campo obrigatório no corpo da requisição, quase sempre messages. É um erro de requisição malformada reportado como erro de servidor.
    O que fazer
    A mensagem cita o nome do campo literalmente, então leia isso e não o código de status. Corrija o corpo; repetir vai falhar igual.
    Os SDKs repetem
    Sim, duas vezes por padrão
    Medido no endpoint real
    probes-errors.mjs: missing-field
    Mensagem retornada
    field messages is required
  • HTTP 400invalid_request_errorO código de status engana
    O que aconteceu de fato
    Esse endpoint não existe aqui: /v1/embeddings, /v1/completions e /v1/images/generations caem todos neste caso. E o corpo afirma que messages é obrigatório, apontando para algo que não tem nada a ver com o problema real.
    O que fazer
    Este gateway atende chat completions e o endpoint messages da Anthropic. Se algum framework chama um endpoint de embeddings por baixo, essa parte precisa de outro provedor.
    Os SDKs repetem
    Não, falha na hora
    Medido no endpoint real
    probes-errors.mjs: unsupported-endpoint
    Mensagem retornada
    `messages` is required and must be a non-empty array.
  • HTTP 400string vazia
    O que aconteceu de fato
    O corpo da requisição não é JSON válido. O upstream duplica o próprio prefixo "Invalid request:", o que é só cosmético.
    O que fazer
    Normalmente é um corpo escrito na mão ou problema de aspas no shell. Valide o JSON antes de enviar e, no shell, coloque o corpo inteiro entre aspas simples.
    Os SDKs repetem
    Não, falha na hora
    Medido no endpoint real
    probes-errors.mjs: malformed-json
    Mensagem retornada
    Invalid request: Invalid request: invalid JSON request body
  • HTTP 404string vazia
    O que aconteceu de fato
    POST /v1/messages/count_tokens não está implementado. O Claude Code e o SDK da Anthropic chamam esse endpoint para estimar o contexto antes de enviar a requisição.
    O que fazer
    Não há nada para corrigir do seu lado. Os clientes pulam a estimativa ou mostram um aviso; chat, streaming e ferramentas não são afetados.
    Os SDKs repetem
    Não, falha na hora
    Medido no endpoint real
    probes-errors.mjs: count-tokens
    Mensagem retornada
    Invalid URL (POST /v1/messages/count_tokens)

Falhas silenciosas

Pior que um erro: HTTP 200

Três falhas retornam 200, não lançam exceção nenhuma e deixam o seu programa seguir em frente. O que está errado é o conteúdo ou a fatura — e é justamente por isso que são difíceis de descobrir sozinho.

A imagem é aceita e depois ignorada

O upstream marca cinco modelos com image_ratio. Essa marca é um coeficiente de cobrança, não uma capacidade de visão. Os cinco aceitam imagem em data URL, retornam 200 e respondem com toda a confiança sobre uma imagem que nunca viram: a sonda mandou um PNG verde puro e nenhum acertou a cor. O modelo recomendado, ao contrário, recusa com 400 — das duas falhas, essa é a menos perigosa.

Da matriz de compatibilidade de clientes

max_completion_tokens limita o texto, não a fatura

Com o limite em 12, o moonshotai/kimi-k2.5 cobrou 261 tokens: 21,8 vezes mais. O corte em si funciona (finish_reason=length); o excedente são tokens de raciocínio, que são cobrados mas nunca aparecem em content. Qualquer estimativa de custo baseada nesse limite fica baixa no mesmo fator.

Da matriz de compatibilidade de clientes

Os ids de mensagem da Anthropic não têm o prefixo msg_

POST /v1/messages retorna um id hexadecimal sem prefixo. Código que assume o prefixo msg_, ou que faz parsing do id para rotear a resposta, não vai casar — mesmo com o resto do corpo seguindo a especificação.

Da matriz de compatibilidade de clientes

Parsing

Como é um corpo de erro

O invólucro é sempre {"error": {...}}, mas o conjunto de campos não é estável: alguns erros trazem param, outros omitem, e code costuma ser string vazia. Faça o parsing de forma defensiva e trate todo campo como opcional.

401, sem o campo param
{"error":{"code":"","message":"Invalid token (request id: 2026090114474514374…)","type":"new_api_error"}}
404, com param presente mas vazio
{"error":{"message":"Invalid URL (POST /v1/messages/count_tokens)","type":"invalid_request_error","param":"","code":""}}

Toda mensagem termina com um request id, e ele muda em cada chamada. Remova antes de comparar mensagens com esta página e, ao contrário, mande junto quando reportar um problema para nós: é a única coisa que identifica a sua requisição exata nos logs.

Diagnóstico

Três passos que isolam quase tudo

Nesta ordem. Cada passo elimina uma camada, então a resposta está onde a sequência parar.

  1. Confirme primeiro a chave e a rota

    GET /v1/models não custa nada e usa a mesma chave. Um 200 com a lista de modelos prova que chave, rede e borda da CDN estão todas em ordem — ou seja, o problema está no corpo da requisição, não nas credenciais.

    curl -s https://api.y-api.bestvirtualgoods.com/v1/models -H "Authorization: Bearer $YAPI_KEY" | head -c 200
  2. Reproduza com curl

    Isso tira o SDK da jogada. Se o curl funciona e o seu código não, a diferença está em como aquela biblioteca monta a requisição, não no gateway.

    curl -i https://api.y-api.bestvirtualgoods.com/v1/chat/completions \
      -H "Authorization: Bearer $YAPI_KEY" \
      -H "Content-Type: application/json" \
      -d '{"model":"deepseek/deepseek-v4-flash","messages":[{"role":"user","content":"hi"}]}'
  3. Desligue as retentativas enquanto investiga

    Sem retentativas, um 500 ou 503 causado pela sua própria requisição aparece na primeira tentativa em vez de depois de duas inúteis. Religue depois: contra falhas transitórias de verdade, as retentativas valem a pena.

    client = OpenAI(
        base_url="https://api.y-api.bestvirtualgoods.com/v1",
        api_key=os.environ["YAPI_KEY"],
        max_retries=0,  # só para investigar
    )

Não é nenhum desses?

A página de status mostra se o gateway está degradado, com os últimos 90 dias de verificações. Se estiver verde e você continuar travado, o request id do corpo do erro é a única coisa que vale mandar para nós.