⏱️ Leitura: 25 minutos · 🎯 Público: desenvolvedores, arquitetos de integração, squads que vão incorporar a Cortex em aplicações internas.
A Cortex foi projetada para ser uma plataforma, não um silo. Sua inteligência — agentes, base de conhecimento, ferramentas — fica à disposição das suas aplicações através de APIs REST robustas e padrão de mercado, permitindo desde chatbots em apps internos até automações críticas em pipelines de negócio.
Esta página é a referência técnica para integrar a Cortex via código.
A Cortex expõe três famílias de APIs:
| Família | Propósito | Padrão |
|---|---|---|
| Chat Completions | Interagir com agentes/modelos (chat, geração, embedding) | OpenAI-compatible — você pode usar qualquer SDK compatível |
| Admin/Workspace | Gerenciar agentes, bases de conhecimento, usuários, permissões | REST próprio |
| Assets | Upload de arquivos e mídia | REST próprio (multipart) |
Assumindo a instância https://cortex.suaempresa.com:
| Endpoint | URL |
|---|---|
| Chat Completions (OpenAI-compatible) | POST /api/chat/completions |
| Modelos disponíveis | GET /api/models |
| Embeddings | POST /api/embeddings |
| Knowledge (RAG) | /api/v1/knowledge + /api/v1/files |
| Agentes | /api/v1/models (admin) |
| Usuários | /api/v1/users (admin) |
| Upload de assets | POST /u (multipart) |
💡 Compatibilidade OpenAI: o endpoint de chat segue a especificação da OpenAI. Qualquer biblioteca que funcione com OpenAI (
openai,langchain,llamaindex,instructor,promptfooetc.) funciona apontando para a Cortex ao trocar abase_urle aapi_key.
Toda chamada à API é autenticada via API Key no header Authorization: Bearer <api_key>.
curl https://cortex.suaempresa.com/api/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-cortex-abcd1234..." \
-d '{
"model": "claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Olá!"}]
}'
| Escopo | Permite |
|---|---|
chat |
Chamar agentes/modelos via chat completions |
embeddings |
Gerar embeddings |
knowledge.read |
Ler coleções de conhecimento |
knowledge.write |
Criar/editar coleções e arquivos |
admin.models |
Gerenciar agentes |
admin.users |
Gerenciar usuários |
admin.full |
Acesso administrativo total |
O endpoint mais usado. Permite conversar com qualquer modelo ou agente disponível.
POST /api/chat/completions
{
"model": "claude-sonnet-4-6",
"messages": [
{"role": "system", "content": "Você é um assistente jurídico."},
{"role": "user", "content": "Me dê 3 pontos de atenção em um NDA."}
],
"temperature": 0.3,
"max_tokens": 800
}
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1713730800,
"model": "claude-sonnet-4-6",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "1. Duração e vigência..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 45,
"completion_tokens": 287,
"total_tokens": 332
}
}
from openai import OpenAI
client = OpenAI(
api_key="sk-cortex-...",
base_url="https://cortex.suaempresa.com/api"
)
resposta = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[
{"role": "system", "content": "Você é um assistente jurídico."},
{"role": "user", "content": "Me dê 3 pontos de atenção em um NDA."}
],
temperature=0.3,
max_tokens=800
)
print(resposta.choices[0].message.content)
print(f"Custo: {resposta.usage.total_tokens} tokens")
import requests, os
resp = requests.post(
"https://cortex.suaempresa.com/api/chat/completions",
headers={
"Authorization": f"Bearer {os.environ['CORTEX_API_KEY']}",
"Content-Type": "application/json"
},
json={
"model": "claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Olá!"}]
},
timeout=60
)
resp.raise_for_status()
data = resp.json()
print(data["choices"][0]["message"]["content"])
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.CORTEX_API_KEY,
baseURL: "https://cortex.suaempresa.com/api",
});
const resposta = await client.chat.completions.create({
model: "claude-sonnet-4-6",
messages: [
{ role: "system", content: "Você é um assistente jurídico." },
{ role: "user", content: "Me dê 3 pontos de atenção em um NDA." }
],
temperature: 0.3,
});
console.log(resposta.choices[0].message.content);
curl -s https://cortex.suaempresa.com/api/chat/completions \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [
{"role": "user", "content": "Olá"}
]
}' | jq '.choices[0].message.content'
$headers = @{
"Authorization" = "Bearer $env:CORTEX_API_KEY"
"Content-Type" = "application/json"
}
$body = @{
model = "claude-sonnet-4-6"
messages = @(
@{ role = "user"; content = "Olá" }
)
} | ConvertTo-Json
$resp = Invoke-RestMethod `
-Uri "https://cortex.suaempresa.com/api/chat/completions" `
-Method Post -Headers $headers -Body $body
$resp.choices[0].message.content
| Parâmetro | Tipo | Descrição |
|---|---|---|
model |
string | ID do modelo ou agente |
messages |
array | Histórico da conversa (role: system / user / assistant / tool) |
temperature |
number 0-2 | Criatividade (padrão 1) |
top_p |
number 0-1 | Diversidade (padrão 1) |
max_tokens |
integer | Teto de tokens na resposta |
stream |
boolean | Streaming SSE |
stop |
string/array | Sequências que param a geração |
frequency_penalty |
number -2 a 2 | Penaliza repetição |
presence_penalty |
number -2 a 2 | Incentiva novos tópicos |
seed |
integer | Reprodutibilidade (quando suportado) |
response_format |
object | Ex.: {"type":"json_object"} |
tools |
array | Ferramentas disponíveis (function calling) |
tool_choice |
string/object | Como escolher ferramenta |
user |
string | Identificador do usuário final (para logs) |
Agentes criados no Espaço de Trabalho da Cortex têm um model_id próprio (ex.: revisor-contratos-senior). Use-o no campo model:
resposta = client.chat.completions.create(
model="revisor-contratos-senior", # ← ID do seu agente
messages=[
{"role": "user", "content": "Analise este contrato: [texto]"}
]
)
O agente traz consigo: prompt do sistema, base de conhecimento vinculada, ferramentas habilitadas, parâmetros pré-configurados. Você só envia a mensagem do usuário.
Para respostas longas, use streaming (Server-Sent Events) — o texto vai sendo entregue conforme é gerado, como em chats ao vivo.
Basta setar stream: true.
stream = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Escreva um texto de 500 palavras sobre LGPD"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
const stream = await client.chat.completions.create({
model: "claude-sonnet-4-6",
messages: [{ role: "user", content: "Escreva um texto longo" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
curl -N https://cortex.suaempresa.com/api/chat/completions \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"stream": true,
"messages": [{"role": "user", "content": "Olá"}]
}'
Cada chunk vem como evento SSE:
data: {"choices":[{"delta":{"content":"Olá"}}]}
data: {"choices":[{"delta":{"content":"!"}}]}
data: [DONE]
Modelos com function calling podem invocar ferramentas declaradas por você.
ferramentas = [
{
"type": "function",
"function": {
"name": "consultar_cliente",
"description": "Consulta dados de cliente pelo CNPJ no CRM.",
"parameters": {
"type": "object",
"properties": {
"cnpj": {
"type": "string",
"description": "CNPJ do cliente (apenas números)"
}
},
"required": ["cnpj"]
}
}
}
]
resposta = client.chat.completions.create(
model="gpt-5",
messages=[{"role": "user", "content": "Me diga sobre o cliente com CNPJ 12345678000190"}],
tools=ferramentas,
)
A resposta vem com tool_calls:
{
"choices": [{
"message": {
"role": "assistant",
"tool_calls": [{
"id": "call_abc",
"type": "function",
"function": {
"name": "consultar_cliente",
"arguments": "{\"cnpj\": \"12345678000190\"}"
}
}]
}
}]
}
Você então executa a ferramenta do seu lado e devolve o resultado:
# 1. Executa sua função
resultado = consultar_cliente(cnpj="12345678000190") # sua implementação
# 2. Chama novamente incluindo o resultado
resposta_final = client.chat.completions.create(
model="gpt-5",
messages=[
{"role": "user", "content": "Me diga sobre o cliente..."},
resposta.choices[0].message, # tool_call do modelo
{
"role": "tool",
"tool_call_id": "call_abc",
"content": json.dumps(resultado)
}
],
tools=ferramentas,
)
print(resposta_final.choices[0].message.content)
# "O cliente ACME Ltda (CNPJ 12.345.678/0001-90) está ativo desde..."
╔══════════════════════════════════════════╗
║ 1. USUÁRIO faz pergunta ║
║ → envia para o modelo ║
╚══════════════════════════════════════════╝
│
▼
╔══════════════════════════════════════════╗
║ 2. MODELO decide chamar ferramenta ║
║ → retorna tool_calls ║
╚══════════════════════════════════════════╝
│
▼
╔══════════════════════════════════════════╗
║ 3. SUA APLICAÇÃO executa a ferramenta ║
║ → retorna resultado ║
╚══════════════════════════════════════════╝
│
▼
╔══════════════════════════════════════════╗
║ 4. MODELO recebe o resultado ║
║ → gera resposta final (ou chama ║
║ mais ferramentas) ║
╚══════════════════════════════════════════╝
│
▼
╔══════════════════════════════════════════╗
║ 5. USUÁRIO recebe a resposta ║
╚══════════════════════════════════════════╝
Pode haver múltiplas iterações antes de o modelo ter a resposta final.
Gerencie coleções de conhecimento e arquivos programaticamente — útil para pipelines de ingestão contínua.
curl https://cortex.suaempresa.com/api/v1/knowledge \
-H "Authorization: Bearer $CORTEX_API_KEY"
curl -X POST https://cortex.suaempresa.com/api/v1/knowledge \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Políticas de RH 2026",
"description": "Todas as políticas vigentes em 2026",
"access_control": null
}'
import requests
# 1. Upload do arquivo
files = {"file": open("politica-home-office.pdf", "rb")}
upload = requests.post(
"https://cortex.suaempresa.com/api/v1/files/",
headers={"Authorization": f"Bearer {API_KEY}"},
files=files
)
file_id = upload.json()["id"]
# 2. Aguardar processamento
import time
while True:
status = requests.get(
f"https://cortex.suaempresa.com/api/v1/files/{file_id}/process/status",
headers={"Authorization": f"Bearer {API_KEY}"}
).json()
if status["status"] == "completed":
break
time.sleep(2)
# 3. Adicionar à coleção
requests.post(
f"https://cortex.suaempresa.com/api/v1/knowledge/{colecao_id}/file/add",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={"file_id": file_id}
)
⚠️ Importante: o processamento de arquivos é assíncrono. Use o polling no status antes de referenciar o arquivo em uma coleção. Ignorar isso causa "empty content" silencioso.
Via API de chat, você pode injetar contexto ad-hoc:
resposta = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Qual a política de férias?"}],
extra_body={
"files": [
{"type": "collection", "id": "colecao_id_aqui"}
]
}
)
A Cortex fará RAG automaticamente usando a coleção indicada.
Crie, edite e liste agentes programaticamente — útil para CI/CD de configurações.
curl https://cortex.suaempresa.com/api/models \
-H "Authorization: Bearer $CORTEX_API_KEY"
import requests
payload = {
"id": "revisor-contratos-senior",
"name": "Revisor de Contratos Sênior",
"base_model_id": "claude-sonnet-4-6",
"params": {
"system": "Você é um(a) advogado(a) sênior...",
"temperature": 0.2,
"max_tokens": 2000
},
"meta": {
"description": "Pré-análise de contratos",
"capabilities": {
"vision": True,
"file_upload": True
},
"tags": [{"name": "Jurídico"}]
}
}
requests.post(
"https://cortex.suaempresa.com/api/v1/models/create",
headers={
"Authorization": f"Bearer {ADMIN_API_KEY}",
"Content-Type": "application/json"
},
json=payload
)
Os agentes podem ser exportados como JSON (via UI ou API) e importados em outra instância da Cortex — útil para:
A Cortex oferece três tipos distintos de webhooks para manter você informado sobre eventos da instância e permitir integrações com sistemas externos. Eles cobrem desde notificações de cadastro de novos usuários até a possibilidade de postar mensagens em canais a partir de serviços externos.
| Tipo | Direção | Quem configura | Propósito |
|---|---|---|---|
| Admin Webhook | Saída (Cortex → externo) | Administrador (instância) | Notifica administradores sobre novos cadastros |
| User Webhook | Saída (Cortex → externo) | Cada usuário (próprio perfil) | Notifica o usuário quando uma resposta de chat fica pronta, útil em tarefas longas |
| Channel Webhook | Entrada (externo → Cortex) | Gestor do canal ou administrador | Permite que serviços externos postem mensagens em um canal específico |
ℹ️ Os webhooks da Cortex hoje cobrem esses três casos específicos. Para automações mais amplas (eventos de uso, budget, auditoria, SIEM, etc.) use a API REST, Tools e Functions ou Pipelines — webhooks não substituem essas camadas.
Webhook da instância para administradores acompanharem o cadastro de novas contas em tempo real.
Caso de uso típico: receber um alerta em um canal Slack/Discord/Teams sempre que alguém criar conta na Cortex, possibilitando boas-vindas e acompanhamento do crescimento da base.
Existem duas formas, com efeito equivalente:
Opção A — Pelo Painel Admin
Opção B — Por variável de ambiente
Defina a variável WEBHOOK_URL na configuração do backend da Cortex. A variável tem precedência igual ao painel — escolha o método que melhor se encaixa no seu fluxo de deploy.
Quando um novo usuário se cadastra, a Cortex envia um POST JSON para a URL configurada:
{
"event": "new_user",
"user": {
"email": "[email protected]",
"name": "Tim"
}
}
Webhook pessoal que cada usuário pode configurar para receber um aviso quando o modelo terminar de gerar uma resposta para uma prompt.
Caso de uso típico: o usuário submete uma prompt longa (análise extensa, geração de relatório, raciocínio agêntico multi-passo) e fecha a aba para trabalhar em outra coisa. Quando a resposta fica pronta, ele recebe um ping no Slack/Discord/Telegram/etc. e volta para ler.
A notificação é disparada somente quando o usuário não está com a aba da Cortex em foco. Se ele está olhando para a conversa em tempo real, o webhook não é acionado — evitando notificações redundantes.
User webhooks vêm desabilitados por padrão. O administrador escolhe se libera ou não para a instância, em duas formas:
ENABLE_USER_WEBHOOKS=False para desabilitar globalmente e ocultar o campo no perfil dos usuários.🛡️ Recomendação de governança: ative apenas se houver demanda formal. Cada user webhook é uma URL externa que a Cortex chamará — multiplica a superfície de saída e exige confiança nos destinos dos usuários (eles podem apontar para serviços arbitrários). Considere combinar com a política de uso aceitável.
Quando uma resposta fica pronta e o usuário está inativo, a Cortex envia um POST JSON para a URL configurada por ele:
{
"event": "chat_response",
"chat": {
"id": "abc-123-def-456",
"title": "Minha conversa incrível",
"last_message": "Esta é a prompt que enviei."
}
}
Diferentemente dos dois acima, channel webhooks são de entrada: permitem que serviços externos, ferramentas de automação ou scripts postem mensagens diretamente em canais da Cortex. Cada canal pode ter múltiplos webhooks, cada um com sua própria identidade.
Cada channel webhook possui:
POSTAs mensagens postadas via webhook aparecem no canal com a identidade do webhook — deixando claro que vieram de um sistema externo, não de um usuário humano.
Apenas gestores do canal (channel managers) e administradores da Cortex podem criar, editar e excluir webhooks de um canal.
{WEBUI_API_BASE_URL}/channels/webhooks/{webhook_id}/{token}
A URL é única e contém um token de autenticação embutido. Qualquer pessoa com essa URL pode postar no canal — trate-a como uma credencial.
A URL não muda quando você atualiza o nome ou a imagem. Mensagens postadas após a alteração mostrarão a nova identidade; mensagens anteriores preservam a identidade do momento em que foram criadas.
Após a exclusão, a URL para de funcionar imediatamente. Mensagens já postadas pelo webhook permanecem visíveis, mas aparecem com a autoria "Deleted Webhook".
Endpoint: POST {webhook_url}
Headers: Content-Type: application/json
Body:
{
"content": "Conteúdo da sua mensagem aqui"
}
Exemplo — cURL:
curl -X POST "https://sua-cortex.com/api/channels/webhooks/{webhook_id}/{token}" \
-H "Content-Type: application/json" \
-d '{"content": "Deploy em produção concluído com sucesso! 🚀"}'
Exemplo — Python:
import requests
webhook_url = "https://sua-cortex.com/api/channels/webhooks/{webhook_id}/{token}"
mensagem = {
"content": "Build #1234 falhou: testes unitários não passaram."
}
resposta = requests.post(webhook_url, json=mensagem)
print(resposta.json())
{
"success": true,
"message_id": "abc-123-def-456"
}
Mensagens postadas via webhook têm um sistema de identidade próprio:
role do autor é marcado como webhook, distinguindo claramente de usuários humanosSe as notificações ou postagens não estão chegando, verifique nesta ordem:
ENABLE_USER_WEBHOOKS não está em False.📌 Roadmap: o conjunto de eventos suportados por webhooks da Cortex está em evolução. Acompanhe atualizações futuras para novos tipos de evento, autenticação adicional e opções de customização.
pip install cortex-sdk (em desenvolvimento)npm install @sinapsetech/cortex-sdkTodo SDK/framework que fala OpenAI funciona:
openai, langchain, llamaindex, instructor, dspy, litellmopenai, langchainjs, ai-sdk (Vercel)go-openaiasync-openaiOpenAI-DotNetopenai4j, spring-aiBasta apontar base_url para a Cortex e usar sua API Key.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="claude-sonnet-4-6",
api_key="sk-cortex-...",
base_url="https://cortex.suaempresa.com/api"
)
resposta = llm.invoke("Resuma a LGPD em 3 frases.")
print(resposta.content)
from llama_index.llms.openai import OpenAI
llm = OpenAI(
model="gpt-5",
api_key="sk-cortex-...",
api_base="https://cortex.suaempresa.com/api"
)
✅ RECOMENDADO:
Frontend ─→ Backend ─→ Cortex
(API key no backend, não exposta ao navegador)
❌ EVITAR:
Frontend ─→ Cortex direto
(API key no navegador = comprometida em minutos)
Para aplicações web, sempre intermediar via seu backend. A API key da Cortex nunca deve ir ao browser.
Chamadas a LLMs podem falhar por:
Use retry com backoff exponencial:
from tenacity import retry, wait_exponential, stop_after_attempt
@retry(
wait=wait_exponential(multiplier=1, min=2, max=30),
stop=stop_after_attempt(5)
)
def chamar_cortex(messages):
return client.chat.completions.create(
model="claude-sonnet-4-6",
messages=messages
)
LLMs podem demorar. Configure timeouts altos (60-120s para modelos de raciocínio):
client = OpenAI(
api_key="...",
base_url="...",
timeout=120.0 # 2 minutos
)
Passe o campo user para facilitar auditoria:
resposta = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[...],
user="[email protected]" # ← aparece nos logs
)
seedPara casos reproduzíveis (testes, QA), fixe seed:
resposta = client.chat.completions.create(
model="gpt-5",
messages=[...],
seed=42,
temperature=0 # para máxima reprodutibilidade
)
Para processar muitos itens, use async ou batch:
import asyncio
from openai import AsyncOpenAI
async_client = AsyncOpenAI(api_key="...", base_url="...")
async def processar_item(item):
resp = await async_client.chat.completions.create(
model="claude-haiku-4-5",
messages=[{"role": "user", "content": item}]
)
return resp.choices[0].message.content
async def processar_lote(itens):
return await asyncio.gather(*[processar_item(i) for i in itens])
# Processa 100 itens em paralelo
resultados = asyncio.run(processar_lote(itens_list))
Para integrações que esperam JSON confiável:
resposta = client.chat.completions.create(
model="gpt-5",
messages=[
{"role": "system", "content": "Responda APENAS em JSON válido."},
{"role": "user", "content": "Extraia nome e CNPJ deste texto: ..."}
],
response_format={"type": "json_object"},
temperature=0.1
)
import json
dados = json.loads(resposta.choices[0].message.content)
request_id retornado pela Cortex em seus logsDependem do plano e das políticas da sua organização. Exemplos típicos:
| Limite | Valor |
|---|---|
| Requests por minuto por API key | 60-6.000 |
| Tokens por minuto por API key | 100k-10M |
| Requests simultâneas | 10-500 |
| Tamanho máximo de request | 10 MB |
Use os headers de rate limit para monitorar:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1713730900
| Código | Significado | Ação |
|---|---|---|
| 200 | Sucesso | - |
| 400 | Request malformado | Verifique o payload |
| 401 | Não autenticado | Verifique API key |
| 403 | Sem permissão | API key sem escopo necessário |
| 404 | Recurso não encontrado | Verifique URL/ID |
| 429 | Rate limit excedido | Retry com backoff |
| 500 | Erro interno | Retry; se persistir, abra ticket |
| 502/503/504 | Gateway / indisponível | Retry com backoff |
import time
from openai import RateLimitError, APIError, APITimeoutError
def chamar_com_retry(messages, max_tries=5):
for tentativa in range(max_tries):
try:
return client.chat.completions.create(
model="claude-sonnet-4-6",
messages=messages
)
except RateLimitError:
espera = 2 ** tentativa
print(f"Rate limit; aguardando {espera}s")
time.sleep(espera)
except APITimeoutError:
print("Timeout; tentando novamente")
continue
except APIError as e:
if 500 <= e.status_code < 600:
time.sleep(2 ** tentativa)
continue
raise
raise RuntimeError("Falhou após todas as tentativas")
Frontend React/Vue/Angular chama seu backend, que chama a Cortex via API. Fácil, seguro, padronizado.
Novo ticket → webhook dispara → backend consulta Cortex → agente classifica e sugere resolução → atualiza ticket.
SharePoint / Confluence → webhook ao criar/editar documento → pipeline ingere na Cortex → atualiza RAG.
Todo dia 1º do mês → script roda → processa N itens pela Cortex em paralelo → gera relatório → envia para stakeholders.
Instalar bot → mensagens no canal chegam via webhook → roteia para Cortex → responde no canal.
Sistema dispara evento → Cortex analisa → cria atividade automática no ERP via conector nativo.
Em vez de múltiplas aplicações chamando múltiplas APIs de IA, tudo passa pela Cortex — governança central, FinOps unificado, logs padronizados.
💬 Precisa integrar a Cortex em um sistema específico ou desenvolver um conector customizado? A SinapseTech oferece equipe especializada em integração corporativa, SDKs, conectores sob medida, revisão arquitetural. Fale com a equipe via Atendimento e Suporte.
📖 Documentação técnica complementar (especificação OpenAPI/Swagger, exemplos avançados, tutoriais de integração) é disponibilizada para clientes sob NDA.