Integre o Prazeo com os sistemas do seu escritório
API REST com chaves por escopo, webhooks assinados e um servidor MCP para assistentes de IA. As mesmas regras do app valem aqui: permissões de quem criou a chave, processos restritos protegidos e tudo registrado na auditoria.
API aberta em todos os planos, inclusive no gratuito.
Começando
- No app, vá em Configurações › API e webhooks › Nova chave, dê um nome e escolha os escopos. A chave (
prm_live_…) aparece uma única vez: guardamos só um hash. - Use a URL base
https://prazeo.com.br/api/v1e envie a chave no cabeçalhoAuthorization: Bearer. - Teste com a rota que diz quem a chave representa:
curl https://prazeo.com.br/api/v1/me \
-H "Authorization: Bearer prm_live_SUA_CHAVE"# Processos visíveis para quem criou a chave
curl "https://prazeo.com.br/api/v1/cases?limit=20&status=active" \
-H "Authorization: Bearer prm_live_SUA_CHAVE"
# Criar um prazo (passa pela dupla checagem no app)
curl -X POST https://prazeo.com.br/api/v1/agenda-items \
-H "Authorization: Bearer prm_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"type":"deadline","title":"Contestação","due_date":"2026-10-28","case_id":"..."}'Autenticação e escopos
Cada chave age em nome de quem a criou: só funciona enquanto essa pessoa fizer parte do escritório (ao sair, as chaves dela são revogadas), e nunca pode mais do que o perfil dela permite hoje, mesmo que a chave tenha o escopo. Processos privados ou de equipe só aparecem se a pessoa tiver acesso a eles. Se o escritório exigir a verificação em duas etapas, a chave só funciona depois que quem a criou ativar. Chaves podem ter validade e são revogadas na hora.
| Escopo | Permite |
|---|---|
| contacts:read | Listar e consultar clientes, partes e demais contatos. |
| contacts:write | Cadastrar contatos e alterar dados cadastrais. |
| contacts:delete | Enviar contatos para a lixeira (podem ser restaurados por 90 dias). |
| cases:read | Processos visíveis para quem criou a chave e seus andamentos. |
| cases:write | Cadastrar processos e alterar dados como responsável, fase e status. |
| publications:read | Publicações capturadas, com teor e situação da triagem. |
| publications:triage | Registrar, descartar, restaurar e atribuir publicações. |
| agenda:read | Prazos, audiências, tarefas e compromissos. |
| agenda:write | Criar prazos, tarefas e compromissos e alterar situação. |
| finance:read | Lançamentos e cobranças de clientes. |
| documents:read | Lista de documentos e download dos arquivos. |
Paginação, datas e erros
- Paginação por cursor:
?limit=50(1 a 200) e, para a próxima página,?cursor=com onext_cursorda resposta. Quando ele viernull, acabou. - Datas: datas de calendário (prazos, vencimentos) em
AAAA-MM-DD; instantes em ISO 8601 UTC (2026-10-14T13:00:00.000Z). - Dinheiro: sempre em centavos, em campos terminados em
_cents(150000 = R$ 1.500,00). - Corpo: JSON em snake_case (camelCase também é aceito nas requisições).
- Limite: 120 requisições por minuto por chave. Cabeçalhos
X-RateLimit-Limit/X-RateLimit-Remaining; ao estourar,429comRetry-After. - Somente leitura: se a assinatura do escritório estiver em modo somente leitura, as leituras continuam funcionando e as escritas respondem
403 read_only.
HTTP/1.1 422 Unprocessable Entity
{
"error": {
"code": "validation_failed",
"message": "Verifique os campos enviados.",
"details": { "name": ["Informe o nome (mínimo 2 letras)."] }
}
}Endpoints
Descrição completa (campos, filtros e exemplos) em /api/v1/openapi.json. Importe no Postman, Insomnia ou no gerador de clientes da sua linguagem.
| Método | Rota | O que faz | Escopo |
|---|---|---|---|
| GET | /api/v1/me | Contexto da chave | — |
| GET | /api/v1/contacts | Listar contatos | contacts:read |
| POST | /api/v1/contacts | Cadastrar contato | contacts:write |
| GET | /api/v1/contacts/{id} | Consultar contato | contacts:read |
| PATCH | /api/v1/contacts/{id} | Alterar contato | contacts:write |
| DELETE | /api/v1/contacts/{id} | Excluir contato (lixeira) | contacts:delete |
| GET | /api/v1/cases | Listar processos | cases:read |
| POST | /api/v1/cases | Cadastrar processo | cases:write |
| GET | /api/v1/cases/{id} | Consultar processo | cases:read |
| PATCH | /api/v1/cases/{id} | Alterar processo | cases:write |
| GET | /api/v1/cases/{id}/movements | Andamentos do processo | cases:read |
| GET | /api/v1/publications | Listar publicações | publications:read |
| GET | /api/v1/publications/{id} | Consultar publicação | publications:read |
| PATCH | /api/v1/publications/{id} | Tratar publicação (triagem) | publications:triage |
| GET | /api/v1/agenda-items | Listar itens da agenda | agenda:read |
| POST | /api/v1/agenda-items | Criar item na agenda | agenda:write |
| GET | /api/v1/agenda-items/{id} | Consultar item | agenda:read |
| PATCH | /api/v1/agenda-items/{id} | Alterar situação, responsáveis ou data | agenda:write |
| GET | /api/v1/transactions | Listar lançamentos | finance:read |
| GET | /api/v1/invoices | Listar cobranças | finance:read |
| GET | /api/v1/documents | Listar documentos | documents:read |
| GET | /api/v1/documents/{id}/download | Baixar arquivo | documents:read |
Webhooks
Cadastre a URL do seu sistema em Configurações › API e webhooks. Para cada evento escolhido enviamos um POST com JSON. Responda com qualquer status 2xx em até 10 segundos. Se falhar, tentamos de novo com espera exponencial (1 min, 3 min, 7 min, 15 min, 31 min, 1 h…) por até 24 horas; cada tentativa aparece no registro de entregas, com a resposta do seu sistema e um botão para reenviar. Depois de 50 falhas seguidas o endereço é desativado e avisamos os administradores. Eventos de processos privados não são enviados por webhook.
| Evento | Quando |
|---|---|
| publication.created | Uma nova publicação (intimação, despacho, edital…) foi capturada para uma OAB monitorada. |
| agenda_item.created | Prazo, audiência, tarefa ou compromisso criado (por pessoa, publicação, fluxo ou API). |
| agenda_item.updated | Mudança de data, responsável ou situação (inclusive conclusão). |
| case.movement.created | Andamento novo em um processo monitorado (tribunal, publicação registrada ou lançamento manual). |
| invoice.paid | Um cliente pagou uma cobrança (Pix, boleto ou cartão) ou a baixa foi registrada. |
| contact.created | Novo cliente, parte ou outro contato (manual, importação, portal ou API). |
POST /webhooks/prazeo HTTP/1.1
Content-Type: application/json; charset=utf-8
Prazeo-Event: agenda_item.created
Prazeo-Delivery: 7f3c…
Prazeo-Event-Id: evt_9b1e…
Prazeo-Signature: t=1760450400, v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
{
"id": "evt_9b1e…",
"type": "agenda_item.created",
"created_at": "2026-10-14T13:00:00.000Z",
"organization_id": "…",
"data": {
"id": "…",
"type": "deadline",
"title": "Contestação",
"due_date": "2026-10-28",
"case_id": "…",
"status": "pending"
}
}Verificar a assinatura
O cabeçalho Prazeo-Signature tem o formato t=<segundos unix>, v1=<assinatura>. A assinatura é o HMAC-SHA256, em hexadecimal, de "<t>.<corpo bruto>" com o segredo do endereço (whsec_…). Recalcule sobre o corpo exatamente como chegou, compare em tempo constante e rejeite carimbos com mais de 5 minutos. Durante a troca de segredo pode haver mais de um v1.
Node.js (Express)
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.PRAZEO_WEBHOOK_SECRET; // whsec_...
// Use o corpo BRUTO: a assinatura é calculada sobre os bytes recebidos.
app.post("/webhooks/prazeo", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("Prazeo-Signature") ?? "";
const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
const t = Number(parts.t);
const expected = crypto.createHmac("sha256", SECRET).update(`${t}.${req.body}`).digest("hex");
const ok =
Math.abs(Date.now() / 1000 - t) <= 300 &&
header.split(",").some((p) => {
const [k, v] = p.trim().split("=");
return k === "v1" && v.length === expected.length && crypto.timingSafeEqual(Buffer.from(v), Buffer.from(expected));
});
if (!ok) return res.status(400).send("assinatura inválida");
const event = JSON.parse(req.body.toString("utf8"));
// Use event.id para não processar o mesmo evento duas vezes.
console.log(event.type, event.data);
res.sendStatus(204);
});Python (Flask)
import hashlib, hmac, json, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["PRAZEO_WEBHOOK_SECRET"].encode() # whsec_...
@app.post("/webhooks/prazeo")
def prazeo_webhook():
header = request.headers.get("Prazeo-Signature", "")
parts = [p.strip().split("=", 1) for p in header.split(",") if "=" in p]
t = next((int(v) for k, v in parts if k == "t"), 0)
raw = request.get_data() # corpo bruto, antes de interpretar o JSON
expected = hmac.new(SECRET, f"{t}.".encode() + raw, hashlib.sha256).hexdigest()
valid = abs(time.time() - t) <= 300 and any(
k == "v1" and hmac.compare_digest(v, expected) for k, v in parts
)
if not valid:
abort(400)
event = json.loads(raw)
print(event["type"], event["data"]) # use event["id"] para deduplicar
return "", 204Assistentes de IA (MCP)
O Prazeo tem um servidor Model Context Protocol (HTTP, sem sessão) em https://prazeo.com.br/api/mcp, em todos os planos. O assistente usa uma chave de API sua, com os mesmos escopos, permissões e processos restritos. Sugestões de prazo vindas de publicações continuam precisando de confirmação humana no app.
| Ferramenta | O que faz | Escopo |
|---|---|---|
| search_cases | Busca processos por título, número CNJ ou cliente. | cases:read |
| get_case | Detalhes do processo: partes, fase, últimos andamentos e itens abertos na agenda. | cases:read |
| get_case_movements | Andamentos mais recentes de um processo. | cases:read |
| list_deadlines | Prazos e audiências em aberto num período (padrão: próximos 14 dias). | agenda:read |
| list_pending_publications | Publicações ainda não tratadas, das mais urgentes para as menos. | publications:read |
| search_contacts | Busca clientes e contatos por nome, e-mail ou CPF/CNPJ. | contacts:read |
| create_task | Cria uma tarefa na agenda (registrada na auditoria como feita via API). | agenda:write |
Claude Code
claude mcp add --transport http prazeo https://prazeo.com.br/api/mcp \
--header "Authorization: Bearer prm_live_SUA_CHAVE"Claude Desktop
Em Configurações › Desenvolvedor › Editar configuração, adicione ao claude_desktop_config.json (usa a ponte mcp-remote, que exige Node.js) e reinicie o app:
{
"mcpServers": {
"prazeo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://prazeo.com.br/api/mcp",
"--header",
"Authorization:Bearer ${PRAZEO_API_KEY}"
],
"env": {
"PRAZEO_API_KEY": "prm_live_SUA_CHAVE"
}
}
}
}ChatGPT e outros clientes MCP
Em clientes que aceitam servidores MCP remotos com cabeçalho de autorização (por exemplo, conectores personalizados no modo desenvolvedor do ChatGPT, Cursor ou VS Code), informe a URL https://prazeo.com.br/api/mcp, transporte “HTTP (streamable)” e o cabeçalho Authorization: Bearer prm_live_…. Se o cliente só aceitar OAuth, use a ponte mcp-remote como no Claude Desktop.
Testar com curl
curl https://prazeo.com.br/api/mcp \
-H "Authorization: Bearer prm_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_cases","arguments":{"query":"Silva"}}}'