API do Keural
Envie requisições no formato OpenAI Chat Completions com uma chave de API.
Chame os modelos cadastrados no Keural no formato OpenAI Chat Completions.
A URL base tem o formato https://<seu domínio público de API>/llm/v1. O domínio público da API varia de acordo com o ambiente; confirme com o seu administrador.
| Método | Caminho | Descrição |
|---|---|---|
POST | /llm/v1/chat/completions | Cria uma conclusão de chat (com suporte a streaming) |
GET | /llm/v1/models | Lista os modelos conectados à chave |
GET | /llm/v1/models/{model} | Obtém informações sobre um modelo conectado à chave |
Embeddings, geração de imagens, voz e a API Responses não são suportados, e as requisições para esses caminhos retornam 404.
Fluxo de uso
| Etapa | O que fazer |
|---|---|
| 1. Emitir a chave | Em Configurações → API, escolha um modelo e obtenha uma chave. Copie o ID do modelo e a chave. |
| 2. Conectar o cliente | Informe a URL base, a chave de API e o ID do modelo no aplicativo ou no código. |
| 3. Usar e gerenciar | Na mesma tela, consulte o uso e, se necessário, emita novamente ou revogue a chave. |
Pré-requisitos
| Item | Detalhes |
|---|---|
| Conta do Keural | Conta do Keural com login |
| Menu de API | Se API não aparecer em Configurações, solicite ao administrador a ativação do recurso. |
| Permissão de membro da organização | Para emitir chaves em um workspace da organização, o administrador da organização precisa permitir. Consulte Permissão de API dos membros da organização. |
| URL base | Endereço público da API informado pelo administrador |
| Cliente | Aplicativo ou SDK compatível com OpenAI API |
Emitir uma chave de API
- No menu da conta, abra Configurações → API. Nos apps de desktop e celular, o item fica na seção Ferramentas.
- Na aba API keys, escolha o workspace ao qual a chave pertence (pessoal ou da organização) e o Model ID.
- Se necessário, defina a New key expiration (optional, Korea time). Se deixar em branco, a chave não expira até ser revogada.
- Clique em Issue key e use Copy key para copiar a chave e guardá-la. O texto completo da chave é exibido somente nesse momento.
- A chave fica vinculada ao workspace escolhido e a um modelo. O uso é atribuído a quem emitiu a chave.
- Cada combinação de workspace e modelo tem apenas uma chave. Para obter uma nova, reemita (Rotate) ou revogue (Revoke) a chave existente.
- Se perder a chave, reemita-a. Ao reemitir, a chave anterior deixa de funcionar imediatamente.
- Se não houver modelos disponíveis para emissão, verifique com o administrador a configuração de publicação dos modelos, o plano e a permissão de API da organização.
Permissão de API dos membros da organização
Esta permissão é destinada a proprietários e administradores da organização. Para que um membro emita chaves em um workspace da organização, o administrador precisa liberá-la antes. Para todos os membros, o padrão é bloqueado.
Gerenciamento da organização → Organization API é composto pelas três seções a seguir. Se o menu não aparecer, a função de API está desativada ou a sua conta não tem permissão de administração da organização.
| Seção | O que faz |
|---|---|
| API permissions by user | Ativa ou desativa a permissão de API de cada membro. |
| Issued keys | Mostra o estado das chaves emitidas na organização e permite revogá-las. Não é possível ver o texto das chaves. |
| API usage | Mostra as requisições e o uso de tokens das chaves emitidas na organização. |
| Ação | Resultado |
|---|---|
| Ativar Allow API access | O membro pode emitir chaves no workspace da organização. |
| Desativar Allow API access | Bloqueia novas emissões e as chamadas com chaves existentes. As chaves emitidas não são excluídas automaticamente; se necessário, revogue-as em Issued keys. |
Quando um membro sai ou é removido da organização, as chaves que recebeu nela são revogadas automaticamente.
Conectar a um cliente
Informe os três valores a seguir em aplicativos compatíveis com OpenAI API (clientes de chat, extensões de IDE, ferramentas de automação etc.).
| Valor | O que informar | Nome do campo por aplicativo |
|---|---|---|
| Base URL | O endereço público da API informado pelo administrador (…/llm/v1) | Base URL, API Base, Endpoint, Host |
| API Key | A chave emitida (sem espaços no início ou no fim) | API Key, Token, Secret Key, Authorization |
| Model | O Model ID da tela de emissão. Deve ser exatamente igual ao modelo conectado à chave | Model, Model ID, Model Name |
- Nas configurações do aplicativo, adicione uma conexão compatível com OpenAI (Connection).
- Informe a Base URL e a API Key e salve.
- Escolha um modelo na lista. A lista mostra somente o modelo conectado à chave.
- Envie uma mensagem curta e confirme a resposta.
O formato das requisições é o seguinte.
| Tipo | Conteúdo |
|---|---|
| Requisição de chat | POST <Base URL>/chat/completions |
| Consulta de modelos | GET <Base URL>/models |
| Cabeçalho de autenticação | Authorization: Bearer <chave emitida> |
| Cabeçalho de conteúdo | Content-Type: application/json |
Primeira requisição
export KEURAL_API_KEY='sua_chave_emitida'
export KEURAL_BASE_URL='https://<seu-domínio-de-api>/llm/v1'
export MODEL_ID='ID_do_modelo_na_tela_de_emissão'
curl "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Olá.\"}]}"O model do corpo da requisição deve ser o mesmo modelo conectado à chave. Se houver prefixo de caminho, como provider/ID_do_modelo, compara-se o trecho após a última /. Se for diferente, a API retorna 403. A resposta sempre traz no campo model o ID do modelo da chave.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["KEURAL_API_KEY"],
base_url=os.environ["KEURAL_BASE_URL"],
)
res = client.chat.completions.create(
model=os.environ["MODEL_ID"],
messages=[{"role": "user", "content": "Olá."}],
)
print(res.choices[0].message.content)Campos de requisição aceitos
A API aceita somente os 18 campos de nível superior abaixo. Se você enviar outros campos, a resposta é 400. Campos opcionais com valor null são tratados como não enviados.
| Campo | Regra |
|---|---|
model | Obrigatório. O ID do modelo da chave |
messages | Obrigatório. De 1 a 4.096 itens |
stream · stream_options | stream_options só é enviado com stream: true. Suporta include_usage. |
tools | Até 128. O nome da função usa [A-Za-z0-9_-], de 1 a 64 caracteres |
tool_choice | none · auto · required · uma função específica. required exige que haja tools. |
parallel_tool_calls | Se o modelo não suportar, a resposta é 400 |
response_format | text · json_object · json_schema |
max_tokens · max_completion_tokens | Envie apenas um dos dois. Se não enviar, o valor é 4.096 (ou o limite do modelo, se for menor). Se ultrapassar o limite do modelo, a resposta é 400. |
temperature | De 0 a 2. Se o modelo não suportar, a resposta é 400 |
top_p | De 0 a 1 |
frequency_penalty · presence_penalty | De -2 a 2 |
stop | Uma string ou um array de até 4 itens |
seed | Inteiro |
user | Até 256 caracteres |
n | Somente 1 |
Mensagens
| Papel | Campos aceitos |
|---|---|
system · developer | content, name |
user | content (string ou array de partes de texto e imagem), name |
assistant | content, name, refusal, tool_calls |
tool | content, tool_call_id |
- Uma mensagem
toolresponde uma única vez a cadaiddostool_callsanteriores. - Partes de imagem (
image_url) só são incluídas em mensagensuserde modelos que aceitam imagens. Use um endereçohttpouhttps, ou um data URI base64 de PNG, JPEG, GIF ou WebP. Odetailpode serauto,lowouhigh.
Corpo
| Item | Limite |
|---|---|
| Content-Type | application/json |
| Tamanho | 1 MiB |
| Estrutura JSON | Um único objeto de nível superior, profundidade de aninhamento de até 64, sem chaves duplicadas |
| Tempo da requisição | Máximo de 600 segundos |
Se você descumprir as regras do corpo, a resposta é 400 e param é body.
Streaming
Com "stream": true na requisição, a resposta é enviada por SSE. Os fragmentos são enviados como eventos data: ..., e no final é enviado data: [DONE]. Com "stream_options": {"include_usage": true}, um fragmento com o uso de tokens é enviado adicionalmente logo antes de [DONE].
Com include_usage, todos os fragmentos trazem usage: null, e o último fragmento de uso tem choices como array vazio. Respostas sem streaming só trazem usage quando os tokens de entrada e de saída foram confirmados.
O id da resposta tem o formato chatcmpl-<x-request-id>. Todas as respostas incluem o cabeçalho x-request-id.
Se houver erro durante o streaming, um evento data: com o JSON do erro é enviado e a conexão é encerrada sem [DONE]. Se um fragmento ultrapassar 1 MiB ou a resposta ultrapassar 16 MiB, a conexão termina com 503.
curl -N "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Olá.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true}}"Limites de uso
As requisições têm limites por usuário, organização e modelo: número de requisições simultâneas, requisições por minuto (RPM) e tokens por minuto (TPM). Os valores reais variam conforme o ambiente.
Os tokens por minuto são descontados antecipadamente ao receber a requisição. A entrada é calculada em 1 token a cada 4 caracteres em inglês, 1 token por caractere nos demais casos, e 2.000 tokens por imagem. A saída é descontada conforme max_tokens (máximo de 4.096), então definir o limite de saída apenas no necessário aumenta a folga dentro do limite.
Código 429 | Causa | Retry-After |
|---|---|---|
rate_limit_exceeded | RPM, TPM ou número de requisições simultâneas excedido | 60 segundos para RPM e TPM; 1 segundo para simultâneas |
api_busy | Capacidade de processamento do servidor excedida | Não há. Aguarde um pouco e tente novamente. |
upstream_rate_limit | Limite do provedor do modelo excedido | Não há |
Gerenciamento de chaves
Em Configurações → API → API keys, consulte o estado das chaves (válida · expirada · revogada) e reemita ou revogue.
As chaves são strings de 51 caracteres que começam com krl_llm_. Em cada workspace de emissão, só há uma chave; se já houver uma, ela é reemitida. A data de expiração só pode ser definida a partir de hoje.
| Ação | Resultado | O que considerar |
|---|---|---|
| Reemitir (Rotate) | Uma nova chave é gerada. | A chave anterior fica inválida imediatamente. Atualize também a chave nos aplicativos conectados. |
| Revogar (Revoke) | A chave é bloqueada imediatamente. | Use quando houver suspeita de exposição da chave. Uma chave revogada não pode ser restaurada. |
Consulta de uso
As requisições da API e o uso de tokens podem ser consultados nos dois locais a seguir.
| Local | Conteúdo |
|---|---|
| Configurações → API → API usage | Uso das chaves emitidas por você no workspace atual |
| Gerenciamento da organização → Organization API, seção API usage | Uso de todas as chaves emitidas na organização (proprietários e administradores da organização) |
Condições da consulta
| Condição | Descrição |
|---|---|
| Hora de início · Hora de fim | Horário de Coreia. A hora de início é incluída e a de fim não. Se deixadas em branco, são exibidos os últimos 7 dias. A consulta abrange no máximo 90 dias por vez. |
| Model ID | Consulta somente as requisições de um modelo específico. Se deixado em branco, consulta todos. |
| Status da requisição | Escolha entre Todos · Em andamento · Concluída · Com falha · Interrompida · Não confirmada. |
Defina as condições e clique em Consultar. Para incluir requisições recentes, clique em Atualizar.
Valores exibidos na tela
- Período de consulta aplicado: o período que foi realmente consultado. Se a hora de início ou de fim ficou em branco, ou se o período passou de 90 dias, é exibido o período ajustado.
- Número de requisições e os totais de tokens de entrada · tokens de saída · tokens totais: somam apenas valores confirmados. Tokens não confirmados são exibidos como Não confirmado.
- Lista de requisições: cada requisição exibe horário, Model ID, status e tokens de entrada, saída e totais. São exibidas 20 por página, navegáveis com Anterior e Próximo.
Ao clicar em Detalhes da requisição em uma linha, são exibidos os valores a seguir.
| Item | Descrição |
|---|---|
| ID da requisição | Valor informado ao entrar em contato com o suporte |
| Modo de resposta | Streaming ou resposta comum |
| Status de confirmação do uso | Confirmado · Parcialmente confirmado · Não confirmado |
| Horário de término · Tempo de resposta (ms) | Quando a requisição terminou e quanto tempo levou |
| Leitura de cache · Criação de cache · Tokens de raciocínio | Exibidos somente quando o modelo retorna esses valores |
Requisições em streaming registram o uso mesmo sem stream_options.include_usage. Se uma requisição for interrompida no meio, ela pode ficar como Parcialmente confirmado ou Não confirmado.
Formato de erro
Os erros são retornados no formato compatível com OpenAI.
{
"error": {
"message": "Descrição do erro legível para pessoas",
"type": "authentication_error",
"code": "invalid_api_key",
"param": null
}
}O type é definido pelo código de status, e o code indica a causa.
| Status | type | code | Causa |
|---|---|---|---|
400 | invalid_request_error | invalid_request | Campo, valor ou regra do corpo inválidos. param indica o campo com problema |
400 | invalid_request_error | upstream_rejected_request | O provedor do modelo rejeitou a requisição |
401 | authentication_error | invalid_api_key | Formato de chave inválido, chave ausente, expirada, revogada ou reemitida, ou mais de um cabeçalho Authorization |
403 | permission_error | api_disabled | A função de API do Keural está desativada |
403 | permission_error | model_api_disabled | A publicação do modelo para API está desativada |
403 | permission_error | model_not_allowed | model diferente do modelo da chave, ou membro sem permissão de API |
404 | invalid_request_error | not_found | Caminho inexistente |
405 | invalid_request_error | method_not_allowed | Método incorreto. O cabeçalho Allow indica os métodos permitidos |
429 | rate_limit_error | Tabela de Limites de uso | Limite excedido |
503 | server_error | upstream_timeout | A resposta não foi concluída em 600 segundos |
503 | server_error | invalid_upstream_response | Formato de resposta anormal do provedor, ou fluxo acima do tamanho permitido |
503 | server_error | dependency_unavailable · unsupported_provider | Problema interno temporário. Entre em contato com o suporte informando o x-request-id |
Solução de problemas
| Sintoma | Código de resposta | O que verificar |
|---|---|---|
| A lista de modelos está vazia ou a conexão falha | 404 · 405 | Se a Base URL termina em …/llm/v1 |
| A autenticação falha | 401 | Erros de digitação ou espaços na chave; se a chave expirou, foi revogada ou reemitida |
| A conexão funciona, mas o modelo não pode ser usado | 403 | Se o Model ID é igual ao da chave e a permissão de API da organização |
| A resposta demora ou falha de vez em quando | 429 | Limites de uso |
| Não há resposta por um momento | 5xx | Tente novamente mais tarde |
| O uso não aparece ou não confere com o real | — | O período da consulta e o workspace ao qual a chave pertence |
Se o problema não for resolvido, entre em contato com o administrador e informe os dados a seguir. Não envie o texto da chave nem o conteúdo dos prompts.
- Horário da ocorrência
- ID do modelo usado
- Nome e versão do aplicativo cliente
- Valor de
x-request-iddo cabeçalho de resposta - Mensagem de erro exibida na tela