# ProvJud API — documentação completa

> Versão da documentação: 2026-09-01  
> API base: `https://api.provjud.com`  
> OpenAPI: `https://api.provjud.com/openapi.json`  
> Swagger interativo: `https://api.provjud.com/docs`

A ProvJud é uma API privada de discovery judicial, consulta e monitoramento processual, jurisprudência, documentos públicos, dívida ativa federal, certificados A1 e webhooks persistentes.

Esta documentação também foi preparada para consumo por agentes de IA. Valores entre `<...>` devem ser substituídos. Nunca inclua tokens, senhas administrativas, senhas de certificados ou arquivos PFX em prompts, logs ou repositórios.

## 1. Conceitos importantes

### 1.1 Discovery não é certidão negativa

O discovery consulta as fontes integradas e devolve, junto com os processos, um relatório `coverage`. Um resultado vazio significa apenas que nenhuma ocorrência foi localizada nas fontes e períodos efetivamente cobertos. Não significa inexistência de processos.

Estados usuais de uma execução:

| Estado | Significado |
|---|---|
| `complete` | Todas as fontes previstas para aquela execução responderam adequadamente. |
| `partial` | Uma ou mais fontes estavam incompletas, indisponíveis ou não suportadas. |
| `failed` | A execução falhou antes de produzir resultado utilizável. |

Estados de associação de um processo:

| Estado | Significado |
|---|---|
| `confirmed` | Identidade confirmada por evidência forte, como CPF/CNPJ estruturado. |
| `probable` | Nome estruturado ou outra combinação de evidências com alta confiança. |
| `possible` | Indício útil que ainda exige revisão. |
| `rejected` | Associação rejeitada. |

### 1.2 Operações síncronas e assíncronas

Consultas curtas podem ser síncronas. Pesquisas históricas extensas devem usar jobs:

1. envie `POST /v1/discovery/jobs`;
2. guarde o `job_id`;
3. consulte `GET /v1/discovery/jobs/{job_id}` até o estado terminal;
4. use `Idempotency-Key` para não duplicar uma solicitação após timeout de rede.

Atualizações processuais seguem o mesmo padrão com `POST /v1/processes/{number}/refresh` e `GET /v1/process-refresh/{job_id}`.

## 2. Autenticação

### 2.1 Aplicações consumidoras

As aplicações usam Bearer Token:

```http
Authorization: Bearer jd_live_<key_id>.<secret>
```

Exemplo:

```bash
curl --fail-with-body \
  -H "Authorization: Bearer $PROVJUD_TOKEN" \
  -H "X-Request-Id: integracao-123" \
  https://api.provjud.com/v1/sources
```

O token completo é mostrado somente na criação ou rotação. Armazene-o em um cofre de segredos.

Escopos disponíveis:

| Escopo | Recursos principais |
|---|---|
| `discovery` | Discovery, sujeitos e dívida ativa federal. |
| `processes` | Processos, movimentações, documentos e monitoramentos. |
| `jurisprudence` | Busca, pesquisa e precedentes relacionados. |
| `credentials` | Cofre de certificados pertencente ao cliente da API. |
| `admin` | Recursos administrativos autorizados. |
| `*` | Todos os escopos. Use somente quando indispensável. |

Cabeçalhos de resposta relevantes:

```text
X-Request-Id
X-RateLimit-Limit
X-RateLimit-Remaining
```

### 2.2 Administração

Os endpoints `/v1/admin/*` aceitam `X-Admin-Key`. O console web usa cookie de sessão `HttpOnly` e proteção CSRF. Não exponha a chave administrativa no frontend da aplicação jurídica.

```bash
curl --fail-with-body \
  -H "X-Admin-Key: $PROVJUD_ADMIN_KEY" \
  https://api.provjud.com/v1/admin/api-clients
```

## 3. Códigos HTTP e erros

| Código | Interpretação |
|---|---|
| `200` | Consulta concluída. |
| `201` | Recurso criado. |
| `202` | Job aceito para processamento assíncrono. |
| `307` | Download redirecionado para uma origem HTTPS ou Object Storage. |
| `401` | Token ausente, inválido ou expirado. |
| `403` | Escopo insuficiente, autorização inválida ou CSRF ausente. |
| `404` | Recurso não localizado para aquele cliente. |
| `410` | Documento existia, mas o arquivo não está disponível. |
| `422` | Payload, identificador ou combinação de parâmetros inválida. |
| `429` | Limite por minuto excedido. Respeite `Retry-After`. |
| `503` | Dependência operacional ou autenticação indisponível. |

Erro simples:

