Quando usar
Use este endpoint para cadastrar um destino de webhook e receber eventos da plataforma em tempo real. Você pode usar quando quiser reagir automaticamente a mudanças de status de relatório, conclusão de processamento ou eventos operacionais sem depender de polling.Autenticação
Bearer JWT no headerAuthorization.
Corpo da requisição
{
"type": "REPORT_FINISHED",
"url": "https://webhook-test.com/a0a7aadb8de3e",
"apiKey": "xxx-xxx-xxx"
}
type(obrigatório): um dos tipos de webhook abaixo. Cada webhook escuta um único tipo; para receber mais de um, cadastre webhooks separados.url(obrigatório): endpoint HTTPS que receberá oPOST.apiKey(opcional): se informado, a GYRA+ envia esse valor no headerapi-keyde cada requisição, para o seu endpoint validar a origem.
Tipos de webhook
Cada disparo é umPOST com o envelope { organizationId, webhookType, data }. O que muda entre os tipos é quando dispara e o conteúdo de data:
type | Quando dispara | O que vem em data |
|---|---|---|
REPORT_FINISHED | Relatório totalmente processado (todas as integrações concluíram). É o evento mais usado. | reportId, policyId, isFinalized, finalizedAt e, se houve falha parcial, errors.sections[]. |
REPORT | A cada seção concluída durante o processamento (granular, vários disparos por relatório). | Os dados da seção concluída em content. |
REPORT_STATUS | Decisão manual (analista aprovou/rejeitou via analyze/re-analyze). | reportId e analysis com status (REPORT_APPROVED/REPORT_REJECTED), autor e data. |
REPORT_EXPORTED | Exportação do relatório (PDF ou XLS) ficou pronta, ou falhou. | reportId, exportUrl (assinada) e exportedAt. Em falha, exportUrl vem null e há error. |
CREDIT_POLICY | Política de crédito avaliada (resultado final do motor de regras). | reportId, policyId, version, status, risk, score, date. |
COMMITTEE_FINISHED | Comitê de Crédito IA concluiu (ou falhou) a deliberação do relatório, seja ela automática ou convocada manualmente. | reportId, status, decision, synthesis, deliberationId, finishedAt. Em falha, status vem ERROR e há error. |
OPERATION | Operação (fluxo multi-relatório com cadeia de políticas) concluiu com status final. | operationId, operationResultId, document, status. |
OPTIN | Reservado para o fluxo de opt-in de onboarding. | Conforme o fluxo de onboarding contratado. |
O que cada tipo retorna em data
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "REPORT_FINISHED",
"data": {
"content": {
"reportId": "6612a7f30000000000000001",
"policyId": "6612a7f30000000000000010",
"isFinalized": true,
"finalizedAt": "2026-04-23T14:30:45Z",
"errors": { "sections": ["PROCESSES"] }
},
"compress": false
}
}
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "CREDIT_POLICY",
"data": {
"content": {
"reportId": "6612a7f30000000000000001",
"policyId": "6612a7f30000000000000010",
"version": 3,
"status": "APPROVED",
"risk": "LOW",
"score": 720,
"date": "2026-04-23T14:30:45Z"
}
}
}
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "COMMITTEE_FINISHED",
"data": {
"content": {
"reportId": "6612a7f30000000000000001",
"status": "DONE",
"decision": "APPROVED",
"synthesis": {
"decision": "APPROVED",
"resumo": "Aprovar com ressalvas: caixa e histórico sustentam a operação.",
"reasoning": "Seis dos sete agentes recomendaram aprovação...",
"proximaAcao": "Solicitar garantia adicional antes do desembolso.",
"conditions": ["Garantia adicional de 20% do limite"],
"confidence": 0.82,
"alcadaLevel": null
},
"deliberationId": "6612a7f30000000000000900",
"finishedAt": "2026-07-30T14:31:12.004Z"
}
}
}
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "REPORT_STATUS",
"data": {
"reportId": "6612a7f30000000000000001",
"analysis": {
"userId": "user-id-ou-'Política de crédito'",
"userName": "Nome do analista",
"status": "REPORT_APPROVED",
"date": "2026-04-23T14:35:00Z"
}
}
}
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "REPORT_EXPORTED",
"data": {
"reportId": "6612a7f30000000000000001",
"exportUrl": "https://...url-assinada...",
"exportedAt": "2026-04-23T14:40:00Z"
}
}
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "OPERATION",
"data": {
"operationId": "6612a7f30000000000000100",
"operationResultId": "6612a7f30000000000000101",
"document": "43591367000130",
"status": "APPROVED"
}
}
{
"organizationId": "6612a7f30000000000000001",
"webhookType": "REPORT",
"data": {
"content": { "...dados da seção concluída..." },
"compress": false
}
}
Para a maioria das integrações, escute
REPORT_FINISHED (resultado pronto) e/ou CREDIT_POLICY (decisão). Use REPORT apenas se precisar de atualizações seção a seção. Se a sua política usa o Comitê de Crédito IA, adicione COMMITTEE_FINISHED. Visão geral e boas práticas em Webhooks e tempo real.Os webhooks da organização são copiados para o relatório no momento em que ele é criado. Um webhook
COMMITTEE_FINISHED registrado depois da criação não dispara para relatórios que já existiam. Registre o webhook antes de começar a criar relatórios que vão a comitê.A URL é validada com um POST de verdade antes de ser salva. No cadastro, a GYRA+ envia para a sua URL um
POST com o corpo {"message": "Teste de webhook cadastrado com sucesso!"} e, se você informou apiKey, o header api-key. Se essa chamada falhar por qualquer motivo (endpoint fora do ar, timeout, status de erro), o cadastro é recusado com 400 "URL de webhook inválida.".Ou seja: o seu endpoint precisa estar no ar e respondendo 2xx no momento do cadastro, e precisa tolerar esse payload de teste, que não tem o envelope { organizationId, webhookType, data } dos eventos reais.curl --location 'https://gyra-core.gyramais.com.br/webhook' \
--header 'Authorization: Bearer {seu_token_jwt}' \
--header 'Content-Type: application/json' \
--data-raw '{
"type": "REPORT_FINISHED",
"url": "https://webhook-test.com/a0a7aadb8de3e",
"apiKey": "xxx-xxx-xxx"
}'
fetch("https://gyra-core.gyramais.com.br/webhook", {
method: "POST",
headers: {
"Authorization": "Bearer {seu_token_jwt}",
"Content-Type": "application/json",
},
body: JSON.stringify({
"type": "REPORT_FINISHED",
"url": "https://webhook-test.com/a0a7aadb8de3e",
"apiKey": "xxx-xxx-xxx"
})
})
.then(res => res.json())
.then(console.log)
import requests
url = "https://gyra-core.gyramais.com.br/webhook"
headers = {
"Authorization": "Bearer {seu_token_jwt}"
}
payload = {
"type": "REPORT_FINISHED",
"url": "https://webhook-test.com/a0a7aadb8de3e",
"apiKey": "xxx-xxx-xxx"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
{
"id": "6612a7f32f90990d00000000",
"createdAt": "2026-07-31T18:02:54.965Z",
"updatedAt": "2026-07-31T18:02:54.965Z",
"organizationId": "6612a7f3fa9e086b00000000",
"type": "REPORT_FINISHED",
"url": "https://seu-sistema.com/webhooks/gyra",
"apiKey": "teste-doc"
}
{
"code": 400,
"message": "type must be one of the following values: REPORT, OPTIN, CREDIT_POLICY, REPORT_STATUS, REPORT_FINISHED, REPORT_EXPORTED, COMMITTEE_FINISHED, OPERATION,type should not be empty,url should not be empty,url must be a string"
}
{
"code": 401,
"message": "Token de acesso inválido."
}

