TogaAI API
Documentação
Uma API REST para integrar o assistente jurídico do TogaAI. Base URL https://www.togai.pt/api/v1.
Autenticação
Todas as chamadas precisam de uma chave de API no cabeçalho Authorization. Cria a tua no portal — a chave é mostrada uma única vez.
Authorization: Bearer sk_toga_live_...Trata a chave como uma palavra-passe: nunca a exponhas no frontend/browser.
POST /api/v1/chat
O endpoint principal. O developer escolhe o modo, o esforço e se envia documentos.
| Campo | Tipo | Descrição |
|---|---|---|
| message* | string | A pergunta ou instrução jurídica. |
| mode | "fast" | "deep" | Rápido (default) ou aprofundado (pesquisa exaustiva). |
| effort | "low" | "medium" | "high" | Profundidade de raciocínio/pesquisa (low mais rápido, high mais capaz). |
| documents | { name, content }[] | Até 10 documentos em texto para dar como contexto. |
| anonymize | boolean | Anonimização de dados pessoais antes de sair para o modelo — ativo por default. Desliga com false se o pedido não tiver dados pessoais. |
| stream | boolean | true (default) devolve SSE; false devolve um JSON único. |
| request_id | string | Identificador para rastreio/idempotência. |
Exemplo (cURL)
curl https://www.togai.pt/api/v1/chat \
-H "Authorization: Bearer sk_toga_live_..." \
-H "Content-Type: application/json" \
-d '{
"message": "Resume as cláusulas de rescisão deste contrato",
"mode": "fast",
"effort": "medium",
"stream": false
}'Exemplo (JavaScript)
const res = await fetch("https://www.togai.pt/api/v1/chat", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TOGA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
message: "Qual o prazo de oposição à renovação de um arrendamento?",
mode: "deep",
documents: [{ name: "contrato.txt", content: "..." }],
stream: false,
}),
});
const data = await res.json();
console.log(data.answer, data.usage, data.cost_micro);Resposta (stream: false)
{
"answer": "Nos termos do artigo 1097.º do Código Civil...",
"sources": [{ "id": "https://www.dgsi.pt/...", "citation_number": 1, "content": "..." }],
"usage": { "input_tokens": 4210, "output_tokens": 980 },
"cost_micro": 8540,
"mode": "deep"
}Streaming (stream: true, default)
Devolve text/event-stream. Cada evento é data: {...}: {status}, {sources}, {chunk, done:false} repetido, e por fim {done:true, usage}.
POST /api/v1/messages
O modelo por trás do TogaAI, no formato da Messages API da Anthropic: prompt de sistema, conversa com várias mensagens, tool calling e streaming. Serve para correr um agente (o assistente de um CRM, um fluxo com ferramentas) só com a chave do TogaAI. Um cliente feito para a Anthropic funciona trocando o URL base e a chave, sem mais alterações.
curl https://www.togai.pt/api/v1/messages \
-H "x-api-key: sk_toga_live_..." \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "toga-standard",
"max_tokens": 1024,
"system": "És o assistente do CRM de uma sociedade de advogados.",
"tools": [{
"name": "procurar_cliente",
"description": "Procura um cliente pelo nome.",
"input_schema": { "type": "object", "properties": { "nome": { "type": "string" } }, "required": ["nome"] }
}],
"messages": [{ "role": "user", "content": "Que processos tem a Maria Santos?" }]
}'Com o SDK da Anthropic
import Anthropic from "@anthropic-ai/sdk";
// O SDK acrescenta /v1/messages ao baseURL.
const client = new Anthropic({
apiKey: process.env.TOGA_API_KEY,
baseURL: "https://www.togai.pt/api",
});
const msg = await client.messages.create({
model: "toga-standard",
max_tokens: 1024,
messages: [{ role: "user", content: "Olá" }],
});- Modelos:
toga-standardetoga-fast. A lista e os preços em vigor vêm emGET /api/v1/models. Um idclaude-*é aceite e encaminhado para o nível mais próximo. - A chave vai em
x-api-key(como nos SDK da Anthropic) ou emAuthorization: Bearer. - O pedido, a resposta, os eventos de streaming e os erros têm a forma da Anthropic. O campo
modelda resposta traz o nível pedido. - Não disponível: execução de código, ficheiros e batches.
/api/v1/chat.Privacidade no /api/v1/chat: o modelo nunca vê dados pessoais
Por default (anonymize: true), antes de o teu pedido chegar ao modelo os dados pessoais são pseudonimizados na Europa (nomes → "Pessoa A", moradas → "Morada 1", NIF, contactos, IBAN, matrículas…). O modelo — e a pesquisa web — recebem apenas o texto anonimizado e nunca veem os dados reais. Os valores reais são reinseridos do lado do TogaAI, em tempo real, à medida que a resposta é gerada (inclusive em streaming).
- Todo o processamento corre em servidores na UE (Frankfurt); nenhum dado pessoal toca em infraestrutura fora da UE.
- A anonimização e o mapeamento correm num modelo europeu; o modelo de geração recebe só pseudónimos.
- Se a anonimização não puder correr, o pedido é bloqueado — nunca enviamos dados pessoais em claro.
- Desliga com
anonymize: falsequando o pedido não tem dados pessoais (mais rápido e económico).
GET /api/v1/usage
Consulta o saldo e o consumo dos últimos 30 dias.
curl https://www.togai.pt/api/v1/usage -H "Authorization: Bearer sk_toga_live_..."{
"balance": { "eur": 24.61, "currency": "EUR", "billing_mode": "prepaid" },
"usage_30d": { "requests": 128, "spend_eur": 5.39, "input_tokens": 512000, "output_tokens": 96400 }
}Preços & créditos
€14 por 1 milhão de tokens
input + output combinados · ≈ €0,014 / 1.000 tokens · o mesmo preço em fast/deep e em qualquer modelo.
A faturação é por tokens (input + output) do pedido, debitada da tua carteira de API — separada da subscrição da app. Cada resposta inclui cost_micro (micro-EUR, 1e-6 €), por isso sabes o custo exato de cada chamada.
- Pré-pago: carregas saldo e cada chamada desconta; a 0, as chamadas devolvem
402. - Pay-as-you-go: consumo faturado ao fim do mês (em breve).
/api/v1/messages
Um agente reenvia a conversa inteira a cada passo, por isso aqui o preço separa o que é lido do cache (barato) do resto. Em euros por 1 milhão de tokens:
| Modelo | Input | Output | Cache (leitura) | Cache (escrita) |
|---|---|---|---|---|
| toga-standard | €3,61 | €18,06 | €0,36 | €4,51 |
| toga-fast | €1,20 | €6,02 | €0,12 | €1,50 |
Gere o saldo no portal.
Erros
| 400 | Pedido inválido (ex.: falta `message`). |
| 401 | Chave em falta, malformada ou revogada. |
| 402 | Saldo insuficiente — carrega créditos. |
| 429 | Demasiados pedidos (rate limit). |
| 500 | Erro do servidor. |