```json
{"detail":"Credencial de servico obrigatoria"}
```

Erro de validação:

```json
{
  "detail": [
    {
      "loc": ["body", "name"],
      "msg": "String should have at least 3 characters",
      "type": "string_too_short"
    }
  ]
}
```

## 4. Início rápido

### 4.1 JavaScript/TypeScript

```ts
const baseUrl = "https://api.provjud.com";
const token = process.env.PROVJUD_TOKEN!;

async function provjud(path: string, init: RequestInit = {}) {
  const response = await fetch(`${baseUrl}${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "X-Request-Id": crypto.randomUUID(),
      ...init.headers,
    },
  });
  if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
  return response.json();
}

const result = await provjud("/v1/discovery/jobs", {
  method: "POST",
  headers: { "Idempotency-Key": crypto.randomUUID() },
  body: JSON.stringify({
    kind: "company",
    name: "EMPRESA EXEMPLO LTDA",
    identifier: "<CNPJ>",
    aliases: ["EMPRESA EXEMPLO"],
    regions: ["RS", "MG", "SP", "BR"],
    date_start: "2016-01-01",
    date_end: "2026-09-01"
  }),
});
```

### 4.2 Python

```python
import os
import uuid
import httpx

headers = {
    "Authorization": f"Bearer {os.environ['PROVJUD_TOKEN']}",
    "X-Request-Id": str(uuid.uuid4()),
}

with httpx.Client(base_url="https://api.provjud.com", headers=headers, timeout=60) as client:
    response = client.get("/v1/jurisprudence/search", params={
        "q": "responsabilidade civil atraso entrega imóvel",
        "court": "STJ",
        "limit": 10,
    })
    response.raise_for_status()
    print(response.json())
```

## 5. Discovery

### `POST /v1/discovery`

Executa discovery síncrono. Requer escopo `discovery`.

```bash
curl --fail-with-body -X POST https://api.provjud.com/v1/discovery \
  -H "Authorization: Bearer $PROVJUD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind":"company",
    "name":"EMPRESA EXEMPLO LTDA",
    "identifier":"<CNPJ>",
    "aliases":["EMPRESA EXEMPLO"],
    "regions":["RS","MG","SP","BR"],
    "date_start":"2026-08-01",
    "date_end":"2026-09-01"
  }'
```

Campos:

| Campo | Tipo | Obrigatório | Observação |
|---|---|---:|---|
| `kind` | `person \| company` | sim | Tipo do sujeito. |
| `name` | string | sim | Nome ou razão social, 3 a 300 caracteres. |
| `identifier` | string/null | não | CPF ou CNPJ; usado para correlação quando a fonte o oferece. |
| `aliases` | string[] | não | Até 20 nomes históricos ou comerciais. |
| `regions` | string[] | não | Atualmente `RS`, `MG`, `SP` e `BR`. |
| `date_start` | date | sim | Início inclusivo. |
| `date_end` | date | sim | Fim inclusivo. |

Resposta ilustrativa:

```json
{
  "run_id": "<uuid>",
  "status": "partial",
  "subject_id": "<uuid>",
  "cases": [
    {
      "cnj_number": "<20-digitos>",
      "court": "TRT4",
      "role": "P",
      "confidence": 0.94,
      "status": "probable",
      "match_basis": ["similar_structured_party_name"],
      "publication_ids": ["<id-origem>"],
      "metadata_available": true
    }
  ],
  "coverage": [
    {"source":"djen","status":"success","results":1,"details":{}},
    {"source":"djen_archive","status":"partial","results":1,"details":{}}
  ],
  "warning": "Ausencia de resultados nao equivale a certidao negativa judicial."
}
```

### `POST /v1/discovery/historical`

Mesmo contrato de entrada e saída do discovery síncrono, destinado a períodos históricos. Para intervalos extensos prefira o job assíncrono.

### `POST /v1/discovery/jobs`

Cria discovery histórico assíncrono. Aceita `Idempotency-Key`.

```bash
curl --fail-with-body -X POST https://api.provjud.com/v1/discovery/jobs \
  -H "Authorization: Bearer $PROVJUD_TOKEN" \
  -H "Idempotency-Key: discovery-cliente-42-20260901" \
  -H "Content-Type: application/json" \
  -d @discovery.json
