Data
auxiliar.ai — Brazilian credit check API (CPF score + judicial + óbito + sanctions)
Bundled CPF credit screening for the Brazilian rental, fintech, and lending vertical. One auth surface, four upstreams: QUOD score band (Direct Data, paid), óbito flag (Direct Data, paid, permanent cache), judicial processes (Direct Data, paid, 7-day cache), federal sanctions (CGU + TCU, free anonymous). Free tier returns the same field names as paid with reduced depth — strict subset, so devs build against free and add a token later without refactoring response handlers.
When to use auxiliar.ai — Brazilian credit check API (CPF score + judicial + óbito + sanctions)
Choose if
Your app integrates Brazilian CPF credit screening — rental platform, fintech KYC, lending onboarding, supplier-onboarding for regulated vendors. Pick this when you want (a) one auth surface for QUOD score + dossier + óbito + judicial + federal sanctions instead of four vendor accounts, (b) a free anonymous starting point that returns the same field shape your paid handler will see (no refactor), (c) predictable per-call pricing with no monthly minimum, (d) explicit Lei 12.414/2011 + LGPD posture documented at the response level so your DPO doesn't have to re-derive it.
Avoid if
You only need one upstream (e.g. just QUOD score, no judicial / no sanctions). Hit Direct Data directly via app.directd.com.br — one vendor account is simpler than two. Or, your screening volume is >10k CPFs/day with steady throughput — at that scale, negotiate directly with QUOD or Serasa for a flat-rate enterprise contract.
Risk Flags
- HIGH regulatory The QUOD score from Direct Data is Cadastro Positivo data (Lei 12.414/2011). It can be used internally to decide acceptance/ rejection but MUST NOT be re-disclosed to the screened individual, to the requester (e.g. landlord), or to any third party. If the tenant asks "what was my score", direct them to QUOD's consumer portal. The same applies to the full CPF dossier and judicial detail (Direct Data ToS §7.4 forbids re-disclosure via "análises, estudos, ou outros meios"). Paid-tier callers sign acceptance of these terms during token mint.
- MEDIUM regulatory LGPD legitimate-interest basis is valid for credit-screening use cases (Art. 7º, IX combined with Lei 12.414/2011) but documents must record the basis at the request layer. The bearer-token tier stamps each call with the caller's tenant_id; keep your own access logs aligned to your DPO's retention policy.
- MEDIUM data_freshness Sanctions data is sourced from CGU's Portal da Transparência daily bulk dumps + TCU's open-data CSV. Lag is typically <48h but can stretch over weekends/holidays. For real-time fraud detection (a sanction added today), pair with a webhook from the upstream registries; this capability does not subscribe to those.
- LOW vendor_lockin The free-tier rating-action portion uses S&P Brazil only (Moody's and Fitch press releases are subscription-walled). For a multi-agency view, the paid tier composes external rating provider calls — cost passes through, response normalization is auxiliar's job.
Cost
Type: Freemium · Free tier: Anonymous tier (no signup, no token) returns the federal-sanctions portion: CGU CEIS/CNEP/CEPIM/Acordos-Leniência + TCU Inidôneos lookup by CPF, plus rating-action bands (S&P) when the subject is a CNPJ issuer. Same response shape as paid tier; HIGH_PII fields (raw QUOD score, óbito date, judicial-process detail, full CPF dossier) are returned as null with `"tier_required":"paid"` — strict subset, so your handler code is unchanged when you add a token. Rate-limited per IP (600 RPM shared anonymous pool). · Paid starts: Mint a bearer token via auxiliar.ai's onboarding flow (no contract minimum — pay-per-call). Per-call costs are vendor pass-through: Direct Data charges R$1.98 for the QUOD score, R$0.36 for the CPF dossier, R$0.36 for the óbito check, R$3.30 for judicial processes by CPF. Sanctions and rating-action lookups remain free at all tiers. A full bundled call (score + dossier + óbito + judicial + sanctions + rating) costs R$5.99 in upstream charges. Cached per (tenant_id, sub_tenant_id) at TTLs documented per-field below.
Hidden costs
- Per-call billing scales linearly with screening volume — at >1k CPFs/day, model ahead. The R$3.30 judicial lookup is the biggest line item; cache it for 7 days unless your use case requires fresher data.
- Anonymous tier rate limit (600 RPM shared) is fine for one-off integration testing but will throttle a real screening pipeline — token-mint upgrades you to 60 RPM external (per-user) or 6000 RPM internal.
- Direct Data tokens require a R$50 trial top-up at app.directd.com.br to activate. auxiliar.ai's bearer-token tier abstracts this — operator pays Direct Data once, devs see one bill.
- QUOD score is Lei 12.414/2011 (Cadastro Positivo) — internal-decisioning only. Re-display to end-users (e.g. showing the score on a tenant-facing page) is out of compliance. See LGPD posture below.
Install
Default
curl -X POST https://api.auxiliar.ai/api/invoke/sancoes_empresa -H "content-type: application/json" -d '{"documento": "12345678909"}'
# ============================================================
# FREE TIER — anonymous, no signup, no token
# Same response shape as paid; HIGH_PII fields = null + tier_required.
# ============================================================
curl -s -X POST https://api.auxiliar.ai/api/invoke/sancoes_empresa \
-H "content-type: application/json" \
-d '{"documento": "12345678909"}'
# → returns sanctions list. score/obito/judicial = null + tier_required:"paid".
#
# ============================================================
# PAID TIER — bearer token (mint at https://auxiliar.ai/account)
# One bundled screening = 4 invoke calls + 1 sanctions call:
# ============================================================
AUXILIAR_TOKEN="<your bearer token>"
CPF="12345678909"
#
# 1. QUOD score (R$1.98, 30d cache)
curl -s -X POST https://api.auxiliar.ai/api/invoke/directd_credit_score \
-H "Authorization: Bearer $AUXILIAR_TOKEN" \
-H "content-type: application/json" \
-d "{\"cpf\": \"$CPF\"}"
# 2. CPF dossier (R$0.36, 30d cache)
curl -s -X POST https://api.auxiliar.ai/api/invoke/directd_cpf_dossie \
-H "Authorization: Bearer $AUXILIAR_TOKEN" \
-H "content-type: application/json" \
-d "{\"cpf\": \"$CPF\"}"
# 3. Óbito (R$0.36, permanent cache)
curl -s -X POST https://api.auxiliar.ai/api/invoke/directd_obito \
-H "Authorization: Bearer $AUXILIAR_TOKEN" \
-H "content-type: application/json" \
-d "{\"cpf\": \"$CPF\"}"
# 4. Judicial processes (R$3.30, 7d cache)
curl -s -X POST https://api.auxiliar.ai/api/invoke/directd_processo_por_documento \
-H "Authorization: Bearer $AUXILIAR_TOKEN" \
-H "content-type: application/json" \
-d "{\"cpf\": \"$CPF\"}"
# 5. Federal sanctions (free, no token needed even on paid tier)
curl -s -X POST https://api.auxiliar.ai/api/invoke/sancoes_empresa \
-H "content-type: application/json" \
-d "{\"documento\": \"$CPF\"}"
#
# See https://auxiliar.ai/data/credit-score-cpf/ for the merged-
# response schema your handler should target, raw upstream samples
# per tool, judicial coverage matrix, and the LGPD/Lei 12.414/2011
# internal-decisioning-only constraint. A single bundled aggregate
# tool (one call → merged response) is roadmap-deferred — today's
# integration is 5 calls + client-side merge, billed per call.
Estimated time to first success: ~5 min
Claude code
claude mcp add auxiliar npx auxiliar-mcp
# In-loop dispatch via auxiliar-mcp (one MCP, four tool slugs):
invoke_capability(tool="sancoes_empresa", args={"documento": "12345678909"}) # free
invoke_capability(tool="directd_credit_score", args={"cpf": "12345678909"}) # paid
invoke_capability(tool="directd_cpf_dossie", args={"cpf": "12345678909"}) # paid
invoke_capability(tool="directd_obito", args={"cpf": "12345678909"}) # paid
invoke_capability(tool="directd_processo_por_documento", args={"cpf": "12345678909"}) # paid
# find_capability("rental-credit-screening") returns this YAML.
Claude desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"auxiliar": {
"command": "npx",
"args": ["-y", "auxiliar-mcp"]
}
}
}
Cursor
Add via Cursor's MCP settings UI or .cursor/mcp.json
{ "mcpServers": { "auxiliar": { "command": "npx", "args": ["-y", "auxiliar-mcp"] } } }
Openclaw
curl -X POST https://api.auxiliar.ai/api/invoke/sancoes_empresa -H "content-type: application/json" -d '{"documento": "..."}'
# OpenClaw / Telegram-bot / shell-bound agents call the gateway
# directly via HTTP. Same five POSTs as the curl snippet above.
# No MCP host required.
Dependencies
Minimum runtime: Any HTTP client (curl works).
Requires: auxiliar-mcp
Composes with: Auxiliar.ai CNPJ fetch (BrasilAPI → CNPJ.ws cascade), CNPJ.ws: free + commercial CNPJ lookup, CNPJá: CNPJ lookup (free cached + paid real-time), BrasilAPI: CNPJ lookup
Distribution
- Repository
- https://github.com/Tlalvarez/Auxiliar-ai
- License
- MIT (gateway code); upstream data per Direct Data ToS, CGU open-data, TCU open-data, S&P public press releases.
Read this before you ship — LGPD + Lei 12.414/2011
Internal-decisioning only. QUOD score, full CPF dossier, and per-process judicial metadata are Lei 12.414/2011 (Cadastro Positivo) data. Use them to derive an internal verdict (approve | require_fiador | extra_deposit | decline | manual_review) — do not re-display raw bureau fields to the screened individual, the landlord, or any third party. Direct Data ToS §7.4 binds the screening operator, not just auxiliar.
If your UI must show something to the requester: render the verdict + a generic explanation tag (high judicial exposure, low credit profile, name appears in federal sanctions registry) — never the raw fields. Sanctions is the exception — CGU and TCU registries are public open data under Lei 12.527/2011; safe to re-display. See LGPD legitimate-interest basis for DPO paperwork.
What this endpoint does
Bundled CPF credit screening for Brazilian rental, fintech, and lending. One auth surface composes four paid Direct Data upstreams + the free federal-sanctions surface:
| Field | Provenance | Tool slug | Tier | Cost (per call) | Cache TTL |
|---|---|---|---|---|---|
score.value (raw QUOD score, 0–1000) |
QUOD via Direct Data Score |
directd_credit_score |
paid (bearer) | R$1.98 | 30 days |
score.band (low/mid/high) |
derived from .value (or null on free tier) |
derived | both | (included) | 30 days |
obito.deceased (bool) + obito.date (ISO) |
Direct Data Obito |
directd_obito |
paid (bearer) | R$0.36 | permanent |
judicial.process_count + judicial.processes[] |
Direct Data ProcessosJudiciaisCompleta |
directd_processo_por_documento |
paid (bearer) | R$3.30 | 7 days |
dossie (full PII record) |
Direct Data CadastroPessoaFisicaPlus |
directd_cpf_dossie |
paid (bearer) | R$0.36 | 30 days |
sanctions.registros[] (CEIS, CNEP, CEPIM, Leniência, TCU Inidôneos) |
CGU Portal da Transparência + TCU open-data | sancoes_empresa |
free anonymous | R$0 | 24 hours |
rating.actions[] (issuer CNPJs only) |
S&P Brazil public press releases | rating_actions_brazil_recent |
free anonymous | R$0 | 24 hours |
A bundled screening is 5 round-trips to /api/invoke/{tool_slug} + client-side merge. An aggregate /api/invoke/credit_screen_cpf (single call, server-side merge) is on the roadmap — see Known limitations.
Required reading before production
This page documents the merged response shape, the decisioning rubric, and the LGPD posture. Two companion pages carry load-bearing detail your handler needs — fetch both before shipping:
→ Required:
/data/credit-score-cpf-upstream-shapes/— raw per-tool wire-format payloads (Score,Obito,ProcessosJudiciaisCompleta,CadastroPessoaFisicaPlus,sancoes_empresa,rating_actions_brazil_recent); verbatim camelCase keys returned insideresultbefore client-side merge. You cannot write the handler from this page alone.
→ Required:
/data/credit-score-cpf-judicial-detail/— every per-process field (natureza,natureza_codigo,valor_causa,transitado,arquivado,partes[],vara,tribunal), starter severity buckets, tribunal coverage gaps (STF / TJM / electoral), andsegredo de justiçaredaction. The rubric below references those buckets but does not define them.
Free vs paid: what you can actually test
What each tier proves:
| What you’re testing | Free anonymous | Paid bearer |
|---|---|---|
| Wiring (auth, request shape, error handling, parsing) | Yes | Yes |
| Field-name stability (paid is strict superset) | Yes | Yes |
| Federal-sanctions decisioning (CEIS / CNEP / CEPIM / Leniência / TCU) | Yes — real data | Yes |
| QUOD score, óbito, judicial, full dossier | No — null + tier_required: "paid" |
Yes |
| End-to-end accept / decline / fiador decisioning | No — sanctions only | Yes |
The free tier is a wiring harness — stand up the integration and exercise null-population edge cases without minting a token. Field NAMES are identical across tiers; HIGH_PII fields come back as null with a sibling tier_required: "paid" marker. You do not refactor when you add a token — values populate, shape doesn’t move. See the merged-shape integration contract for the exact free-tier replacement; sandbox CPF for full-shape validation is on the roadmap (see Known limitations).
Authentication
Bearer token in Authorization: Bearer <token> header.
Get a token
Mint a token at https://auxiliar.ai/account — sign in (OAuth: Google / GitHub / email passcode), open the Tokens tab, click Mint new token, name it (e.g. prod-rental-screening), copy the Bearer eyJ.... Token is shown once — store it in your runtime secret manager. No contract minimum; pay-per-call billing is invoiced monthly against the tenant_id the token stamps. Mint is dashboard-only today (programmatic mint is on the roadmap — see Known limitations).
Use the token
5-call sequence is in Install above (curl + bearer header). Anonymous tier (no header): sancoes_empresa and rating_actions_brazil_recent only — Direct Data tools return HTTP 403 (tier=anonymous barred from HIGH_PII).
Error shapes. 200 = success ({ tool, source_module, elapsed_ms, result, scope }); 400 = bad input (e.g. CPF not 11 digits); 403 = wrong tier; 404 = stale tool slug; 429 = rate-limited (anonymous 600 RPM shared, external 60 RPM/user, internal 6000 RPM — back off with jitter).
Recommendation rubric
auxiliar documents the data, not your policy — you own the policy. A defensible four-way default for rental screening; adjust to your portfolio.
Inputs (after the 5-call merge)
score.value— QUOD numeric, 0–1000. Decide off this, notfaixa_score.obito.deceased— boolean. Hard veto.judicial.process_count+ per-processnatureza/valor_causa/transitado— bucketed severe / moderate / light per the judicial-detail page.sanctions.resumo.ativas_count— count of active federal sanctions on CPF. Hard veto.dossie.situacao_cadastral—RegularvsSuspensa/Cancelada/Pendente de Regularização. Hard veto if notRegular.
→ Severity bucketing is your responsibility — the API does not classify. The judicial endpoint returns raw CNJ
naturezastrings andnatureza_codigocodes verbatim; auxiliar does not pre-classify them into severity tiers. The severe / moderate / light mapping in/data/credit-score-cpf-judicial-detail/is a recommended starter set — calibrate to your portfolio’s risk profile (a high-end rental in Jardins behaves differently from a Programa Casa Verde e Amarela unit). Build yournatureza-to-bucket lookup as a versioned table you own, then feed those buckets into the matrix below.
Hard vetoes — return decline immediately
| Signal | Why |
|---|---|
obito.deceased == true |
Tenant is deceased. |
sanctions.resumo.ativas_count >= 1 |
Active federal sanction. LGPD-public; safe to cite as decline reason. |
dossie.situacao_cadastral != "Regular" |
CPF is suspenso / cancelado / pendente. Receita Federal flag. |
judicial.processes[].natureza matches Despejo AND transitado == true AND dataTransitoJulgado within last 24 months |
Recent finalized eviction (res judicata). |
judicial.processes[].natureza matches Despejo AND transitado == false AND dataDistribuicao within last 24 months |
Recent filed eviction (action pending). Treat as hard veto; a despejo lawsuit filed in the last 24 months is decisioning-grade signal even before trânsito em julgado. |
Eviction-recency date-field choice. Prefer dataTransitoJulgado when present (eviction is final), fall back to dataDistribuicao when not (action filed but pending). Don’t key the recency window off dataAutuacao (registry bookkeeping) or statusDetalhes text — both are noisier. Normalize the chosen date to ISO before computing the 24-month window. See judicial-detail dates + status for field semantics.
Score × judicial matrix (apply if no hard veto fires)
QUOD score.value |
0 severe + 0 moderate | 0 severe + 1–2 moderate | 0 severe + 3+ moderate, OR ≥1 severe (open) |
|---|---|---|---|
| > 700 (high) | approve |
approve |
extra_deposit |
| 551–700 (mid) | approve |
require_fiador |
extra_deposit |
| 350–550 (low) | require_fiador |
extra_deposit |
decline |
| < 350 (very low) | extra_deposit |
decline |
decline |
Verdict semantics. approve — default deposit (typically 1× rent). require_fiador — proceed only if a guarantor passes a separate screening. extra_deposit — 2–3× rent caução (Lei 8.245/91 art. 38 caps at 3 months). decline — refuse; surface a generic tag, never raw bureau fields.
Tuning notes. Severe-bucket transitado == true within 24 months is near-veto regardless of score. Light-bucket judicial (e.g. Indenização por Dano Moral consumer cases) is informational, not matrix input. Re-screen on lease renewal. Log verdict + inputs against tenant_id for LGPD audit trails.
Sample paid-tier merged response
Result of merging the four /api/invoke/directd_* calls + sancoes_empresa. Until the aggregate ships, your handler does this client-side:
{
"cpf": "123.456.789-09",
"score": { "value": 742, "band": "high", "faixa_score": "Médio", "scoring_model": "QUOD", "calculated_at": "2026-04-28", "tier_required": null },
"obito": { "deceased": false, "date": null, "year": null, "source": "Direct Data / Cartório", "tier_required": null },
"judicial": {
"process_count": 1,
"processes": [
{ "numero": "0001234-56.2023.8.26.0100", "tribunal": "TJSP", "ambito": "Justiça Estadual",
"vara": "5ª Vara Cível Central", "data_distribuicao": "2023-04-15", "valor_causa": 25000.00,
"natureza": "Cobrança de Aluguéis - Sem Despejo", "natureza_codigo": "7691",
"segredo_justica": false, "transitado": false, "arquivado": false } ],
"tier_required": null
},
"dossie": { "nome_completo": "<redacted>", "renda_estimada": "<redacted>", "situacao_cadastral": "Regular", "tier_required": null },
"sanctions": { "registros": [], "resumo": { "cadastros_presentes": [], "total_registros": 0, "ativas_count": 0 },
"checked_at": "2026-04-30T14:22:11Z", "registries_consulted": ["CEIS","CNEP","CEPIM","LENIENCIA","TCU_INIDONEOS"] },
"rating": { "actions": [] },
"scope": { "tier": "external", "tenant_id": "<your tenant>", "billable_units": 5.99 }
}
scope.billable_units totals upstream pass-through cost in BRL: R$1.98 (score) + R$0.36 (dossier) + R$0.36 (óbito) + R$3.30 (judicial) + R$0 (sanctions) = R$5.99.
Two band views, one ground truth. band (low | mid | high) is derived client-side from numeric value (≤500 / 501–700 / >700); faixa_score is QUOD’s raw label. They can disagree on edges (742 → band: "high" even though QUOD returned "Médio") — decision off value, treat faixa_score as informational.
→ The merged shape above is the post-merge view. Each
/api/invoke/{tool_slug}returns its upstream’s raw camelCase wire format insideresult(e.g. Direct Data’smetaDados/retorno.pessoaFisica.score, notscore.value). For exact field paths and per-tool wire payloads, fetch/data/credit-score-cpf-upstream-shapes/before writing the mapper.
Code against the merged shape — that is the integration contract. The post-merge view above (with score, obito, judicial, dossie, sanctions, rating, scope) is what your handler stores, decisions on, and persists. On the free tier it is the same shape with score/obito/judicial/dossie each replaced by { ...nulls, tier_required: "paid" }, sanctions and rating populated, scope.tier == "anonymous". The raw per-tool wire payloads on /data/credit-score-cpf-upstream-shapes/ — including the standalone sancoes_empresa upstream payload — are reference material for writing the mapper and for debugging, not the integration contract. If you persist raw upstream JSON anywhere, treat it as a debug-tier artifact (different retention, different LGPD posture) — your business logic should only ever read the merged shape.
LGPD legitimate-interest basis (DPO paperwork)
(Operational rule is at the top of the page.) Legal basis: LGPD Art. 7º, IX + Lei 12.414/2011 — DPO records the basis at the request layer; the bearer token stamps each call with tenant_id. Retention: match your DPO policy (typical 5 years for credit-decisioning); auxiliar retains raw upstream responses only within per-tenant cache TTL. Subject-access (LGPD Art. 18): you cannot honor correção against upstream bureau data — direct subjects to QUOD, the tribunal, or CGU/TCU. Sanctions = public (Lei 12.527/2011); restrictions apply to score / dossier / judicial only.
Reliability + cost
Direct Data status at https://status.directd.com.br/ (typical 99.9%). Paid responses cached per (tenant_id, sub_tenant_id) at TTLs above; repeat lookups within TTL are zero-cost (elapsed_ms < 50). scope.billable_units is the upstream pass-through cost in BRL — no hidden per-call margin (flat per-tenant access fee separately). Gateway: https://github.com/Tlalvarez/Auxiliar-ai (MIT); tools at backend/sources/br/empresa/{direct_data,sancoes,rating_actions}.py.
Rate limits and backoff
Server-side (token-bucket per (tier, tenant_id, sub_tenant_id), refilled at RPM/60 per second; backend/gateway/rate_limit.py): anonymous 600 RPM shared, external bearer 60 RPM/token, internal 6000 RPM/token. Exhausted bucket returns 429 with {"detail": "<tier>-tier limit exceeded for <tenant>::<sub_tenant> (capacity=N req/min)"}. No Retry-After header is set today — the gateway doesn’t yet emit one (will land with rate-limit middleware hardening); until then, run client-side backoff blind.
Client-side backoff. Exponential with full jitter, header-independent: start 1s, double each retry (1, 2, 4, 8, 16), cap 30s, max 3–5 retries, total wall-clock budget ~60s — delay = random.uniform(0, min(30, 2**attempt)).
Idempotency. All directd_* plus sancoes_empresa / rating_actions_brazil_recent are read-only — no upstream state mutates, retries are safe. An in-TTL repeat hits the per-tenant cache (zero billable units), so a successful retry typically does not double-bill.
Retry only 429 / 502 / 503 / 504. Don’t retry 400 (fix the CPF), 403 (mint a paid token), or 404 (stale slug — refresh from GET /api/invoke). Each retry on a paid tool (directd_credit_score R$1.98, directd_processo_por_documento R$3.30, directd_obito / directd_cpf_dossie R$0.36 each) re-charges upstream pass-through after cache TTL expires — bound retries to protect spend.
Discovery
- MCP.
claude mcp add auxiliar npx auxiliar-mcp;find_capability("rental-credit-screening")returns this YAML;solve_task("CPF credit check")ranks this above hand-rolling. - Curl.
POST https://api.auxiliar.ai/api/invoke/{tool_slug}from any HTTP client. - Hub.
https://auxiliar.ai/data/credit-score-cpf/.
Cross-references
Companion pages: see Required reading before production. Related: auxiliar-cnpj-fetch (when the screened entity is a CNPJ); auxiliar-mcp (in-loop discovery surface).
Known limitations
- No single aggregate tool yet — 5 calls + client-side merge today. Aggregate
directd_credit_screen_cpf(single call, one billable unit) on the roadmap; trigger is Stripe agentic-system rollout for paid-scope auth. - No programmatic token-mint API. Token issuance is dashboard-only at
https://auxiliar.ai/account. ProgrammaticPOST /api/tokens/issueships paired with the Stripe agentic-auth rollout (same backlog entry as the aggregate tool). - Free tier cannot test paid-tier decisioning end-to-end. HIGH_PII fields come back
null. Sandbox CPF returning synthetic-but-real-shape data is on the roadmap, ships when the paid-tier auth path lands. bandis client-side derived today — moves server-side when the aggregate ships.- Judicial coverage broad, not 100%. STF / TJM / electoral courts surface inconsistently; sealed (segredo de justiça) processes return case number but redact
partes[]. Full coverage table on/data/credit-score-cpf-judicial-detail/. - CPF-keyed lookups go via POST
/api/invoke/, not GET/data/*— GET URLs log in too many places (CDN logs, history, referers). - No webhook / streaming — poll-only. For sanction-added webhooks, subscribe to CGU’s RSS/Atom directly.