Pular para o conteúdo
Testar o chatObter chave de API

Como a Bayle funciona

Esta página explica o que acontece entre a sua requisição chegar a https://api.bayle.ai e a resposta voltar. Você não precisa dela para fazer a primeira chamada (para isso existe o Início rápido). Ela serve para quando você está construindo algo que precisa se comportar bem diante de timeouts, falhas e payloads grandes, ou quando quer saber para onde vão os seus dados.

Your code / SDK / tool chat.bayle.ai (web chat)
│ browser ──► chat server
│ │
│ HTTPS, Authorization: Bearer <key> │ key from an HttpOnly cookie
▼ ▼
┌──────────────────────────────────────────────────────────────┐
│ Bayle API (api.bayle.ai) │
│ CORS ─► request ID ─► request log ─► panic recovery │
│ ─► language ─► auth ─► body limit ─► handler │
└──────────────────────────────────────────────────────────────┘
│
▼
Model infrastructure
(runs the model you named in `model`)

A API não guarda estado. Ela não tem banco de dados, cache nem armazenamento de sessão próprio, então nada de uma requisição passa para a seguinte.

Toda requisição passa pelas mesmas etapas, nesta ordem.

Etapa O que faz
CORS Toda resposta permite qualquer origem. Um preflight do navegador (OPTIONS) é respondido com 204 na hora e não segue adiante.
ID de requisição Cada requisição recebe um ID usado para correlacionar a sua linha de log.
Log de requisição Uma linha por requisição, gravada quando a resposta termina: método, caminho, status, duração, ID de requisição. Nada mais.
Recuperação de panic Uma falha interna inesperada vira um envelope de erro normal, em vez de uma conexão derrubada.
Idioma Lê Accept-Language, escolhe inglês ou português do Brasil e define Content-Language na resposta antes de qualquer outra coisa ser escrita.
Autenticação Confere a key, a menos que o endpoint seja público.
Limite do corpo Limita o corpo da requisição a 10 MiB.
Handler Valida o formato, chama o modelo e escreve a resposta.

A autenticação roda antes do limite do corpo, de propósito. Uma requisição sem key válida é recusada depois que os cabeçalhos são lidos, antes de qualquer byte do corpo.

A API atende exatamente oito operações, na raiz de https://api.bayle.ai.

Endpoint Exige key
GET /models Não
POST /video/quote Não
POST /chat/completions Sim
POST /embeddings Sim
POST /images/generations Sim
POST /video/queue Sim
POST /video/retrieve Sim
POST /video/complete Sim

A autenticação vem ligada por padrão. Só os dois endpoints marcados com “Não” ficam de fora, então qualquer coisa adicionada depois é protegida, a menos que seja aberta de propósito.

Envie a sua key como bearer token:

Authorization: Bearer <your Bayle key>

Todo jeito de isso dar errado recebe a mesma resposta: cabeçalho ausente, esquema diferente de Bearer, key malformada, key que não é da Bayle, valor vazio ou cabeçalho enviado duas vezes. Todos recebem 401 com o código invalid_api_key e a mesma mensagem. A resposta nunca diz qual verificação falhou, então não entrega nada a quem está tentando adivinhar keys.

Uma key válida, mas sem saldo, é outro caso. Ela autentica, e a requisição falha em seguida com 402 e o código usd_spend_limit_exceeded. Adicionar saldo mantém a mesma key. Veja Autenticação.

A Bayle valida as partes do corpo de que precisa e repassa o resto. Um campo que ela não nomeia é enviado ao modelo do jeito que você mandou, então um parâmetro que o seu modelo aceita chega até ele mesmo que esta documentação ainda não fale dele.

  • Em /chat/completions, o único campo em que a Bayle age é stream, que decide entre uma resposta JSON e um stream de eventos.
  • A Bayle não acrescenta nenhum system prompt próprio. O modelo vê as mensagens que você envia.
  • Um corpo que não é JSON válido, ou que não bate com o formato da operação, é recusado com 400 antes de o modelo ser chamado, então não custa nada.