```

Resposta `202`:

```json
{"job_id":"<uuid>","status":"queued"}
```

### `GET /v1/discovery/jobs/{job_id}`

Consulta o job. Trate `success`, `partial` e `failed` como estados terminais. Em `partial`, sempre leia `coverage`.

### `GET /v1/subjects/{identifier}/processes?kind=company`

Lista processos já associados ao CPF/CNPJ informado. `kind` aceita `company` ou `person`.

### `POST /v1/subjects/monitor`

Cria monitoramento recorrente do sujeito.

```json
{
  "kind": "company",
  "name": "EMPRESA EXEMPLO LTDA",
  "identifier": "<CNPJ>",
  "aliases": ["EMPRESA EXEMPLO"],
  "regions": ["RS", "MG", "SP", "BR"],
  "frequency": "daily",
  "recurrence_days": 1,
  "lookback_days": 31,
  "callback_url": "https://app.exemplo.com/webhooks/provjud"
}
```

`lookback_days` aceita 1 a 3650 e controla as consultas recorrentes. No primeiro
cadastro de uma empresa com CNPJ, a ProvJud consulta o cadastro empresarial,
adiciona razão social e nome fantasia como aliases, identifica município/UF,
inclui automaticamente a região da sede e o escopo nacional (`BR`) e enfileira
um discovery inicial desde a data de abertura. A resposta contém
`initial_discovery_job_id`, `initial_discovery_start` e `company_routing`.
`BR` significa todos os tribunais ativos do catálogo nacional; a UF da sede é
usada como prioridade operacional, não como exclusão de processos em outros estados.
A URL de callback deve usar HTTPS.

## 6. Processos e documentos

Números CNJ podem ser enviados formatados ou apenas com 20 dígitos.

### `GET /v1/processes/{number}?refresh=true`

Retorna capa, classe, unidade, grau, sigilo, assuntos, partes, movimentações, publicações, documentos públicos, relacionados e informações de cache.

```bash
curl --fail-with-body \
  -H "Authorization: Bearer $PROVJUD_TOKEN" \
  "https://api.provjud.com/v1/processes/<NUMERO-CNJ>?refresh=true"
```

Campos relevantes da resposta:

```json
{
  "cnj_number": "<20-digitos>",
  "formatted_number": "<numero-formatado>",
  "court": "TJMG",
  "degree": "G1",
  "filing_date": "2024-01-10",
  "court_unit": "<unidade>",
  "case_class": "<classe>",
  "confidentiality_level": 0,
  "electronic": true,
  "subjects": [],
  "movements": [],
  "parties": [],
  "public_documents": [],
  "publications": [],
  "related_cases": [],
  "cache": {
    "cached_response": false,
    "collected_at": "2026-09-01T12:00:00Z",
    "age_seconds": 10,
    "stale": false,
    "content_hash": "<sha256>"
  }
}
```

### Recursos especializados do processo

| Método e rota | Função |
|---|---|
| `GET /v1/processes/{number}/movements?refresh=false` | Lista movimentações. |
| `GET /v1/processes/{number}/parties` | Lista partes conhecidas e seus papéis. |
| `GET /v1/processes/{number}/public-documents` | Lista documentos públicos. |
| `GET /v1/processes/{number}/documents/{document_id}` | Baixa ou redireciona para o arquivo público. |
| `GET /v1/processes/{number}/documents/{document_id}/text` | Texto extraído e páginas, quando processado. |
| `GET /v1/processes/{number}/legal-profile` | Perfil de temas jurídicos extraído do processo. |
| `POST /v1/processes/{number}/legal-profile/refresh` | Recalcula o perfil jurídico. |
| `GET /v1/processes/{number}/related-precedents` | Precedentes relacionados ao processo. |

`related-precedents` aceita `q` opcional e `limit` de 1 a 50.

### `POST /v1/processes/{number}/refresh`

Solicita atualização assíncrona.

Atualização pública:

```json
{"scope":"public_documents"}
```

Tentativa autorizada de autos completos:

```json
{
  "scope": "full_docket",
  "credential_id": "<uuid-do-certificado>",
  "authorization_declaration": "Certificado da própria parte para acesso ao processo em que figura."
}
```

`full_docket` exige certificado e declaração. A existência de um certificado válido não garante que o tribunal ofereça autenticação autônoma; o job pode terminar `partial` ou `denied`.

Resposta `202`:

```json
{"job_id":"<uuid>","status":"queued","scope":"full_docket"}
```

### `GET /v1/process-refresh/{job_id}`

Retorna estado, tentativas, resultado, erro e timestamps do refresh.

### Monitoramento de processo

`POST /v1/processes/{number}/monitor`

```json
{
  "frequency": "daily",
  "recurrence_days": 1,
  "include_public_documents": true,
  "response_type": "lawsuit",
  "callback_url": "https://app.exemplo.com/webhooks/provjud"
}
```

Operações:

| Método e rota | Função |
|---|---|
| `GET /v1/monitors/{monitor_id}` | Estado do monitor. |
| `POST /v1/monitors/{monitor_id}/pause` | Pausa. |
| `POST /v1/monitors/{monitor_id}/resume` | Retoma e agenda nova execução. |

## 7. Jurisprudência e pesquisa jurídica

### `GET /v1/jurisprudence/search`

Busca híbrida por texto e similaridade semântica.

Parâmetros:

| Parâmetro | Obrigatório | Limites |
|---|---:|---|
| `q` | sim | 3 a 1000 caracteres. |
| `court` | não | Código, por exemplo `STJ`, `STF`, `TJMG`. |
| `date_from` | não | Data ISO. |
| `date_to` | não | Data ISO. |
| `limit` | não | 1 a 100; padrão 20. |

```bash
curl --get https://api.provjud.com/v1/jurisprudence/search \
  -H "Authorization: Bearer $PROVJUD_TOKEN" \
  --data-urlencode "q=responsabilidade civil atraso entrega imóvel" \
  --data-urlencode "court=STJ" \
  --data-urlencode "limit=10"
