Um endpoint. Todos os modelos.
Formato compatível com OpenAI. Se você já usa a SDK da OpenAI, o código não muda — só a baseURL e a chave.
1. Crie sua chave
No painel, em Chaves de API, clique em Criar chave. O segredo aparece uma única vez — copie antes de sair da tela.
2. Faça a primeira chamada
curl https://api.novality.com.br/v1/chat/completions \ -H "Authorization: Bearer nv_live_SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-fable-5", "messages": [{"role": "user", "content": "Olá"}] }'A resposta vem no formato da OpenAI:
{ "id": "chatcmpl_a0398abf7ed143df89a5", "object": "chat.completion", "model": "claude-fable-5", "choices": [{ "index": 0, "message": { "role": "assistant", "content": "Olá! Como posso ajudar?" }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 12, "completion_tokens": 8, "total_tokens": 20 }}3. Use a SDK da OpenAI
Instale openai e aponte a base_url para a Novality. O resto do seu código não muda.
from openai import OpenAIimport os client = OpenAI( base_url="https://api.novality.com.br/v1", api_key=os.environ["NOVALITY_API_KEY"],) resposta = client.chat.completions.create( model="claude-fable-5", messages=[{"role": "user", "content": "Olá"}],)print(resposta.choices[0].message.content)import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.novality.com.br/v1", apiKey: process.env.NOVALITY_API_KEY,}); const resposta = await client.chat.completions.create({ model: "claude-fable-5", messages: [{ role: "user", content: "Olá" }],});console.log(resposta.choices[0].message.content);4. Streaming
Envie stream: true e receba os tokens incrementalmente em SSE:
stream = client.chat.completions.create( model="claude-fable-5", messages=[{"role": "user", "content": "Escreva um poema"}], stream=True,) for pedaco in stream: delta = pedaco.choices[0].delta.content or "" print(delta, end="", flush=True)data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"Olá"}}]}data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"!"}}]}data: {"object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop"}]}data: [DONE]Para receber a contagem de tokens no fim do stream, peça stream_options: { include_usage: true }:
stream = client.chat.completions.create( model="claude-fable-5", messages=[{"role": "user", "content": "Escreva um poema"}], stream=True, stream_options={"include_usage": True},) for pedaco in stream: if pedaco.usage: print("\n", pedaco.usage.prompt_tokens, "->", pedaco.usage.completion_tokens) else: print(pedaco.choices[0].delta.content or "", end="", flush=True)Sem include_usage a API não manda o bloco de uso — é o comportamento padrão da OpenAI. O consumo continua sendo registrado no painel de Uso da API de qualquer forma.
Modelos disponíveis
Consulte GET /v1/models para pegar os nomes exatos:
curl https://api.novality.com.br/v1/models \ -H "Authorization: Bearer nv_live_SUA_CHAVE"- claude-fable-5
- claude-fable-5.1
- claude-opus-5
- claude-opus-5.5
- deepseek-v4-pro-0813
- gpt-5.5
- gpt-5.5-pro
- gpt-5.6-luna
Erros
Toda resposta de erro segue o formato { error: { message, type, code, param } }, com o code estável para tratar por código.
| HTTP | code | Quando acontece |
|---|---|---|
| 401 | missing_api_key | Falta o header Authorization: Bearer |
| 401 | invalid_api_key | A chave não existe |
| 401 | revoked_api_key | A chave foi revogada |
| 401 | expired_api_key | A chave expirou |
| 402 | subscription_inactive | Assinatura inativa |
| 403 | model_disabled | O modelo não está liberado |
| 404 | model_not_found | O nome do modelo não existe |
| 413 | payload_too_large | Corpo acima de 1 MiB |
| 429 | rate_limit_exceeded | Estourou o RPM (veja Retry-After) |
| 429 | concurrency_limit | Muitos streams abertos |
| 503 | upstream_unavailable | Provedor fora do ar |
| 504 | timeout | Passou do tempo máximo |
Limites
Toda requisição passa por um controle por chave e um global antes de consumir o provedor. Ao estourar, a resposta vem com Retry-After:
- Requisições por minuto (chave)
- 60
- Requisições por minuto (conta interna)
- 120
- Requisições por minuto (global)
- 2.400
- Pico em rajada
- 10
- Streams simultâneos (chave)
- 3
- Tamanho máximo do corpo
- 1 MiB
- Tempo máximo de resposta
- 120 s
Segurança
- ✓A chave fica no servidor. Nunca exponha no frontend do seu app nem versione no git.
- ✓Use uma chave por ambiente (produção, staging) para revogar sem quebrar nada.
- ✓Gire a chave se ela vazar: revogue e crie outra na hora.