Defina "stream": true num chat completion para receber Server-Sent Events.

HTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache
X-Accel-Buffering: no
Content-Language: en
data: {"id":"...","choices":[{"delta":{"content":"Hel"}}]}
data: {"id":"...","choices":[{"delta":{"content":"lo"}}]}
data: [DONE]

Os eventos chegam até você linha a linha, assim que são gerados, então você vê os tokens conforme o modelo os produz. Um stream saudável sempre termina com data: [DONE].

Se um stream quebra depois de começar, o código de status não pode mais mudar: o 200 já foi enviado. Então a Bayle informa a falha dentro do próprio stream. Você recebe um último evento com o envelope de erro de sempre e, depois, [DONE]:

data: {"error":{"message":"...","type":"api_error","param":null,"code":null}}
data: [DONE]

Isso acontece quando o stream do modelo termina sem o marcador de fim, quando a conexão com o modelo cai, ou quando um único evento passa de 4 MiB.

Um stream não tem prazo próprio da Bayle. Ele pode durar até uma hora; depois disso, a plataforma de hospedagem fecha a conexão. Esse corte chega sem evento de erro, então trate uma conexão que fecha sem [DONE] também como falha.

A Bayle para de esperar o modelo depois de um tempo fixo por chamada e responde 504 com o código request_timeout.

Chamada Prazo
GET /models 30 s
POST /chat/completions (sem streaming) 30 s
POST /chat/completions (com streaming) Nenhum da Bayle; a conexão é fechada depois de uma hora
POST /embeddings 30 s
POST /images/generations 4 min
POST /video/quote, /queue, /retrieve, /complete 30 s cada

Uma resposta longa que não cabe em 30 segundos deve usar streaming. O vídeo contorna o limite por desenho: a geração roda em segundo plano, e cada chamada é curta.

Algumas chamadas a Bayle repete sozinha, sem você ver, e outras nunca. A linha divisória é se uma segunda tentativa poderia cobrar duas vezes.

A Bayle repete Nunca repetidas
GET /models POST /chat/completions
POST /embeddings POST /images/generations
POST /video/quote POST /video/queue
POST /video/retrieve
POST /video/complete

A coluna da esquerda é repetida até três vezes, com um pequeno backoff, quando a conexão cai, ou diante de um 429 ou de um 5xx. São leituras, cotações ou limpeza, então repetir não faz mal.

A coluna da direita gera saída cobrada. Se a conexão cai depois que o modelo começou, o trabalho pode já estar feito e pago, e uma retentativa silenciosa poderia pagá-lo de novo. Por isso a Bayle devolve a falha para você decidir. Quando você mesmo repetir uma delas, a página Erros diz quais códigos valem a pena.

Todo erro usa o envelope da OpenAI:

