Documentação
API SummitCli
everything que você precisa para integrar: autenticação por API Key, inferência com streaming SSE, formatos de erro e a referência completa de endpoints.
Primeiros passos
O essencial em 30 segundos
Consulte os modelos disponíveis (sem autenticação) e faça a primeira chamada com sua API Key.
# 1. Descubra os modelos (não exige autenticação)curl https://api.summitcli.tech/api/v1/models# 2. Faça uma chamada com sua API Keycurl https://api.summitcli.tech/api/v1/chat/completions \ -H 'Authorization: Bearer sk-summit-...' \ -H 'Content-Type: application/json' \ -d '{ "model": "SLUG_DO_MODELO", "messages": [{"role": "user", "content": "Olá"}] }'Autenticação
Dois mecanismos — não misture
A API usa dois mecanismos diferentes, e cada grupo de endpoints exige um deles. Este é o ponto que mais gera erro de integração.
| Endpoint | O que usar | De um script? |
|---|---|---|
| /api/v1/billing/balance | sessão + Origin | ❌ Não |
| /api/v1/billing/subscription | sessão + Origin | ❌ Não |
| /api/v1/keys | sessão + Origin | ❌ Não |
| /api/v1/me | sessão + Origin | ❌ Não |
| /api/v1/models | pública | ✅ Sim |
| /api/v1/chat/completions | API Key | ✅ Sim |
| /api/v1/keys | sessão + Origin | ❌ Não |
| /api/v1/preferences/locale | Origin | ❌ Não |
| /api/v1/billing/subscription | sessão + Origin | ❌ Não |
| /api/v1/keys | sessão + Origin | ❌ Não |
A regra prática
Anatomia de uma API Key
sk-summit-3kJ9xQmR2vB8nT5wL0pZaYdHcE4uFgN1sIoO7rCjXl └─┬───┘└────────────┬─────────────┘ │ └─ 32 bytes aleatórios em base64url └─ prefixo fixo
- •Criada em POST /api/v1/keys, pelo próprio usuário, sem fila de aprovação.
- •O segredo em texto puro aparece uma única vez, na resposta da criação. Só o hash SHA-256 fica no banco — não há endpoint para recuperá-lo.
- •Depois você só vê a máscara sk-summit-abc…wxyz. A revogação em DELETE /api/v1/keys é imediata e definitiva.
Uma chave por ambiente
Chaves de API
Criando sua primeira chave
A criação acontece no painel autenticado (cookie de sessão), não por API Key:
curl -X POST https://api.summitcli.tech/api/v1/keys \ -H 'Content-Type: application/json' \ -H 'Origin: https://summitcli.tech' \ -b 'summit_session=SEU_COOKIE_DE_SESSAO' \ -d '{"name":"Meu backend"}'Para restringir a chave a modelos específicos, mande modelIds (UUIDs que saem de GET /api/v1/models). Omitir significa que ela vale para todos os modelos ativos.
Guarde o secretKey agora
Gateway
Inferência
POST /api/v1/chat/completions é o endpoint principal. Exige chave ativa, um modelo liberado para ela e um plano recorrente ativo.
| Campo | Tipo | Padrão | Limite |
|---|---|---|---|
| model | string | — | obrigatório, 1–128 chars |
| messages | array | — | obrigatório, 1–200 itens |
| messages[].role | enum | — | system · user · assistant |
| messages[].content | string | — | 1–200.000 chars |
| stream | boolean | false | — |
| temperature | number | 0.7 | — |
| max_tokens | integer | 1024 | — |
Corpos acima de 1 MB são recusados com 413.
Streaming
Streaming (SSE)
Com "stream": true a resposta vem como text/event-stream e os tokens chegam conforme são gerados, em vez de tudo de uma vez.
import osfrom openai import OpenAIclient = OpenAI( api_key=os.environ["SUMMIT_API_KEY"], base_url="https://api.summitcli.tech/v1",)stream = client.chat.completions.create( model="SLUG_DO_MODELO", messages=[{"role": "user", "content": "Escreva um haiku sobre TypeScript"}], stream=True,)for chunk in stream: delta = chunk.choices[0].delta.content if delta: print(delta, end="", flush=True)Descarte a linha data: [DONE]
Erros
Tratamento de erros
O gateway e o painel usam dois formatos diferentes, de propósito. O gateway segue o OpenAI; o painel usa um envelope próprio.
gateway /chat/completions · /models
{
"error": {
"message": "API key inválida.",
"type": "invalid_request_error"
}
}painel /keys · /billing/* · /me
{
"success": false,
"error": {
"code": "SUBSCRIPTION_REQUIRED",
"message": "Você ainda não possui um plano ativo."
},
"meta": { "timestamp": "..." }
}Se seu código normaliza erros, trate os dois. O code do envelope é estável e serve para lógica de controle; a mensagem é para humanos e pode mudar.
| Status | code | Causa | O que fazer |
|---|---|---|---|
| 400 | VALIDATION_ERROR | JSON malformado ou campo inválido | Confira os tipos e limites da tabela |
| 401 | UNAUTHORIZED | Chave ausente, inválida, revogada ou sem permissão no modelo | Verifique o header Authorization e o prefixo sk-summit- |
| 402 | SUBSCRIPTION_REQUIRED | Chave válida, mas sem plano recorrente ativo | Ative um plano — não é bug, é assinatura |
| 403 | FORBIDDEN | Saldo insuficiente ou modelo indisponível para a chave | Recarregue a carteira ou libere o modelo |
| 413 | — | Corpo acima de 1 MB | Reduza o histórico ou o conteúdo das mensagens |
| 429 | RATE_LIMITED | Limite de requisições excedido (por IP e por chave) | Backoff exponencial |
import timeimport urllib.errorMAX_TENTATIVAS = 5for tentativa in range(MAX_TENTATIVAS): try: return chamar_api() except urllib.error.HTTPError as erro: # 429 é transiente. 401/402/403 são permanentes: retry só gasta cota. if erro.code != 429 or tentativa == MAX_TENTATIVAS - 1: raise time.sleep(2 ** tentativa) # 1s, 2s, 4s, 8s...Não faça retry cego
Referência
Todos os endpoints
Clique em um endpoint para ver a descrição.
Antes de produção
Checklist de produção
- A chave está em variável de ambiente, nunca no código ou no git
- Uma chave por ambiente (prod / staging), para revogação independente
- Você consulta GET /api/v1/models em vez de assumir o slug do modelo
- Você trata 402 como "precisa de assinatura", não como bug
- Você faz backoff em 429; não retenta em 401/402/403
- Em streaming, você descarta a linha data: [DONE]
- Assinatura ativa antes de tráfego real — 402 não gasta o saldo, mas não gera resposta
- Saldo monitorado — saldo zerado vira 403 no meio do fluxo