```

### `GET /v1/jurisprudence/decisions/{decision_id}`

Retorna a decisão, trechos indexados, metadados e origem preservada.

### `POST /v1/jurisprudence/research`

Pesquisa orientada por pergunta. A resposta é baseada no acervo recuperado; não substitui revisão jurídica.

```json
{
  "question": "Qual é o entendimento recente do STJ sobre atraso na entrega de imóvel e dano moral?",
  "court": "STJ",
  "date_from": "2023-01-01",
  "date_to": "2026-09-01",
  "max_sources": 10
}
```

`max_sources` aceita 3 a 30.

### Estado do acervo

| Método e rota | Função |
|---|---|
| `GET /v1/jurisprudence/status` | Quantidade, indexação e saúde do acervo. |
| `GET /v1/ingestion/status` | Estado das filas e fontes de ingestão. |
| `GET /v1/sources` | Catálogo de fontes e capacidades. |

## 8. Dívida ativa federal

### `GET /v1/federal-claims/{cnpj}?sued_only=false`

Consulta o snapshot local dos dados abertos da PGFN. `sued_only=true` restringe a inscrições marcadas como ajuizadas.

Uma fonte sem snapshot carregado é reportada como cobertura `partial`, com
`reason=snapshot_not_loaded`; isso nunca deve ser interpretado como zero dívidas.
O campo `sued=true` confirma que a inscrição oficial está marcada como ajuizada,
mas o número CNJ só é associado quando houver correlação documental auditável.

```json
{
  "cnpj": "<CNPJ>",
  "snapshot": "2026-08",
  "registrations": 2,
  "sued_registrations": 1,
  "consolidated_value": 15000.0,
  "sued_consolidated_value": 10000.0,
  "claims": [
    {
      "registration_number": "<inscricao>",
      "debt_base": "<base>",
      "debtor_name": "EMPRESA EXEMPLO LTDA",
      "sued": true,
      "consolidated_value": 10000.0,
      "correlations": [
        {
          "cnj_number": "<20-digitos>",
          "status": "unverified",
          "confidence": 0.6,
          "source": "trf4_dejf",
          "match_basis": ["nearby_registration_and_process"]
        }
      ]
    }
  ]
}
```

Uma inscrição ajuizada não equivale automaticamente a um processo distinto. Só trate o número CNJ como confirmado quando `correlations[].status` for `confirmed`.

## 9. Cofre de certificados A1

Requer escopo `credentials`. O arquivo PKCS#12 e sua senha são cifrados no banco. Metadados podem ser listados; a senha e o PFX nunca são devolvidos.

### `POST /v1/credentials/certificates`

```json
{
  "label": "Certificado Empresa Exemplo 2027",
  "pfx_base64": "<BASE64-DO-PFX>",
  "password": "<SENHA-DO-PFX>",
  "owner_kind": "company",
  "owner_name": "EMPRESA EXEMPLO LTDA",
  "owner_identifier": "<CNPJ>",
  "authorizations": [
    {
      "subject_kind": "company",
      "subject_name": "EMPRESA EXEMPLO LTDA",
      "subject_identifier": "<CNPJ>",
      "relationship": "self",
      "declared_basis": "Certificado pertencente à própria pessoa jurídica.",
      "valid_until": null,
      "evidence": {"source":"client_declaration"}
    }
  ]
}
```

Relacionamentos aceitos: `self`, `legal_representative`, `attorney`, `court_grant`.

Regras de segurança:

- o certificado deve corresponder ao identificador do titular;
- autorização de sócio não é presumida para a empresa;
- uso em autos completos exige vínculo provável ou confirmado entre o sujeito autorizado e o processo;
- certificados vencidos são desativados;
- avisos de vencimento podem ser enviados por webhook;
- CAPTCHA ou barreira interativa não é contornado.

Operações:

| Método e rota | Função |
|---|---|
| `GET /v1/credentials` | Lista metadados das credenciais do cliente. |
| `DELETE /v1/credentials/{credential_id}` | Revoga uma credencial do cliente. |

## 10. Credenciais PDPJ e Domicílio Judicial

Requer escopo `credentials`. Este fluxo permite que a própria aplicação jurídica do cliente cadastre as credenciais emitidas pelo Gestão de Clientes/PDPJ. Não envie `client_id`, `client_secret` ou tokens em prompts, tickets, URLs ou logs.

### Cadastrar pela aplicação cliente

`POST /v1/credentials/integrations`

```http
Authorization: Bearer jd_live_<key_id>.<secret-provjud>
Content-Type: application/json
```

```json
{
  "provider": "pdpj",
  "service": "domicilio_judicial",
  "environment": "production",
  "label": "PDPJ Empresa Exemplo",
  "owner_name": "EMPRESA EXEMPLO LTDA",
  "owner_identifier": "00.000.000/0001-00",
  "client_id": "<CLIENT-ID-EMITIDO-PELO-CNJ>",
  "client_secret": "<SECRET-ID-EMITIDO-PELO-CNJ>",
  "token_url": null,
  "api_base_url": null,
  "scopes": ["openid"]
}
```

Não envie `api_client_id`: o proprietário é obtido do token ProvJud autenticado. Um cliente não consegue cadastrar, listar ou revogar integrações pertencentes a outro cliente.

Serviços aceitos:

| Valor | Uso |
|---|---|
| `domicilio_judicial` | Comunicações, citações e intimações destinadas ao CNPJ. |
| `public_datalake` | API de Consulta de Processos Públicos no Datalake. |
| `marketplace` | Outro serviço liberado pelo Marketplace PDPJ. |
| `other` | Integração PDPJ ainda não catalogada. |

Ambientes aceitos: `production` e `homologation`. Para o Domicílio, as URLs oficiais podem ser omitidas; a ProvJud seleciona os endpoints correspondentes ao ambiente durante a validação.

Resposta de criação:

```json
{
  "id": "<uuid-da-integracao>",
  "provider": "pdpj",
  "service": "domicilio_judicial",
  "environment": "production",
  "label": "PDPJ Empresa Exemplo",
  "owner_name": "EMPRESA EXEMPLO LTDA",
  "verification_status": "declared",
  "active": true,
  "created_at": "2026-09-01T16:29:14-03:00"
}
```

O `client_id`, o `client_secret`, o CNPJ completo e qualquer token PDPJ nunca são devolvidos. Os segredos e o payload integral das comunicações são cifrados no banco. Depois do cadastro, um worker valida OAuth, perfil e vínculo do CNPJ e atualiza `verification_status` para `verified` ou `failed`. Integrações verificadas recebem uma fila histórica em janelas de no máximo sete dias, retomável e idempotente, desde a abertura conhecida da empresa; novas janelas mantêm a consulta contínua. A listagem do Domicílio usa somente `GET` e nunca registra ciência.

Operações do cliente:

| Método e rota | Função |
|---|---|
| `POST /v1/credentials/integrations` | Cadastra uma credencial oficial no cofre do cliente autenticado. |
| `GET /v1/credentials/integrations` | Lista apenas os metadados das integrações do cliente. |
| `DELETE /v1/credentials/integrations/{integration_id}` | Revoga apenas uma integração pertencente ao cliente. |
| `POST /v1/credentials/integrations/{integration_id}/communications/{communication_id}/full-text` | Registra ciência expressa e obtém o inteiro teor de uma comunicação já coletada. |

O cadastro administrativo equivalente utiliza `/v1/admin/integrations` e exige `api_client_id` explícito.

### Inteiro teor e registro de ciência

> Esta operação pode iniciar prazo processual e tem efeito jurídico. Ela nunca é chamada pelo discovery, por agentes de IA ou por rotinas automáticas. A aplicação cliente deve obter confirmação humana e autorização válida antes da chamada.

```http
POST /v1/credentials/integrations/<integration_id>/communications/<communication_id>/full-text
Authorization: Bearer jd_live_<key_id>.<secret-provjud>
Content-Type: application/json
```

```json
{
  "register_legal_awareness": true,
  "operator_document": "000.000.000-00",
  "operator_name": "Advogado responsável",
  "authorization_declaration": "Confirmo que possuo autorização para registrar ciência desta comunicação."
}
```

A ProvJud exige literalmente `register_legal_awareness: true`, valida o CPF do operador, verifica que integração e comunicação pertencem ao cliente autenticado e aceita apenas credencial ativa e verificada. O conteúdo retornado é cifrado; o CPF é armazenado somente como hash e a declaração, o horário e os identificadores ficam na auditoria. Trate a chamada como não idempotente do ponto de vista jurídico: não repita automaticamente após timeout sem antes consultar o estado.

## 11. Webhooks persistentes

Webhooks são administrados em `/v1/admin/webhooks`. O evento é persistido antes da tentativa de entrega. Falhas geram retentativas com atraso crescente e preservação de ordem por assinatura.

Eventos aceitos:

```text
case.updated
case.refresh.failed
jurisprudence.match.created
subject.discovery.completed
subject.case.discovered
discovery.completed
credential.expiring
credential.expired
pdpj.communication.discovered
pdpj.sync.failed
```

### Criar assinatura

`POST /v1/admin/webhooks`

```json
{
  "name": "Aplicação jurídica principal",
  "api_client_id": "<uuid-do-cliente>",
  "callback_url": "https://app.exemplo.com/webhooks/provjud",
  "event_types": [
    "case.updated",
    "subject.case.discovered",
    "pdpj.communication.discovered",
    "pdpj.sync.failed",
    "jurisprudence.match.created",
    "credential.expiring"
  ]
}
```

A resposta de criação contém o segredo do webhook uma única vez. Armazene-o em cofre.

Cabeçalhos entregues:

```http
Content-Type: application/json
X-Juridico-Callback-Id: <uuid-da-entrega>
X-Juridico-Event: case.updated
X-Juridico-Signature: sha256=<hex>
```

Validação em Node.js:

```ts
import crypto from "node:crypto";

