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 7 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 401
string 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 503
model_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 403
insufficient_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 403
pre_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 500
invalid_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 400
invalid_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 400
string 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
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.
{"error":{"code":"","message":"Invalid token (request id: 2026090114474514374…)","type":"new_api_error"}}{"error":{"message":"Invalid URL (POST /v1/fine_tuning/jobs)","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.
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 200Reproduza 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"}]}'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 30 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.