Pular para o conteúdo

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

  1. 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.
  2. Use a URL base https://prazeo.com.br/api/v1 e envie a chave no cabeçalho Authorization: Bearer.
  3. 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.

Escopos da API
EscopoPermite
contacts:readListar e consultar clientes, partes e demais contatos.
contacts:writeCadastrar contatos e alterar dados cadastrais.
contacts:deleteEnviar contatos para a lixeira (podem ser restaurados por 90 dias).
cases:readProcessos visíveis para quem criou a chave e seus andamentos.
cases:writeCadastrar processos e alterar dados como responsável, fase e status.
publications:readPublicações capturadas, com teor e situação da triagem.
publications:triageRegistrar, descartar, restaurar e atribuir publicações.
agenda:readPrazos, audiências, tarefas e compromissos.
agenda:writeCriar prazos, tarefas e compromissos e alterar situação.
finance:readLançamentos e cobranças de clientes.
documents:readLista 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 o next_cursor da resposta. Quando ele vier null, 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, 429 com Retry-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.

Endpoints da API
MétodoRotaO que fazEscopo
GET/api/v1/meContexto da chave—
GET/api/v1/contactsListar contatoscontacts:read
POST/api/v1/contactsCadastrar contatocontacts:write
GET/api/v1/contacts/{id}Consultar contatocontacts:read
PATCH/api/v1/contacts/{id}Alterar contatocontacts:write
DELETE/api/v1/contacts/{id}Excluir contato (lixeira)contacts:delete
GET/api/v1/casesListar processoscases:read
POST/api/v1/casesCadastrar processocases:write
GET/api/v1/cases/{id}Consultar processocases:read
PATCH/api/v1/cases/{id}Alterar processocases:write
GET/api/v1/cases/{id}/movementsAndamentos do processocases:read
GET/api/v1/publicationsListar publicaçõespublications:read
GET/api/v1/publications/{id}Consultar publicaçãopublications:read
PATCH/api/v1/publications/{id}Tratar publicação (triagem)publications:triage
GET/api/v1/agenda-itemsListar itens da agendaagenda:read
POST/api/v1/agenda-itemsCriar item na agendaagenda:write
GET/api/v1/agenda-items/{id}Consultar itemagenda:read
PATCH/api/v1/agenda-items/{id}Alterar situação, responsáveis ou dataagenda:write
GET/api/v1/transactionsListar lançamentosfinance:read
GET/api/v1/invoicesListar cobrançasfinance:read
GET/api/v1/documentsListar documentosdocuments:read
GET/api/v1/documents/{id}/downloadBaixar arquivodocuments: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.

Eventos de webhook
EventoQuando
publication.createdUma nova publicação (intimação, despacho, edital…) foi capturada para uma OAB monitorada.
agenda_item.createdPrazo, audiência, tarefa ou compromisso criado (por pessoa, publicação, fluxo ou API).
agenda_item.updatedMudança de data, responsável ou situação (inclusive conclusão).
case.movement.createdAndamento novo em um processo monitorado (tribunal, publicação registrada ou lançamento manual).
invoice.paidUm cliente pagou uma cobrança (Pix, boleto ou cartão) ou a baixa foi registrada.
contact.createdNovo 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 "", 204

Assistentes 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.

Ferramentas MCP
FerramentaO que fazEscopo
search_casesBusca processos por título, número CNJ ou cliente.cases:read
get_caseDetalhes do processo: partes, fase, últimos andamentos e itens abertos na agenda.cases:read
get_case_movementsAndamentos mais recentes de um processo.cases:read
list_deadlinesPrazos e audiências em aberto num período (padrão: próximos 14 dias).agenda:read
list_pending_publicationsPublicações ainda não tratadas, das mais urgentes para as menos.publications:read
search_contactsBusca clientes e contatos por nome, e-mail ou CPF/CNPJ.contacts:read
create_taskCria 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"}}}'