Uma API que pode ler antes de assinar.
A especificação é pública, as superfícies são neutras, a assinatura dos webhooks verifica-se em dez linhas do seu lado. Esta página documenta o que a API expõe hoje — nada mais, e isso é deliberado: o que não está entregue não está documentado.
- Especificação OpenAPI legível sem chave nem conta
- Nunca uma comunicação de operação suspeita, nunca conteúdos literais de clientes
- Webhooks assinados, verificáveis fora da Vigilae
Servida pela própria API: o contrato que lê é o que está a correr.
Superfícies neutras, por construção.
A API expõe o que um integrador pode consumir sem tocar no segredo dos processos: o diário de monitorização e contadores. O conteúdo de um processo de vigilância, os documentos, as comunicações de operações suspeitas não transitam por esta API — não é uma limitação de plano, é a arquitetura.
Diário de monitorização
Os eventos pKYC do gabinete — documento caducado, alteração de beneficiário efetivo, re-triagem a rever — em forma neutra: sequência, tipo, severidade, data. Respostas sempre limitadas a 500 eventos.
Agregados de carteira
Contadores, nunca um processo: volumes por estado, prazos, completude. O suficiente para desenhar um painel na sua ferramenta sem que um único dado de cliente lá entre.
Qualificação
A única escrita: qualificar um evento do diário (estado qualifie ou clos, disposição planifie, traite ou ecarte). Exige o scope de escrita — o menor privilégio é a regra, não uma opção.
A API foi concebida servidor-a-servidor: uma chave em código enviado para o navegador é uma chave publicada. Deixe a chave num proxy do lado do servidor, nunca na página.
Chaves com scopes delimitados, mostradas uma única vez, revogáveis de imediato.
- Formato. Cada chave começa por
vgk_e é enviada comoAuthorization: Bearer vgk_…. O segredo só é mostrado na criação: não conservamos senão o seu digest SHA-256. - Scopes.
lecture(leitura, por defeito) eecriture(escrita). Uma chave sem o scope necessário recebe um 403 — ver #scopes. - Validade. Um ano após a criação (visível na consola do gabinete). Uma chave caducada recebe um 401 explícito — ver #cle-expiree.
- Débito. 60 pedidos/minuto por chave (ajustável por chave). Um 429 transporta
Retry-Aftere os cabeçalhosX-RateLimit-Limit / -Remaining / -Reset. - Revogação. Imediata, a partir da consola. A resolução faz-se por digest: as chaves não podem ser enumeradas.
Três chamadas curl e viu tudo.
# Estado de saúde + autenticação da chave
curl -s https://vigilae.org/api/v1/sante \
-H "Authorization: Bearer vgk_a_sua_chave"
# Diário de monitorização, desde o início, em páginas de 100
curl -s "https://vigilae.org/api/v1/evenements?depuisSeq=0&limite=100" \
-H "Authorization: Bearer vgk_a_sua_chave"
# Qualificar o evento 42 (scope de escrita)
curl -s -X POST https://vigilae.org/api/v1/evenements/42/qualifier \
-H "Authorization: Bearer vgk_a_sua_chave" \
-H "Content-Type: application/json" \
-d '{"statut":"qualifie","disposition":"traite"}'Paginação, numa só regra
Passe depuisSeq (0 na primeira chamada) e limite (com teto em 500): a resposta vem ordenada por seq ascendente e devolve prochainSeq, a repassar tal e qual na chamada seguinte. Uma página mais curta do que limite significa o fim do diário — prochainSeq mantém-se então estável e serve de cursor de polling. Sem depuisSeq, obtém a vista «mais recentes primeiro», limitada a 500.
A carteira consulta-se em /api/v1/portefeuille/agregats — contadores, uma resposta, sem paginação.
Assinados, com carimbo temporal, entregues pelo menos uma vez.
Em vez de fazer polling ao diário, receba-o: a Vigilae entrega os eventos no seu URL, por ordem, em lotes de 100 no máximo. A entrega é at-least-once — o cursor só avança com o seu 2xx, lote a lote — e a idempotência faz-se por seq: processe cada sequência exatamente uma vez (#idempotence).
Verificar a assinatura
Cada entrega transporta o cabeçalho x-vigilae-signature: t=<unix>,v1=HMAC-SHA256(secret, t + "." + body). Recalcule v1 a partir do corpo bruto recebido e rejeite qualquer carimbo t além de 5 min: é essa a proteção anti-replay. Durante uma rotação do segredo, o cabeçalho transporta um v1 por cada segredo ainda válido (sobreposição de 24 h): aceite se qualquer um deles corresponder.
// Node — verificação da assinatura (sem dependências)
import { createHmac, timingSafeEqual } from 'node:crypto';
export function signatureValid(header, rawBody, secrets, toleranceMs = 5 * 60 * 1000) {
const t = Number((/(?:^|,)t=(\d+)/.exec(header) || [])[1]);
if (!t || Math.abs(Date.now() - t * 1000) > toleranceMs) return false; // anti-replay
const received = [...header.matchAll(/v1=([0-9a-f]{64})/g)].map((m) => m[1]);
return [].concat(secrets).some((secret) => {
const expected = createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex');
return received.some((r) => r.length === expected.length
&& timingSafeEqual(Buffer.from(r), Buffer.from(expected)));
});
}# Python — a mesma verificação
import hmac, hashlib, re, time
def signature_valid(header: str, raw_body: bytes, secrets, tolerance_s: int = 300) -> bool:
m = re.search(r"(?:^|,)t=(\d+)", header)
if not m or abs(time.time() - int(m.group(1))) > tolerance_s:
return False # anti-replay
received = re.findall(r"v1=([0-9a-f]{64})", header)
for secret in secrets:
expected = hmac.new(secret.encode(), m.group(1).encode() + b"." + raw_body,
hashlib.sha256).hexdigest()
if any(hmac.compare_digest(expected, r) for r in received):
return True
return FalseTransitório: o formato antigo sha256=HMAC(body) continua a ser emitido em x-vigilae-signature-legacy para os recetores já instalados; a sua remoção está prevista com os webhooks v2. Os recetores novos verificam o esquema com carimbo temporal acima, não o antigo.
A rotação dispara-se a partir da consola (POST /connect/webhook/rotation do lado da aplicação): durante 24 h o segredo antigo continua a assinar — tempo para instalar o novo do seu lado sem janela de falha.
Sandbox: a pedido.
Cada classe de erro da API tem um endereço estável na referência de erros: #authentification, #scopes, #cloisonnement, #debit, #signature… As respostas de erro da API apontarão para estas âncoras.
A API não expõe comunicações de operações suspeitas nem conteúdos literais de clientes, por construção (art. L.561-18 do CMF francês). Nenhuma decisão de vigilância é tomada pela API: expõe e qualifica eventos; o profissional decide.