export function validProvjudWebhook(rawBody: Buffer, signature: string, secret: string) {
  const received = signature.replace(/^sha256=/, "");
  const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(received, "hex");
  const b = Buffer.from(expected, "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

Valide a assinatura sobre os bytes brutos recebidos, antes de converter o JSON. Responda com qualquer status `2xx` somente depois de persistir o evento. Use `X-Juridico-Callback-Id` como chave de idempotência.

Operações administrativas:

| Método e rota | Função |
|---|---|
| `GET /v1/admin/webhooks` | Assinaturas, backlog, falhas e estado. |
| `POST /v1/admin/webhooks/{subscription_id}/retry` | Reenfileira entregas falhas. |
| `DELETE /v1/admin/webhooks/{subscription_id}` | Revoga a assinatura. |
| `GET /v1/admin/alerts?status=open` | Alertas abertos ou resolvidos. |
| `GET /v1/admin/operations/status` | Saúde operacional dos workers. |

## 12. Administração de clientes da API

O console em `https://api.provjud.com/admin` usa contas individuais. O primeiro acesso apresenta o cadastro do superadministrador e exige a chave administrativa anterior apenas uma vez, como prova de bootstrap. Em seguida, o usuário lê o QR Code em Google Authenticator, Microsoft Authenticator ou aplicativo TOTP compatível e confirma o primeiro código de seis dígitos.

Cada usuário recebe senha própria, 2FA e sessão revogável em cookie `HttpOnly`, `Secure` e `SameSite=Strict`. As senhas usam Argon2id, sessões expiram após oito horas ou trinta minutos de inatividade, cinco falhas bloqueiam temporariamente a conta e cada código TOTP só pode ser usado uma vez. Dez códigos de recuperação são exibidos somente na ativação e são descartáveis.

Perfis disponíveis:

| Perfil | Permissões |
|---|---|
| `superadmin` | Controle integral, cadastro e edição de usuários, clientes da API, certificados e integrações oficiais. |
| `operator` | Leitura operacional, repetição de webhooks e revisão de correspondências jurisprudenciais. |
| `auditor` | Somente leitura de configuração, cobertura, filas e auditoria. |

O superadministrador cadastra o usuário diretamente, informando uma senha inicial forte ou solicitando que a API gere uma. Como ainda não há servidor de e-mail, as credenciais devem ser entregues ao destinatário por um canal seguro. No primeiro acesso, o usuário seleciona **Configurar 2FA**, informa e-mail e senha e vincula o próprio autenticador. O segredo TOTP aparece somente nesse fluxo de primeiro acesso.

Rotas de usuários:

| Método e rota | Função |
|---|---|
| `GET /v1/admin/users` | Lista usuários e estado do 2FA, sem segredos. |
| `POST /v1/admin/users` | Cadastra usuário com `password` ou `generate_password=true`; somente `superadmin`. |
| `PATCH /v1/admin/users/{user_id}` | Edita nome, e-mail, perfil, estado, senha e pode redefinir o 2FA; protege o último `superadmin`. |
| `POST /v1/admin/mfa/enroll` | Inicia o vínculo do autenticador usando e-mail e senha de uma conta com 2FA pendente. |
| `POST /v1/admin/mfa/confirm` | Confirma o primeiro TOTP, ativa o 2FA e entrega códigos de recuperação. |

Cadastro com senha definida pelo administrador:

```json
{
  "email": "advogado@escritorio.com.br",
  "display_name": "Advogado Responsável",
  "role": "operator",
  "password": "Senha-Inicial-Forte-2026!"
}
```

Para geração segura no servidor, omita `password` e envie `"generate_password": true`. A resposta contém `temporary_password` somente nessa chamada. Nunca grave essa senha em logs.

Edição completa:

```json
{
  "display_name": "Novo Nome",
  "email": "novo-email@escritorio.com.br",
  "role": "auditor",
  "active": true,
  "password": "Nova-Senha-Forte-2026!",
  "reset_mfa": true
}
```

Alterar a senha, desativar a conta ou redefinir o 2FA revoga as sessões ativas do usuário. Campos não enviados permanecem inalterados.

### `POST /v1/admin/api-clients`

```json
{
  "name": "Sistema Jurídico Principal",
  "scopes": ["discovery", "processes", "jurisprudence", "credentials"],
  "expires_at": null,
  "rate_limit_per_minute": 120
}
```

Resposta ilustrativa:

```json
{
  "id": "<uuid>",
  "name": "Sistema Jurídico Principal",
  "scopes": ["discovery", "processes", "jurisprudence", "credentials"],
  "token": "jd_live_<key_id>.<secret>"
}
```

Operações:

| Método e rota | Função |
|---|---|
| `GET /v1/admin/api-clients` | Lista clientes sem expor segredos. |
| `GET /v1/admin/api-usage?days=7&client_id=<uuid>` | Uso por rota, status e cliente. |
| `POST /v1/admin/api-clients/{client_id}/rotate` | Revoga o segredo anterior e entrega um novo token uma única vez. |
| `DELETE /v1/admin/api-clients/{client_id}` | Revoga o cliente. |
| `PATCH /v1/admin/jurisprudence/matches/{match_id}` | Marca associação como `accepted` ou `rejected`. |

Certificados administrativos:

| Método e rota | Função |
|---|---|
| `POST /v1/admin/credentials/certificates` | Cadastra certificado para um `api_client_id`. |
| `GET /v1/admin/credentials` | Lista certificados de todos os clientes. |
| `DELETE /v1/admin/credentials/{credential_id}` | Revoga certificado. |

Integrações oficiais administrativas:

| Método e rota | Função |
|---|---|
| `POST /v1/admin/integrations` | Cadastra PDPJ para um `api_client_id`. |
| `GET /v1/admin/integrations` | Lista metadados, nunca os segredos. |
| `DELETE /v1/admin/integrations/{integration_id}` | Revoga a integração. |

## 13. Catálogo integral de endpoints

### Públicos

| Método | Rota | Descrição |
|---|---|---|
| `GET` | `/health` | Saúde da API e banco. |
| `GET` | `/v1/public/platform-stats` | Estatísticas públicas com cache. |
| `GET` | `/openapi.json` | Especificação OpenAPI. |
| `GET` | `/docs` | Swagger interativo. |
| `GET` | `/redoc` | Referência ReDoc. |

### Discovery e sujeitos — escopo `discovery`

| Método | Rota |
|---|---|
| `POST` | `/v1/discovery` |
| `POST` | `/v1/discovery/historical` |
| `POST` | `/v1/discovery/jobs` |
| `GET` | `/v1/discovery/jobs/{job_id}` |
| `GET` | `/v1/subjects/{identifier}/processes` |
| `POST` | `/v1/subjects/monitor` |
| `GET` | `/v1/federal-claims/{cnpj}` |

### Processos — escopo `processes`

| Método | Rota |
|---|---|
| `GET` | `/v1/processes/{number}` |
| `GET` | `/v1/processes/{number}/movements` |
| `GET` | `/v1/processes/{number}/parties` |
| `GET` | `/v1/processes/{number}/public-documents` |
| `GET` | `/v1/processes/{number}/documents/{document_id}` |
| `GET` | `/v1/processes/{number}/documents/{document_id}/text` |
| `POST` | `/v1/processes/{number}/refresh` |
| `GET` | `/v1/process-refresh/{job_id}` |
| `POST` | `/v1/processes/{number}/monitor` |
| `GET` | `/v1/monitors/{monitor_id}` |
| `POST` | `/v1/monitors/{monitor_id}/pause` |
| `POST` | `/v1/monitors/{monitor_id}/resume` |

### Jurisprudência — escopo `jurisprudence`

| Método | Rota |
|---|---|
| `GET` | `/v1/jurisprudence/status` |
| `GET` | `/v1/jurisprudence/search` |
| `GET` | `/v1/jurisprudence/decisions/{decision_id}` |
| `POST` | `/v1/jurisprudence/research` |
| `GET` | `/v1/processes/{number}/related-precedents` |
| `GET` | `/v1/processes/{number}/legal-profile` |
| `POST` | `/v1/processes/{number}/legal-profile/refresh` |

### Operação — token de serviço

| Método | Rota |
|---|---|
| `GET` | `/v1/ingestion/status` |
| `GET` | `/v1/sources` |

### Credenciais — escopo `credentials`

| Método | Rota |
|---|---|
| `POST` | `/v1/credentials/certificates` |
| `GET` | `/v1/credentials` |
| `DELETE` | `/v1/credentials/{credential_id}` |
| `POST` | `/v1/credentials/integrations` |
| `GET` | `/v1/credentials/integrations` |
| `DELETE` | `/v1/credentials/integrations/{integration_id}` |
| `POST` | `/v1/credentials/integrations/{integration_id}/communications/{communication_id}/full-text` |

### Administração — sessão individual com senha e TOTP

| Método | Rota |
|---|---|
| `POST` | `/v1/admin/users` |
| `GET` | `/v1/admin/users` |
| `PATCH` | `/v1/admin/users/{user_id}` |
| `POST` | `/v1/admin/api-clients` |
| `GET` | `/v1/admin/api-clients` |
| `GET` | `/v1/admin/api-usage` |
| `POST` | `/v1/admin/api-clients/{client_id}/rotate` |
| `DELETE` | `/v1/admin/api-clients/{client_id}` |
| `PATCH` | `/v1/admin/jurisprudence/matches/{match_id}` |
| `POST` | `/v1/admin/webhooks` |
| `GET` | `/v1/admin/webhooks` |
| `POST` | `/v1/admin/webhooks/{subscription_id}/retry` |
| `DELETE` | `/v1/admin/webhooks/{subscription_id}` |
| `GET` | `/v1/admin/alerts` |
| `GET` | `/v1/admin/operations/status` |
| `POST` | `/v1/admin/credentials/certificates` |
| `GET` | `/v1/admin/credentials` |
| `DELETE` | `/v1/admin/credentials/{credential_id}` |
| `POST` | `/v1/admin/integrations` |
| `GET` | `/v1/admin/integrations` |
| `DELETE` | `/v1/admin/integrations/{integration_id}` |

## 13. Recomendações para integrações e agentes de IA

1. Consulte `openapi.json` para tipos canônicos e mudanças de versão.
2. Nunca interprete `cases: []` sem examinar `coverage`.
3. Preserve `run_id`, `job_id`, `X-Request-Id`, fontes, `match_basis` e confiança em logs internos.
4. Use jobs e idempotência em rotinas longas.
5. Não repita automaticamente operações `full_docket` bloqueadas por desafio interativo.
6. Não envie PFX, senhas, tokens ou documentos restritos para modelos externos.
7. Exiba ao advogado a fonte, o tribunal, a data e o grau de confiança.
8. Trate sugestões de jurisprudência como apoio revisável, não como conclusão jurídica.
9. Em webhooks, valide HMAC sobre o corpo bruto e deduplique pelo callback ID.
10. Antes de automatizar um endpoint novo, confira o catálogo `/v1/sources` e o estágio real de cobertura.

## 14. Recursos oficiais

- Documentação humana: `https://provjud.com/documentacao`
- Markdown integral: `https://provjud.com/provjud-api.md`
- Índice para LLMs: `https://provjud.com/llms.txt`
- Swagger: `https://api.provjud.com/docs`
- ReDoc: `https://api.provjud.com/redoc`
- OpenAPI JSON: `https://api.provjud.com/openapi.json`
- Console administrativo: `https://api.provjud.com/admin`