{
"error": {
"message": "Your Bayle API key is missing or could not be verified.",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}
  • Decida pelo error.code. A message é para pessoas e muda com o idioma.
  • Toda mensagem é texto da própria Bayle, de um único catálogo, em inglês ou em português do Brasil. Uma falha que a Bayle não reconhece vira um api_error genérico com código null.
  • O código de status diz o tipo de falha: 400 para requisição inválida, 401 para a key, 402 para saldo, 429 para limite de taxa, 503 quando um modelo está offline ou sem capacidade, 504 para timeout.
  • Uma falha ao alcançar o modelo é 502, com tipo api_error e código null.

A lista completa está em Erros.

Envie Accept-Language. Uma tag começando com pt, em qualquer caixa, escolhe português do Brasil; qualquer outra coisa, ou nenhum cabeçalho, escolhe inglês. Toda resposta, de sucesso ou de erro, traz Content-Language dizendo qual foi usado. Só as mensagens de erro são traduzidas; o que o modelo escreve depende do seu prompt. Veja Idioma da resposta.

Limite Valor O que acontece além dele
Corpo da requisição 10 MiB 400, antes de o modelo ser chamado
Resposta de /models, /chat/completions, /embeddings, /video/quote, /video/queue, /video/complete 8 MiB O corpo é cortado no limite
Resposta de /images/generations 32 MiB 502
Resposta de /video/retrieve 128 MiB 502
Um único evento de stream 4 MiB O stream termina com um evento de erro

Os limites de imagem e de vídeo são conferidos antes de qualquer coisa ser enviada, então um resultado grande demais é recusado com 502 em vez de chegar quebrado. Uma resposta sem tamanho declarado que passa do limite é cortada. Na prática, nenhum desses limites chega perto do que uma resposta normal precisa.

As imagens voltam inline em base64, por isso o limite delas é maior. Para entradas grandes, como uma imagem num prompt de visão, mantenha a requisição codificada abaixo de 10 MiB.

Gerar vídeo demora demais para uma única requisição, então é um job que você inicia e depois consulta.

POST /video/quote what it will cost (no key, free)
│
POST /video/queue start the job ──► queue_id (billed)
│ └─ 409 needs_consent: resend the same body with `consents`
▼
POST /video/retrieve every ~10 s
├─ JSON: still processing ─► wait, ask again
└─ video/mp4 bytes, or a download URL ─► done
│
POST /video/complete release the stored media

/video/retrieve devolve um status em JSON ou o próprio vídeo pronto sob o mesmo 200, então leia o Content-Type antes de ler o corpo.

A Bayle não guarda registro do seu queue_id. Ele não fica armazenado em lugar nenhum do lado da Bayle, então só você o tem: se perdê-lo, o job não pode mais ser encontrado. Chamar /video/complete duas vezes é respondido pelo próprio mérito, e não a partir de um registro. O guia de vídeo tem o fluxo completo e a etapa de consentimento.

chat.bayle.ai é um cliente desta mesma API, construído para que a sua key nunca chegue ao navegador.

Browser Chat server Bayle API
─────── ─────────── ─────────
POST /api/chat ──────────► same-origin check
(cookie sent by the read key from cookie
browser, unreadable add Authorization: Bearer ─────► /chat/completions
to page scripts) add Accept-Language
◄──────── stream the reply back ◄────────
  • A página nunca chama api.bayle.ai diretamente. Toda chamada vai para as rotas do servidor do próprio chat.
  • Sua key fica num cookie HttpOnly, Secure, SameSite=Strict. Os scripts da página não conseguem lê-la; o navegador só a envia de volta ao servidor do próprio chat.
  • Histórico de conversas, mídia gerada e configurações ficam no IndexedDB do seu navegador, nunca no servidor. A key nunca é guardada ali.
Lugar O quê O que nunca guarda
API da Bayle Nada entre requisições Prompts, respostas, mídia, keys
Logs da API Método, caminho, status, duração, ID de requisição; motivos de falha Cabeçalhos, corpos, prompts, keys
Logs de acesso da hospedagem URL, status, latência, IP do cliente, user agent Corpos
Registros de conta Saldo e plano da sua key, indexados por um hash de mão única da key A key em si
Seu navegador (chat web) Conversas, mídia e configurações no IndexedDB; a key num cookie A key no IndexedDB
Infraestrutura do modelo Depende do nível de privacidade do modelo Veja Privacidade

GET /models lista o catálogo. Filtre com ?type=: text, code, embedding, image, video e outros. Cada item traz um id para passar de volta como model, um type e um objeto model_spec com os recursos, limites e o nível de privacidade do modelo.

Só modelos de texto, embedding, imagem e vídeo têm endpoints aqui. O catálogo lista outros tipos também, mas não há como chamá-los.

Os preços da Bayle são em reais. A aba Modelos mostra o preço de cada modelo por 100K tokens para texto, por milhão para embeddings, por imagem ou por vídeo, em reais convertidos de dólares por uma cotação USD/BRL ao vivo no seu navegador, ou em dólares se você trocar a moeda no cabeçalho. O consumo desconta do saldo da sua key; quando ele acaba, as requisições falham com 402 até você adicionar mais.

O catálogo muda conforme modelos entram e saem. Consulte os identificadores em vez de fixar uma lista no código, e trate-os como strings opacas. Veja Modelos.