Ir al contenido

Referencia de la API de FPP

Este documento describe cómo integrarse con la API de prevención del fraude de Guardline. Cubre la autenticación, el envío de transacciones para análisis, la interpretación de las decisiones, la recepción de notificaciones por webhook y el manejo del ciclo de vida completo de la decisión.

El modelo de integración sigue una separación clara de responsabilidades: Guardline decide y señaliza, el integrador ejecuta. Guardline nunca accede directamente al core bancario. Todas las acciones (retenciones cautelares, bloqueos de cuenta) se comunican mediante respuesta síncrona o webhook, y el integrador es responsable de ejecutarlas.

Todas las solicitudes a la API deben incluir una clave de API válida en el encabezado X-API-Key.

X-API-Key: gl_live_your_api_key_here

Las claves de API son provisionadas por el equipo de Guardline y tienen alcance por entorno (sandbox, producción). Mantenga su clave de API confidencial. Si se ve comprometida, contacte a Guardline de inmediato para rotarla.

Además del alcance por entorno, las claves de API llevan uno o más alcances de permiso que controlan el acceso a grupos específicos de endpoints. Cada sección de endpoint de este documento indica el alcance que requiere, cuando corresponde. Contacte a Guardline para habilitar alcances adicionales en su clave.

Todos los endpoints requieren HTTPS. Las solicitudes HTTP serán rechazadas.

Envíe una transacción para el análisis de fraude en tiempo real. Este es el endpoint principal de integración.

POST /api/v2/decisions/analyze

Content-Type: application/json

Estos cinco campos son obligatorios en toda solicitud de análisis. Tenga en cuenta que no se requiere ningún registro previo del cliente. Guardline intentará enriquecer el contexto buscando los datos del cliente mediante el accountId, pero si no se encuentra ningún cliente, el análisis continúa normalmente con los datos provistos en la solicitud.

CampoTipoDescripción
transactionIdstringIdentificador único de la transacción en su sistema. Se usa para la idempotencia (las solicitudes duplicadas devuelven la decisión original). Recomendamos un patrón como TX-YYYYMMDD-NNNNNNNN.
accountIdstringIdentificador de la cuenta en su sistema. Se usa para buscar los datos del cliente (si fue registrado previamente) y para correlacionar transacciones en el análisis de velocidad y comportamiento.
transactionTypestringCódigo del tipo de transacción. Crítico para el enrutamiento del flujo de trabajo: el motor de fraude usa este campo para determinar qué flujo de trabajo ejecutar. Para transacciones PIX, use PIX. Los demás tipos admitidos dependen de su configuración.
transactionDatestringMarca de tiempo ISO 8601 con zona horaria (por ejemplo, 2026-03-08T14:30:00-03:00). Se usa para el análisis temporal y el cálculo del SLA.
totalAmountstringImporte de la transacción como cadena decimal (por ejemplo, "15000.00"). Use el punto como separador decimal, sin separador de miles.

Estos campos son opcionales. Cuanto más contexto se proporcione, más preciso será el análisis de fraude. El integrador decide qué bloques incluir según los datos disponibles.

CampoTipoDescripción
accountHolderIdstringMuy recomendado. CPF o CNPJ del titular de la cuenta (por ejemplo, 12345678900). La resolución de identidad se basa en la cantidad de dígitos una vez quitada la puntuación: 11 dígitos se tratan como CPF, 14 como CNPJ, y cualquier otra longitud se ignora a efectos de resolución. Habilita la resolución de identidad del cliente, las baselines de comportamiento, el análisis de velocidad y el perfilado de riesgo. Sin este campo, cada transacción se evalúa de forma aislada, sin historial del cliente. En una transacción entrante este es el documento del receptor, no el del pagador (consulte PIX In).
currencystringCódigo de moneda ISO 4217 (predeterminado: BRL)
channelstringCanal de origen (MOBILE, WEB, API)
countrystringCódigo de país ISO 3166-1 alfa-2
metadataobjectMetadatos de la transacción (dirección, estado)
customerobjectDatos del perfil del cliente
counterPartobjectInformación de la contraparte (beneficiario)
deviceobjectHuella digital y señales del device
locationobjectGeolocalización e inteligencia de IP
instantPaymentobjectDatos específicos de PIX, incluido DICT (ver abajo)
riskSignalsobjectPuntajes y señales de riesgo preexistentes
complianceobjectIndicadores de cumplimiento

Los bloques adicionales (location, riskSignals, compliance) siguen el mismo principio: envíe lo que esté disponible y omita lo que no. La estructura de campos de estos bloques se definirá de forma colaborativa durante la configuración de la integración, según los datos que el integrador pueda proporcionar.

El payload de la solicitud es flexible por diseño. Más allá de los cinco campos obligatorios (transactionId, accountId, transactionType, transactionDate, totalAmount), el integrador controla qué bloques opcionales incluir y qué campos completar dentro de cada bloque.

No se requiere registro previo: no necesita crear clientes, cuentas ni ninguna otra entidad antes de enviar transacciones. Guardline hará lo siguiente:

  1. Enriquecer automáticamente: si en la base de datos de Guardline existe un cliente con el accountId indicado (por registros o sincronizaciones previas), se usarán los datos de su perfil para mejorar el análisis.
  2. Resolver por documento: si ningún cliente coincide con el accountId pero accountHolderId contiene un CPF o CNPJ válido, Guardline buscará al cliente por documento. Si lo encuentra, se usa su perfil para el análisis. Si no lo encuentra, Guardline inscribe automáticamente al cliente para que las transacciones futuras acumulen historial y líneas base de comportamiento.
  3. Continuar sin datos del cliente: si no se encuentra ningún cliente por ninguno de los dos métodos, el análisis se ejecuta con los datos provistos en la solicitud. Las reglas que dependen de atributos del cliente simplemente no coincidirán.
  4. Usar los datos de la solicitud: si incluye el bloque customer en la solicitud, esos datos tienen prioridad y se usan directamente.

La estructura de cada bloque opcional (customer, counterPart, device, location, instantPayment, riskSignals, compliance) la define Guardline, pero el integrador decide qué bloques son relevantes para su caso de uso y qué campos puede proporcionar. Las reglas de fraude se configuran para funcionar con los datos disponibles. Los campos que no se envían simplemente no se evalúan.

El ejemplo siguiente es una referencia que muestra un escenario realista de PIX Out. El payload real debe adaptarse a los datos disponibles en los sistemas del integrador.

{
"transactionId": "TX-20260308-00001234",
"accountId": "ACC-00086",
"accountHolderId": "12345678900",
"transactionType": "PIX",
"transactionDate": "2026-03-08T14:30:00-03:00",
"totalAmount": "15000.00",
"currency": "BRL",
"channel": "MOBILE",
"country": "BR",
"metadata": {
"direction": "OUT",
"status": "pending",
"originSystem": "IPAY"
},
"customer": {
"age": 42,
"kycStatus": "approved",
"kycLevel": "complete",
"riskScore": 15.0,
"riskLevel": "low",
"isPEP": false,
"country": "BR",
"accountAgeDays": 730,
"accountStatus": "active",
"isNewCustomer": false
},
"counterPart": {
"name": "Maria Santos",
"taxIdentifier": {
"taxId": "987.654.321-00",
"country": "BR"
},
"isNewCounterpart": true,
"transactionsCount": 0,
"isSameNetwork": false
},
"device": {
"id": "DEV-9f8e7d6c",
"type": "mobile",
"os": "android",
"isNewDevice": false,
"isTrustedDevice": true,
"ipAddress": "189.44.120.33"
},
"instantPayment": {
"keyType": "cpf",
"keyValue": "987.654.321-00",
"endToEndId": "E60701190202603081430abcd1234ef",
"initiationMethod": "DICT",
"payer": {
"ispb": "60701190",
"ispbName": "Itaú Unibanco S.A.",
"document": "123.456.789-00",
"branch": "0001",
"account": "12345-6",
"name": "João Oliveira"
},
"receiver": {
"ispb": "00000000",
"ispbName": "Banco do Brasil S.A.",
"document": "987.654.321-00",
"branch": "3456",
"account": "78901-2",
"name": "Maria Santos"
},
"dict": {
"keyCreationDate": "2024-06-15T00:00:00Z",
"keyOwnershipDate": "2024-06-15T00:00:00Z",
"accountType": "CACC",
"accountOpeningDate": "2023-01-10T00:00:00Z",
"pspName": "Banco do Brasil S.A.",
"pspIspb": "00000000",
"fraudMarkersCount": 0,
"infractionCount": 0,
"isFlagged": false,
"claimsCount": 0,
"portabilityCount": 0,
"correlationId": "A20260308143052899607011905AD7C8",
"registeredAccounts": "1",
"naturalPersonAntifraudPercentage": 0,
"legalPersonAntifraudPercentage": 0,
"spi": {
"d90": "0",
"m12": "0",
"m60": "0"
},
"reports": {
"openReports": "0",
"distinctReports": "0",
"rejectedD90": "0",
"rejectedM12": "0",
"rejectedM60": "0"
},
"frauds": []
}
}
}

Si el mismo transactionId se envía más de una vez, Guardline devuelve la decisión original sin volver a procesarla. La respuesta incluye "idempotent_replay": true para indicarlo.

Esto permite reintentos seguros ante un tiempo de espera de red, sin riesgo de procesamiento duplicado.

Los tres escenarios (ALLOW, REVIEW, BLOCK) devuelven la misma estructura de respuesta. Este es el formato de payload unificado que se usa en toda la plataforma, tanto en las respuestas síncronas como en los webhooks.

Las respuestas de la API se envuelven en un envoltorio estándar:

{
"error": false,
"data": { ... }
}

El campo data contiene el payload de decisión descrito a continuación. Las respuestas de error usan "error": true (ver Manejo de errores).

CampoTipoSiempre presenteDescripción
idUUIDsíIdentificador único de la decisión
transaction_idUUIDsíIdentificador interno de la transacción
workflow_idUUIDsíFlujo de trabajo que procesó la transacción
workflow_namestringsíNombre del flujo de trabajo
workflow_versionintegersíVersión del flujo de trabajo
assessmentstringsíResultado de la decisión: ALLOW, REVIEW, BLOCK o ESCALATE. Las respuestas síncronas solo llevan ALLOW, REVIEW o BLOCK (el motor no produce ESCALATE). ESCALATE aparece exclusivamente en el evento de webhook en que un analista escala un caso en REVIEW (ver Cuándo se envían los webhooks).
scorenumbersíPuntaje de riesgo final (0-100)
thresholdsobjectsíUmbrales aplicados (revisión y bloqueo)
resolution_sourcestringsíQuién tomó la decisión (ver abajo)
reason_codestringnoCódigo de motivo estructurado de la decisión (ver abajo)
reason_descriptionstringnoDescripción legible del motivo
actionsarraynoAcciones a ejecutar (ver abajo)
review_infoobjectnoPresente solo cuando assessment es REVIEW
execution_time_msintegersíTiempo de procesamiento del motor en milisegundos
analysis_time_msintegersíTiempo total de análisis, incluido el enriquecimiento
created_atdatetimesíMarca de tiempo ISO 8601
idempotent_replaybooleannotrue si esta es una respuesta reproducida
sources_loadedobjectnoFuentes de datos cargadas con éxito
source_errorsobjectnoFuentes de datos que no se pudieron cargar
explanationobjectsíDesglose del puntaje por etapa
ValorSignificado
ENGINEDecisión automática del motor de fraude (respuesta síncrona y, opcionalmente, un webhook cuando el flujo de trabajo vincula send_webhook al tipo de decisión resuelto)
ANALYSTDecisión manual de un analista en la mesa de operaciones (webhook)
SLA_TIMEOUTResolución automática de respaldo por vencimiento del SLA (webhook)

Los campos reason_code y reason_description aportan contexto sobre por qué se tomó la decisión. Esto es crítico para los reportes regulatorios (R6, MED) y para determinar cómo ejecutar las acciones señalizadas.

En las respuestas síncronas (resolution_source: "ENGINE"), el código de motivo refleja la evaluación automatizada del motor. Esa misma evaluación del motor también puede entregarse como webhook cuando el flujo de trabajo vincula send_webhook al tipo de decisión resuelto; en ese caso, el cuerpo del webhook lleva el mismo código de motivo que la respuesta síncrona. En las resoluciones por webhook (resolution_source: "ANALYST" o "SLA_TIMEOUT"), refleja el criterio del analista o la política de tiempo de espera.

OrigenEjemplo de reason_codeEjemplo de reason_description
ENGINEHIGH_RISK_SCORETransacción bloqueada por puntaje de riesgo alto
ENGINELOW_RISKTransacción aprobada con riesgo bajo
ANALYSTCONFIRMED_FRAUDEl analista confirmó actividad fraudulenta
ANALYSTCUSTOMER_CONFIRMEDEl cliente confirmó que la transacción es legítima
ANALYSTSUSPICIOUS_UNCONFIRMEDActividad sospechosa, evidencia insuficiente para confirmar el fraude
ANALYSTFALSE_POSITIVEEl análisis determinó que la alerta era un falso positivo
SLA_TIMEOUTSLA_TIMEOUT_AUTO_APPROVEDAprobada automáticamente por vencimiento del SLA

El conjunto de códigos de motivo no es fijo. Pueden introducirse códigos nuevos a medida que evolucionen las necesidades operativas. El integrador debe tratar reason_code como una cadena de formato libre y manejar con tolerancia los valores desconocidos. El campo reason_description siempre ofrece una explicación legible, sea cual sea el código.

Ambos campos son null cuando no aplican (por ejemplo, en la respuesta síncrona inicial de REVIEW, donde aún no se conoce el motivo final).

Las acciones representan efectos secundarios que el integrador debe ejecutar. Cada acción tiene un type y parameters opcionales.

Tipo de acciónDescripciónParámetros
CAUTIONARY_HOLDCongelar los fondos acreditados por hasta 72 horas (Resolución BCB 142/2021). Se debe notificar al titular de la cuenta.duration_hours (integer)
ACCOUNT_BLOCKSuspensión preventiva de la cuenta.ninguno
BLOCK_BENEFICIARYBloquear a la contraparte (beneficiario) para transacciones futuras.ninguno
BLOCK_DEVICEBloquear el device usado en la transacción.ninguno
ADD_TO_WATCHLISTAgregar al cliente a una lista restrictiva de monitoreo para un escrutinio reforzado en transacciones futuras.ninguno
CAUTIONARY_HOLD_CLEARLiberar una retención cautelar aplicada previamente; levantar el congelamiento temporal de los fondos acreditados. Se emite en el evento de webhook en que un analista libera la retención cautelar y en las resoluciones de caso del analista en que este activa el indicador de liberación.ninguno
ACCOUNT_BLOCK_CLEARLiberar un bloqueo preventivo de cuenta aplicado previamente; restaurar la cuenta al estado activo. Se emite en el evento de webhook en que un analista libera el bloqueo de cuenta y en las resoluciones de caso del analista en que este activa el indicador de liberación.ninguno

Presente solo cuando assessment es REVIEW. Aporta información para notificar al usuario final.

CampoTipoDescripción
estimated_resolution_minutesintegerTiempo estimado para la resolución (28 o 58 minutos)
review_reasonstringMotivo genérico apto para una notificación de cara al usuario
tracking_idUUIDIdentificador para que el usuario haga seguimiento del caso
{
"error": false,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"transaction_id": "f9e8d7c6-b5a4-3210-fedc-ba0987654321",
"workflow_id": "11223344-5566-7788-99aa-bbccddeeff00",
"workflow_name": "pix_out_standard",
"workflow_version": 3,
"assessment": "ALLOW",
"score": 12.5,
"thresholds": {
"review_threshold": 45.0,
"block_threshold": 80.0,
"adjustments": []
},
"stages_executed": 4,
"stages_total": 4,
"early_terminated": false,
"execution_time_ms": 23,
"analysis_time_ms": 45,
"explanation": {
"stages": [
{ "name": "identity_verification", "score": 0 },
{ "name": "transaction_patterns", "score": 5.0 },
{ "name": "counterpart_analysis", "score": 7.5 },
{ "name": "device_signals", "score": 0 }
]
},
"created_at": "2026-03-08T17:30:00.123Z",
"resolution_source": "ENGINE",
"reason_code": "LOW_RISK",
"reason_description": "Transaction approved with low risk",
"actions": [],
"sources_loaded": {
"customer": true,
"counterpart": true,
"device": true,
"dict": true,
"datarudder": true
},
"enrich_time_ms": 18,
"eval_time_ms": 23
}
}

Cuando la decisión es REVIEW, la transacción queda retenida para análisis manual. El integrador no debe procesar la transacción y debe informar al usuario final que está en revisión.

{
"error": false,
"data": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210",
"workflow_id": "11223344-5566-7788-99aa-bbccddeeff00",
"workflow_name": "pix_out_standard",
"workflow_version": 3,
"assessment": "REVIEW",
"score": 62.0,
"thresholds": {
"review_threshold": 45.0,
"block_threshold": 80.0,
"adjustments": []
},
"stages_executed": 4,
"stages_total": 4,
"early_terminated": false,
"execution_time_ms": 31,
"analysis_time_ms": 52,
"explanation": {
"stages": [
{ "name": "identity_verification", "score": 0 },
{ "name": "transaction_patterns", "score": 25.0 },
{ "name": "counterpart_analysis", "score": 30.0 },
{ "name": "device_signals", "score": 7.0 }
]
},
"created_at": "2026-03-08T17:30:00.456Z",
"resolution_source": "ENGINE",
"reason_code": null,
"reason_description": null,
"actions": [],
"review_info": {
"estimated_resolution_minutes": 28,
"review_reason": "Transaction held for security analysis",
"tracking_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
},
"sources_loaded": {
"customer": true,
"counterpart": true,
"device": true,
"dict": true,
"datarudder": false
},
"source_errors": {
"datarudder": "timeout after 1000ms"
},
"enrich_time_ms": 1012,
"eval_time_ms": 31
}
}
{
"error": false,
"data": {
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"transaction_id": "d7c6b5a4-9382-1010-dcba-098765432109",
"workflow_id": "11223344-5566-7788-99aa-bbccddeeff00",
"workflow_name": "pix_out_standard",
"workflow_version": 3,
"assessment": "BLOCK",
"score": 91.0,
"thresholds": {
"review_threshold": 45.0,
"block_threshold": 80.0,
"adjustments": []
},
"stages_executed": 2,
"stages_total": 4,
"early_terminated": true,
"blocked_at": "counterpart_analysis",
"execution_time_ms": 15,
"analysis_time_ms": 38,
"explanation": {
"stages": [
{ "name": "identity_verification", "score": 10.0 },
{ "name": "counterpart_analysis", "score": 81.0 }
],
"blocked_at": "counterpart_analysis"
},
"created_at": "2026-03-08T17:30:00.789Z",
"resolution_source": "ENGINE",
"reason_code": "HIGH_RISK_SCORE",
"reason_description": "Transaction blocked due to high risk score",
"actions": [
{
"type": "ACCOUNT_BLOCK",
"parameters": {}
}
],
"sources_loaded": {
"customer": true,
"counterpart": true,
"dict": true,
"datarudder": true
},
"enrich_time_ms": 22,
"eval_time_ms": 15
}
}

Los webhooks son el canal asíncrono por el cual Guardline notifica al integrador los eventos del ciclo de vida de la decisión. Todo webhook se entrega a través de la configuración de resultados del flujo de trabajo: un resultado con una acción send_webhook entrega por el transporte configurado en ese flujo de trabajo. Todas las clases de evento viajan por este único flujo:

  • Eventos del ciclo de vida de la decisión: decisiones del motor, resoluciones de caso del analista (aprobar, bloquear, escalar) y resoluciones automáticas por vencimiento del SLA.
  • Acciones manuales del analista: una retención cautelar o un bloqueo preventivo de cuenta que un analista aplica o libera desde la estación de trabajo de operaciones, fuera de cualquier caso abierto. Estas acciones viajan por el mismo flujo y el mismo transporte de la instancia; no hay ningún endpoint manual aparte.

Todo cuerpo lleva tres campos discriminadores (event_id, event_kind, subject) que clasifican el evento. Consulte los campos del contrato unificado más abajo.

La emisión de webhooks está condicionada por la configuración de resultados del flujo de trabajo: una acción send_webhook se vincula a uno o más tipos de decisión (allow, review, block, escalate), y el webhook solo se dispara cuando la decisión resuelta coincide con un tipo de decisión vinculado. Los vínculos se configuran durante la puesta en marcha de la integración, según los eventos que usted quiera recibir.

Esto significa que no existe una regla fija del tipo “solo hay webhooks en REVIEW”. Una decisión ALLOW puede disparar un webhook si el flujo de trabajo vincula send_webhook a allow; una decisión BLOCK puede disparar un webhook si está vinculada a block; y así sucesivamente. A la inversa, una decisión REVIEW no disparará ningún webhook si el flujo de trabajo no tiene el vínculo. Sus decisiones de configuración determinan el conjunto real de entregas.

Los eventos emitidos por este flujo son:

Eventoresolution_sourceassessment típico
El motor decide ALLOWENGINEALLOW
El motor decide REVIEWENGINEREVIEW
El motor decide BLOCKENGINEBLOCK
El analista aprueba un caso en REVIEWANALYSTALLOW
El analista bloquea un caso en REVIEWANALYSTBLOCK
El analista escala un caso en REVIEWANALYSTESCALATE
El SLA vence y se resuelve automáticamenteSLA_TIMEOUTALLOW o BLOCK

El analista puede actuar fuera de un caso REVIEW abierto: aplicar o liberar una retención cautelar sobre una transacción, o aplicar o liberar un bloqueo preventivo sobre una cuenta. Cada acción emite un webhook para que el integrador pueda aplicar o liberar el estado correspondiente de su lado. Las cuatro llevan event_kind: "manual_action" y se entregan por el mismo flujo y el mismo transporte de la instancia que los eventos del ciclo de vida de la decisión; no hay ningún endpoint manual aparte.

EventoDisparadorsubject.typeassessment
analyst_cautionary_hold_applyEl analista aplica una retención cautelar sobre una transaccióntransactionBLOCK (acción aplicada en actions)
analyst_cautionary_hold_clearEl analista libera una retención cautelar activatransactionALLOW (acción de liberación en actions)
analyst_account_block_applyEl analista aplica un bloqueo preventivo sobre una cuentaaccountBLOCK (acción aplicada en actions)
analyst_account_block_clearEl analista libera un bloqueo de cuenta activoaccountALLOW (acción de liberación en actions)

Estos eventos usan los mismos encabezados, modos de autenticación, política de reintentos y semántica de idempotencia que se describen a continuación. Las retenciones cautelares se anclan a la decisión de fraude de la transacción, así que su cuerpo lleva el contexto completo de la decisión (transaction_id, workflow_*, score, etc.) junto a resolution_source: "ANALYST" y la acción aplicada o liberada. Los bloqueos preventivos de cuenta no tienen decisión: el analista actúa directamente sobre la cuenta, sin transacción de origen ni decisión de fraude, así que su cuerpo omite el contexto de la decisión y lleva solo el sujeto cuenta. Para esos eventos de cuenta, decision_id y transaction_id son nulos en las superficies de polling y de monitoreo; nunca se emite un UUID en cero. Consulte los eventos con alcance de cuenta (sin decisión) más abajo.

En los eventos con alcance de transacción, el cuerpo del webhook usa la misma estructura plana que la respuesta síncrona de la API (el payload de decisión), pero sin el envoltorio {"error": false, "data": ...}, y lleva de forma aditiva tres campos del contrato unificado (event_id, event_kind, subject). Todos los campos planos del payload síncrono de decisión se conservan, de modo que un parser existente sigue funcionando y un consumidor conforme ignora los campos aditivos que no conoce.

Esto significa que el integrador puede mantener un solo parser para los campos planos de la decisión (reutilizándolo tanto para la respuesta síncrona, extrayendo desde .data, como para el cuerpo del webhook) y ramificar por event_kind más subject para clasificar el evento.

Todo cuerpo de webhook lleva tres campos de primer nivel que clasifican el evento:

CampoTipoDescripción
event_idUUIDÚnico por evento de webhook. No es el id de la decisión (resolver y escalar reutilizan el id de la decisión a lo largo de un ciclo de vida; el event_id es distinto en cada emisión). Estable entre los reintentos de una misma entrega.
event_kindstringEl discriminador del evento. Uno de engine_decision, case_resolution, case_escalation, sla_timeout_resolution, manual_action. Clasifique por este campo, nunca por la presencia de actions[].
subjectobjetoEl sujeto tipado. subject.type es transaction o account. subject.transaction_id está presente en los eventos con alcance de transacción; subject.account_id está presente en los eventos con alcance de cuenta.

Eventos con alcance de cuenta (sin decisión)

Sección titulada «Eventos con alcance de cuenta (sin decisión)»

La aplicación y la liberación de un bloqueo preventivo de cuenta no tienen decisión: el analista actúa directamente sobre una cuenta, sin transacción de origen ni decisión de fraude. Su cuerpo es deliberadamente mínimo y honesto:

  • subject es { "type": "account", "account_id": "<id>" }.
  • event_kind es manual_action; assessment es BLOCK al aplicar y ALLOW al liberar; actions[] lleva ACCOUNT_BLOCK o ACCOUNT_BLOCK_CLEAR; resolution_source es ANALYST; created_at es el momento en que la acción del analista quedó confirmada.
  • Los campos de contexto de la decisión se omiten (sin id, sin transaction_id, sin workflow_*, score, thresholds, stages_*, explanation, tiempos, trace_id ni request_id). Nunca se emite un id de decisión sintético ni un id de transacción en ceros. En las superficies de lectura de polling y de monitoreo, el decision_id y el transaction_id del ledger son null para estos eventos.

Los eventos con alcance de transacción (decisiones del motor, resolución y escalamiento de caso, retenciones cautelares) conservan todos sus campos planos; solo se añaden los tres campos del contrato unificado.

Ejemplo de webhook: el analista aprueba con retención cautelar

Sección titulada «Ejemplo de webhook: el analista aprueba con retención cautelar»
{
"event_id": "9a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9",
"event_kind": "case_resolution",
"subject": { "type": "transaction", "transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210" },
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210",
"workflow_id": "11223344-5566-7788-99aa-bbccddeeff00",
"workflow_name": "pix_out_standard",
"workflow_version": 3,
"assessment": "ALLOW",
"score": 62.0,
"thresholds": {
"review_threshold": 45.0,
"block_threshold": 80.0,
"adjustments": []
},
"stages_executed": 4,
"stages_total": 4,
"early_terminated": false,
"execution_time_ms": 31,
"analysis_time_ms": 52,
"explanation": {
"stages": [
{ "name": "identity_verification", "score": 0 },
{ "name": "transaction_patterns", "score": 25.0 },
{ "name": "counterpart_analysis", "score": 30.0 },
{ "name": "device_signals", "score": 7.0 }
]
},
"created_at": "2026-03-08T17:30:00.456Z",
"resolution_source": "ANALYST",
"reason_code": "CUSTOMER_CONFIRMED",
"reason_description": "Customer confirmed the transaction is legitimate",
"actions": [
{
"type": "CAUTIONARY_HOLD",
"parameters": {
"duration_hours": 72
}
}
]
}

Ejemplo de webhook: aprobación automática por vencimiento del SLA

Sección titulada «Ejemplo de webhook: aprobación automática por vencimiento del SLA»
{
"event_id": "1d2e3f40-5161-7283-94a5-b6c7d8e9f001",
"event_kind": "sla_timeout_resolution",
"subject": { "type": "transaction", "transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210" },
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210",
"workflow_id": "11223344-5566-7788-99aa-bbccddeeff00",
"workflow_name": "pix_out_standard",
"workflow_version": 3,
"assessment": "ALLOW",
"score": 62.0,
"thresholds": {
"review_threshold": 45.0,
"block_threshold": 80.0,
"adjustments": []
},
"stages_executed": 4,
"stages_total": 4,
"early_terminated": false,
"execution_time_ms": 31,
"analysis_time_ms": 52,
"explanation": {
"stages": [
{ "name": "identity_verification", "score": 0 },
{ "name": "transaction_patterns", "score": 25.0 },
{ "name": "counterpart_analysis", "score": 30.0 },
{ "name": "device_signals", "score": 7.0 }
]
},
"created_at": "2026-03-08T17:30:00.456Z",
"resolution_source": "SLA_TIMEOUT",
"reason_code": "SLA_TIMEOUT_AUTO_APPROVED",
"reason_description": "Automatically approved due to SLA expiration",
"actions": [
{
"type": "CAUTIONARY_HOLD",
"parameters": {
"duration_hours": 72
}
}
]
}

Ejemplo de webhook: el analista bloquea con suspensión de la cuenta

Sección titulada «Ejemplo de webhook: el analista bloquea con suspensión de la cuenta»
{
"event_id": "2e3f4051-6273-8495-a6b7-c8d9e0f10203",
"event_kind": "case_resolution",
"subject": { "type": "transaction", "transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210" },
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210",
"workflow_id": "11223344-5566-7788-99aa-bbccddeeff00",
"workflow_name": "pix_out_standard",
"workflow_version": 3,
"assessment": "BLOCK",
"score": 62.0,
"thresholds": {
"review_threshold": 45.0,
"block_threshold": 80.0,
"adjustments": []
},
"stages_executed": 4,
"stages_total": 4,
"early_terminated": false,
"execution_time_ms": 31,
"analysis_time_ms": 52,
"explanation": {
"stages": [
{ "name": "identity_verification", "score": 0 },
{ "name": "transaction_patterns", "score": 25.0 },
{ "name": "counterpart_analysis", "score": 30.0 },
{ "name": "device_signals", "score": 7.0 }
]
},
"created_at": "2026-03-08T17:30:00.456Z",
"resolution_source": "ANALYST",
"reason_code": "CONFIRMED_FRAUD",
"reason_description": "Analyst confirmed fraudulent activity",
"actions": [
{
"type": "CAUTIONARY_HOLD",
"parameters": {
"duration_hours": 72
}
},
{
"type": "ACCOUNT_BLOCK",
"parameters": {}
}
]
}

Ejemplo de webhook: el analista aplica un bloqueo preventivo de cuenta (sin decisión)

Sección titulada «Ejemplo de webhook: el analista aplica un bloqueo preventivo de cuenta (sin decisión)»

Un evento de cuenta sin decisión lleva el sujeto cuenta y omite el contexto de la decisión. El created_at es el momento en que el analista aplicó el bloqueo. El evento de liberación tiene la misma forma, con assessment: "ALLOW" y actions[0].type: "ACCOUNT_BLOCK_CLEAR".

{
"event_id": "7c1f0a2b-3d4e-5f60-7182-93a4b5c6d7e8",
"event_kind": "manual_action",
"subject": {
"type": "account",
"account_id": "ACC-00086"
},
"assessment": "BLOCK",
"resolution_source": "ANALYST",
"reason_code": "SUSPECTED_FRAUD",
"reason_description": null,
"created_at": "2026-03-08T17:32:10.004Z",
"actions": [
{
"type": "ACCOUNT_BLOCK",
"parameters": {}
}
]
}

Toda solicitud de webhook incluye los siguientes encabezados HTTP:

EncabezadoDescripción
Content-TypeSiempre application/json
X-Guardline-Delivery-IDUUID estable de esta entrega, idéntico en todos los reintentos. Úselo para la deduplicación
X-Guardline-Attempt-NumberNúmero secuencial del intento (1 para la primera entrega, 2 para el primer reintento, etc.)
X-Guardline-TimestampMarca de tiempo Unix del momento de la firma (cuando HMAC está habilitado)
X-Guardline-SignatureFirma HMAC-SHA256 en hexadecimal (cuando HMAC está habilitado)
AuthorizationToken Bearer (cuando OAuth está habilitado)

Guardline admite cuatro modos de autenticación de webhook. El modo se configura por endpoint de webhook durante la puesta en marcha de la integración. La firma HMAC aporta verificación de integridad del mensaje y puede combinarse con cualquier modo. En el modo solo HMAC es la única autenticación y es obligatoria. En los modos OAuth, mTLS y OAuth + mTLS es opcional, aunque recomendada como defensa en profundidad; cuando no hay un secreto HMAC configurado en esos modos, los encabezados X-Guardline-Signature y X-Guardline-Timestamp no se envían.

ModoFirma HMACBearer OAuthCertificado de cliente
Solo HMAC (predeterminado)ObligatoriaNoNo
OAuth 2.0Opcional, recomendadaSíNo
mTLSOpcional, recomendadaNoSí
OAuth 2.0 + mTLSOpcional, recomendadaSíSí

La autenticación HMAC usa un secreto compartido provisionado durante la puesta en marcha del integrador.

Proceso de verificación en el receptor:

  1. Extraer el encabezado X-Guardline-Timestamp
  2. Rechazar si la marca de tiempo tiene más de 5 minutos de antigüedad respecto del reloj del servidor
  3. Concatenar la marca de tiempo y el cuerpo de la solicitud: {timestamp}.{body}
  4. Calcular HMAC-SHA256 de la concatenación usando el secreto compartido
  5. Codificar el resultado en hexadecimal
  6. Comparar con el encabezado X-Guardline-Signature usando una comparación de tiempo constante
  7. Rechazar si hay discrepancia

Pseudocódigo:

import hmac, hashlib, time
def verify_webhook(body: bytes, timestamp: str, signature: str, secret: str) -> bool:
if abs(time.time() - int(timestamp)) > 300:
return False
message = f"{timestamp}.".encode() + body
expected = hmac.new(
secret.encode(),
message,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)

La autenticación TLS mutua garantiza la identidad de Guardline en la capa de transporte, sin requerir validación a nivel de aplicación.

Configuración:

  1. Durante el aprovisionamiento, Guardline entrega el certificado de la CA raíz (guardline-ca.pem)
  2. El integrador configura su servidor de webhook para exigir certificados de cliente
  3. El integrador agrega guardline-ca.pem a la lista de CA de confianza del servidor
  4. En cada entrega, Guardline presenta un certificado de cliente firmado por la CA raíz
  5. El servidor del integrador valida la cadena de certificados automáticamente en la capa TLS

El campo CN (Common Name) del certificado de cliente contiene el identificador de la instancia del integrador. El integrador puede validar opcionalmente este campo para asegurarse de que la solicitud proviene de la instancia correcta.

Cuando mTLS es el único modo de autenticación y no hay un secreto HMAC configurado, los encabezados X-Guardline-Signature y X-Guardline-Timestamp no se envían. La misma omisión aplica a los modos OAuth y OAuth + mTLS cuando no hay un secreto HMAC configurado. Consulte la matriz de autenticación del webhook incluida arriba para ver el detalle completo por modo.

La autenticación OAuth permite que Guardline obtenga un token de acceso antes de cada entrega, mediante el flujo de Client Credentials (RFC 6749, sección 4.4).

Configuración:

  1. El integrador proporciona, durante la puesta en marcha de la integración: token_endpoint, client_id, client_secret y, opcionalmente, scope
  2. Antes de cada entrega, Guardline solicita un token al endpoint indicado
  3. La solicitud del token sigue el formato estándar:
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}&scope={scope}
  1. Guardline incluye el token obtenido en el encabezado de autorización del webhook:
Authorization: Bearer {access_token}
  1. El integrador valida el token en su endpoint de webhook según su implementación de OAuth

Guardline almacena el token en caché respetando el campo expires_in de la respuesta del endpoint de token, con un margen de seguridad de 60 segundos. Si el receptor del webhook devuelve 401, el token en caché se invalida y se obtiene un token nuevo para un único reintento.

Si la obtención del token falla por credenciales inválidas (401 o 400 desde el endpoint de token), el primer intento de envío registra una entrega fallida. El worker de reintentos reconoce el error de autenticación no reintentable en su siguiente ciclo y marca la entrega como exhausted, sin más intentos, de modo que el integrador no ve una espera larga por una falla de configuración de credenciales. Las fallas transitorias del endpoint de token (500, tiempo de espera) siguen la política normal de reintentos.

El endpoint de webhook se configura durante la puesta en marcha de la integración. Requisitos:

RequisitoDetalle
ProtocoloHTTPS obligatorio
Versión de TLS1.2 o superior
Respuesta de éxitoCualquier código 2xx (el cuerpo se ignora)
Tiempo de esperaResponder en menos de 10 segundos
IdempotenciaDeduplicar las entregas usando X-Guardline-Delivery-ID

Recomendación de implementación: reciba el webhook, encólelo para procesamiento asíncrono y responda de inmediato con 200. Así se evitan los tiempos de espera agotados y se garantiza una entrega confiable.

Cuando se rotan las credenciales de OAuth o los certificados mTLS, los reintentos en curso de entregas ya despachadas continúan usando las credenciales que estaban activas en el momento del despacho. Las entregas nuevas usan las credenciales actualizadas de inmediato.

Si es necesario reenviar entregas fallidas con las credenciales nuevas, se puede disparar un reenvío desde el lado de operaciones de Guardline. El endpoint correspondiente (POST /api/v2/webhooks/deliveries/{id}/redispatch) es exclusivo de administradores: requiere autenticación JWT con el rol SUPERVISOR o ADMIN y no se puede invocar con una clave de API de integrador. Para disparar un reenvío tras la rotación de credenciales, contacte a su representante de soporte de Guardline; él lo ejecutará en su nombre. El reenvío crea una entrega nueva usando las últimas credenciales configuradas, preservando el payload original y el contexto de la decisión, y la entrega original se conserva intacta con fines de auditoría.

Si Guardline no recibe una respuesta HTTP 2xx, el webhook se reintenta con retroceso exponencial:

IntentoEspera tras la falla
15 segundos
230 segundos
32 minutos
410 minutos
530 minutos
61 hora
72 horas
84 horas
98 horas
1012 horas

Tras 10 intentos fallidos, la entrega se marca como exhausted y se genera una alerta interna. La notificación aún puede recuperarse mediante el endpoint de sondeo.

Tiempo de espera: cada intento de entrega tiene un tiempo de espera de 10 segundos. Asegúrese de que su manejador de webhook responda dentro de esa ventana.

Respuesta esperada: devuelva HTTP 200 OK con cualquier cuerpo. Solo importa el código de estado.

Los webhooks pueden entregarse más de una vez (por reintentos tras problemas de red). Use el encabezado X-Guardline-Delivery-ID para deduplicar:

  1. Almacene cada X-Guardline-Delivery-ID procesado.
  2. Al recibir un webhook, verifique si el ID de entrega ya fue procesado.
  3. Si ya lo fue, responda 200 OK sin volver a procesarlo.

Consulte el estado actual de una decisión por su ID.

GET /api/v2/decisions/{id}

Encabezados:

X-API-Key: gl_live_your_api_key_here

Respuesta: el mismo envoltorio y la misma estructura de payload de decisión que el endpoint de análisis.

Cuando una transacción en REVIEW deja de ser relevante (desistimiento del usuario, expiración de la sesión, duplicado, etc.), el integrador debe cancelarla para que los analistas dejen de trabajar en ella. No se envía ningún webhook después de la cancelación.

POST /api/v2/decisions/{id}/cancel

Encabezados:

Content-Type: application/json
X-API-Key: gl_live_your_api_key_here

Solicitud:

{
"reason": "Client cancelled the transaction"
}
CampoTipoObligatorioDescripción
reasonstringsíMotivo de la cancelación (de 3 a 500 caracteres)

Respuesta (200 OK):

{
"error": false,
"data": {
"decision_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"case_id": "d4e5f6a7-b890-1234-efab-567890123456",
"previous_status": "PENDING",
"new_status": "CANCELLED",
"cancelled_at": "2026-03-08T17:45:00.123Z"
}
}

Comportamiento:

  • Devuelve 200 si el caso se cancela correctamente.
  • Devuelve 200 si el caso ya estaba cancelado (idempotente).
  • Devuelve 409 si el caso ya fue resuelto por un analista o por vencimiento del SLA.
  • Solo se pueden cancelar los casos en estado PENDING o IN_PROGRESS.

Si los webhooks fallan de forma repetida (por ejemplo, durante una indisponibilidad prolongada), el integrador puede sondear las notificaciones no entregadas y confirmarlas después de procesarlas.

Este es un mecanismo de respaldo. El webhook es el canal principal de entrega.

GET /api/v2/decisions/notifications

Encabezados:

X-API-Key: gl_live_your_api_key_here

Parámetros de consulta:

ParámetroTipoPredeterminadoDescripción
sincestringningunoMarca de tiempo ISO 8601. Devuelve solo las notificaciones creadas después de ese momento.
statusstringningunoFiltrar por estado: pending, failed o exhausted
limitinteger50Máximo de resultados (de 1 a 200)

Respuesta (200 OK):

{
"error": false,
"data": {
"notifications": [
{
"delivery_id": "aabbccdd-1122-3344-5566-778899001122",
"decision_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210",
"status": "exhausted",
"payload": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"transaction_id": "e8d7c6b5-a493-2101-edcb-a09876543210",
"assessment": "ALLOW",
"resolution_source": "ANALYST",
"actions": [
{
"type": "CAUTIONARY_HOLD",
"parameters": { "duration_hours": 72 }
}
],
"score": 62.0,
"created_at": "2026-03-08T17:30:00.456Z"
},
"created_at": "2026-03-08T17:35:00.000Z",
"attempt_number": 10
}
],
"total": 1
}
}

El campo payload contiene el mismo cuerpo enviado en el webhook, incluidos los campos event_id, event_kind y subject. En los eventos de cuenta sin decisión (event_kind: "manual_action" con sujeto cuenta), el decision_id y el transaction_id de primer nivel son null, y el payload omite el contexto de la decisión y lleva solo el sujeto cuenta.

Después de procesar una notificación obtenida por sondeo, confírmela para que deje de aparecer en las consultas siguientes.

POST /api/v2/decisions/notifications/{delivery_id}/ack

Encabezados:

X-API-Key: gl_live_your_api_key_here

Respuesta (200 OK):

{
"error": false,
"data": {
"delivery_id": "aabbccdd-1122-3344-5566-778899001122",
"acknowledged": true
}
}

Comportamiento:

  • Devuelve 200 si la confirmación se registra correctamente.
  • Devuelve 200 si ya estaba confirmada (idempotente).
Integrator Guardline
| |
| POST /decisions/analyze |
|---------------------------->|
| | Enrich context (DICT, Data Rudder)
| | Execute fraud rules
| | Calculate score + decision
| 200 OK (ALLOW or BLOCK) |
|<----------------------------|
| |
| Execute actions |
| (if any in response) |

Responsabilidades del integrador:

  • Si es ALLOW: autorizar el PIX.
  • Si es BLOCK: rechazar el PIX y ejecutar las actions que correspondan (por ejemplo, ACCOUNT_BLOCK).

Presupuesto de tiempo: la respuesta de Guardline suele completarse en menos de 100 ms. El SLA regulatorio del PIX es de 40 segundos de extremo a extremo, por lo que el integrador tiene un margen amplio.

Integrator Guardline Analyst
| | |
| POST /decisions/analyze | |
|---------------------------->| |
| | Score in review zone |
| 200 OK (REVIEW) | |
|<----------------------------| |
| | Create case (async) |
| Hold transaction | |
| Notify end user | |
| | |
| | Case assigned |
| |<---------------------------|
| | Resolve case |
| |<---------------------------|
| | |
| Webhook (resolution) | |
|<----------------------------| |
| | |
| Execute decision | |
| Execute actions | |

Responsabilidades del integrador:

  • Ante un REVIEW: retener la transacción y notificar al usuario final con los datos de review_info.
  • Ante el webhook: ejecutar la decisión final (ALLOW o BLOCK) y las actions que correspondan.
  • Use review_info.estimated_resolution_minutes para informar al usuario final el tiempo de espera previsto.

SLA: si ningún analista resuelve el caso dentro del plazo regulatorio, Guardline aplica automáticamente la resolución de respaldo configurada (por lo general, ALLOW con CAUTIONARY_HOLD) y envía el webhook con resolution_source: "SLA_TIMEOUT".

PIX In usa el mismo contrato de API y los mismos nombres de campo que PIX Out, pero las partes que llevan están invertidas, y la semántica de la respuesta difiere porque a Guardline se la llama una vez que el crédito ya se liquidó.

La regla es la misma para cualquier dirección: accountId y accountHolderId siempre identifican a su cliente, el titular de la cuenta sobre cuyo historial y cuyas baselines de comportamiento se construye el análisis, y counterPart siempre describe a la otra parte. Lo que cambia con la dirección es qué parte del mundo real ocupa cada rol.

CampoPIX Out (direction: "OUT")PIX In (direction: "IN")
accountIdLa cuenta pagadoraLa cuenta receptora
accountHolderIdEl CPF o CNPJ del pagadorEl CPF o CNPJ del receptor
counterPartEl beneficiarioEl pagador
instantPayment.payerSu clienteLa contraparte
instantPayment.receiverLa contraparteSu cliente
  • ALLOW: no se requiere ninguna acción.
  • BLOCK: no significa “rechazar” (los fondos ya están acreditados). Significa “aplicar remediación”. Ejecute las actions señalizadas (por lo general, CAUTIONARY_HOLD sobre el importe acreditado o ACCOUNT_BLOCK, o ambas).
  • REVIEW: el crédito ya ocurrió. Esto señaliza “en investigación”. La resolución y las acciones de remediación que correspondan llegarán por webhook.

Esta semántica supone que la integración entrante llama a Guardline después de que el crédito se liquidó, que es el modo de operación para el que PIX In está diseñado. Guardline no lo verifica: la liquidación la llevan los campos opcionales metadata.settledAt y metadata.transactionStatus, y ninguno de los dos es obligatorio ni se valida. Envíelos cuando los tenga, para que el registro de la decisión refleje el momento real de la liquidación.

Fije metadata.direction en "IN" para PIX In. Los valores canónicos son IN, OUT y SELF, la comparación no distingue mayúsculas de minúsculas, y los alias INBOUND y OUTBOUND se aceptan y se canonizan a IN y OUT.

El ejemplo de abajo refleja el ejemplo de PIX Out anterior, con los roles invertidos: ACC-00086 es la cuenta receptora, 12345678900 es el documento del receptor, y el bloque counterPart describe al pagador que envió el dinero.

{
"transactionId": "TX-20260308-00005678",
"accountId": "ACC-00086",
"accountHolderId": "12345678900",
"transactionType": "PIX",
"transactionDate": "2026-03-08T09:12:00-03:00",
"totalAmount": "8400.00",
"currency": "BRL",
"channel": "API",
"metadata": {
"direction": "IN",
"status": "settled",
"settledAt": "2026-03-08T09:12:01-03:00",
"transactionStatus": "Success",
"originSystem": "IPAY"
},
"customer": {
"age": 42,
"kycStatus": "approved",
"kycLevel": "complete",
"riskScore": 15.0,
"riskLevel": "low",
"isPEP": false,
"isNewCustomer": false
},
"counterPart": {
"name": "Carlos Pereira",
"taxIdentifier": {
"taxId": "321.654.987-00",
"country": "BR"
},
"isNewCounterpart": true,
"transactionsCount": 0,
"isSameNetwork": false
},
"instantPayment": {
"keyValue": "12345678900",
"endToEndId": "E60701190202603080912wxyz5678gh",
"initiationMethod": "DICT",
"payer": {
"ispb": "60701190",
"ispbName": "Itaú Unibanco S.A.",
"document": "321.654.987-00",
"branch": "0042",
"account": "55555-1",
"name": "Carlos Pereira"
},
"receiver": {
"ispb": "00000000",
"ispbName": "Banco do Brasil S.A.",
"document": "123.456.789-00",
"branch": "3456",
"account": "78901-2",
"name": "João Oliveira"
}
}
}

Observe cómo instantPayment.payer lleva a la contraparte y instantPayment.receiver lleva a su cliente, al revés que en el ejemplo de PIX Out. Guardline lee el nombre del receptor de este bloque para mantener al día el registro del cliente en las transacciones entrantes, así que completarlo correctamente es lo que mantiene el nombre del cliente atado a la persona correcta.

Todos los errores siguen esta estructura:

{
"error": true,
"message": "description of the error",
"code": "ERROR_CODE",
"details": "additional context (optional)",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
CódigoSignificado
200Éxito
400Solicitud inválida (JSON malformado, falla de validación)
401Falla de autenticación (clave de API inválida o ausente)
404Recurso no encontrado (el ID de decisión no existe)
409Conflicto (el caso ya fue resuelto, no se puede cancelar)
429Límite de solicitudes alcanzado (demasiadas solicitudes)
500Error interno del servidor
  • Ante un 400: corrija el payload de la solicitud. No reintente.
  • Ante un 401: verifique la clave de API. No reintente.
  • Ante un 404: verifique el ID de la decisión. No reintente.
  • Ante un 409: el caso ya fue resuelto. Trátelo como un éxito.
  • Ante un 429: reduzca el ritmo y reintente después de la espera indicada.
  • Ante un 500: reintente con retroceso exponencial (hasta 3 intentos).
  • Ante un tiempo de espera de red agotado: reintente. La idempotencia del transactionId garantiza que no haya procesamiento duplicado.

Recupera la lista de feriados nacionales y bancarios que Guardline usa para las ventanas de SLA y la lógica de días hábiles. Es útil para los integradores que necesitan alinear su propia programación con el mismo calendario que usa Guardline.

GET /api/v2/holidays?year=<int>

Requiere una clave de API con el alcance holidays.read. Contacte a Guardline para habilitar este alcance en su clave.

ParámetroTipoObligatorioDescripción
yearintegerNoAño por el cual filtrar. De forma predeterminada, el año actual. Rango válido: 2000 a 2100.
{
"error": false,
"data": {
"items": [
{
"date": "2026-12-25",
"name": "Natal",
"type": "NATIONAL",
"created_at": "2025-01-01T00:00:00Z"
}
],
"total": 12
}
}
CampoTipoDescripción
data.items[].datestringFecha ISO 8601 (YYYY-MM-DD)
data.items[].namestringNombre del feriado para mostrar (en portugués)
data.items[].typestringNATIONAL (feriados federales) o BANKING (cierres bancarios observados por el sistema bancario brasileño)
data.items[].created_atstringMarca de tiempo ISO 8601 del registro de la entrada
data.totalintegerCantidad de elementos devueltos
GET /api/v2/holidays?year=2026 HTTP/1.1
X-API-Key: gl_live_your_api_key_here

La lista de feriados cambia con poca frecuencia, normalmente una vez al año, cuando se confirman los nuevos calendarios. Se recomienda que los integradores guarden la respuesta en caché de su lado y la actualicen cada semana o cada mes, en lugar de hacerlo en cada solicitud.

Devuelve las ventanas configurables de horario de funcionamiento que rigen el nivel de SLA y las reglas de horario hábil de Guardline. Se exponen dos ventanas en una única respuesta:

  • pix controla el nivel de SLA de las retenciones PIX (ventana de 30 minutos en horario hábil, 60 minutos fuera de él).
  • engine controla el predicado is_business_hours que referencian las reglas tácticas del motor de decisión.

Ambas ventanas se definen por día de la semana, con indicadores explícitos de apertura y cierre y cadenas HH:MM de inicio y fin. Los feriados cierran ambas ventanas, sea cual sea la configuración por día de la semana.

GET /api/v2/calendar/working-hours

Requiere un JWT o una clave de API con el alcance calendar.read. Contacte a Guardline para habilitar este alcance en su clave. El mismo alcance admitirá futuras lecturas de calendario (por ejemplo, un evaluador por marca de tiempo), de modo que una única concesión cubre todo el conjunto.

{
"error": false,
"data": {
"pix": {
"version": 1,
"timezone": "America/Sao_Paulo",
"weekdays": {
"sunday": {"open": false, "start": "00:00", "end": "00:00"},
"monday": {"open": true, "start": "08:00", "end": "20:00"},
"tuesday": {"open": true, "start": "08:00", "end": "20:00"},
"wednesday": {"open": true, "start": "08:00", "end": "20:00"},
"thursday": {"open": true, "start": "08:00", "end": "20:00"},
"friday": {"open": true, "start": "08:00", "end": "20:00"},
"saturday": {"open": false, "start": "00:00", "end": "00:00"}
}
},
"engine": {
"version": 1,
"timezone": "America/Sao_Paulo",
"weekdays": {
"sunday": {"open": false, "start": "00:00", "end": "00:00"},
"monday": {"open": true, "start": "08:00", "end": "18:00"},
"tuesday": {"open": true, "start": "08:00", "end": "18:00"},
"wednesday": {"open": true, "start": "08:00", "end": "18:00"},
"thursday": {"open": true, "start": "08:00", "end": "18:00"},
"friday": {"open": true, "start": "08:00", "end": "18:00"},
"saturday": {"open": false, "start": "00:00", "end": "00:00"}
}
}
}
}
CampoTipoDescripción
data.pixobjectVentana de horario de funcionamiento del nivel de SLA de PIX.
data.engineobjectVentana de horario de funcionamiento del predicado is_business_hours del motor.
data.<window>.versionintegerVersión del payload. La forma actual es la versión 1.
data.<window>.timezonestringNombre de zona horaria IANA. Actualmente fijo en America/Sao_Paulo a nivel de implantación para todos los integradores.
data.<window>.weekdays.<day>.openbooleanIndica si el día de la semana está abierto. Cuando es false, start y end se ignoran.
data.<window>.weekdays.<day>.startstringInicio de la ventana en hora local, en formato HH:MM de 24 horas.
data.<window>.weekdays.<day>.endstringFin de la ventana en hora local, en formato HH:MM de 24 horas. El fin es exclusivo: una ventana que termina a las 20:00 no incluye 20:00:00.
GET /api/v2/calendar/working-hours HTTP/1.1
X-API-Key: gl_live_your_api_key_here
  • La zona horaria está fija actualmente en America/Sao_Paulo para todos los integradores. Las zonas horarias por tenant están en la hoja de ruta; este campo se expone hoy para que las futuras implantaciones por tenant no requieran un cambio de contrato.
  • Los feriados cierran ambas ventanas. Use el Calendario de feriados para alinear su propia lista de feriados con la de Guardline.
  • start y end son límites de reloj en hora local, no desplazamientos respecto de UTC. Conviértalos a su interpretación local usando el timezone devuelto.
  • La ventana engine puede diferir de pix (por ejemplo, pix de 08:00 a 20:00 mientras que engine va de 08:00 a 18:00). Lea ambos campos en lugar de suponer una única ventana global.
EstadoMotivo
401Credencial ausente o inválida.
403La clave de API no tiene el alcance calendar.read.
500Error inesperado.

No existe un 400 porque el endpoint no recibe parámetros.

La configuración de horario de funcionamiento cambia con poca frecuencia. Se recomienda que los integradores guarden la respuesta en caché de su lado y la actualicen cada semana o cada mes, en lugar de hacerlo en cada solicitud.

El Banco Central do Brasil exige un SLA de 40 segundos de extremo a extremo para las transacciones PIX estándar. El tiempo de respuesta de Guardline (normalmente inferior a 100 ms) es una fracción pequeña de ese presupuesto.

Transferencia inteligente (retención en REVIEW)

Sección titulada «Transferencia inteligente (retención en REVIEW)»

Cuando una transacción queda retenida para análisis de fraude (decisión REVIEW), el SLA regulatorio depende del momento en que se retuvo la transacción:

Momento de la retenciónTiempo máximo de retención
Horario hábil (días hábiles, de 08:00 a 20:00 BRT)30 minutos
Fuera del horario hábil (noches, fines de semana, feriados)60 minutos

Guardline aplica un margen de seguridad de 2 minutos, disparando la resolución automática de respaldo a los 28 o 58 minutos, respectivamente.

El concepto de “día hábil” sigue el calendario nacional de feriados del Banco Central do Brasil. La lista completa está disponible mediante el endpoint Calendario de feriados.

Una retención cautelar congela los fondos acreditados por hasta 72 horas cuando existe sospecha fundada de fraude, conforme a la Resolución BCB 142/2021. Se debe notificar al titular de la cuenta sobre la retención.

Las tablas siguientes documentan los campos disponibles en cada bloque de la solicitud. Todos los campos de los bloques opcionales son, a su vez, opcionales. El integrador debe enviar los campos que estén disponibles en sus sistemas. Guardline usará lo que se le proporcione y omitirá lo que falte.

Solicitud de análisis: objeto instantPayment

Sección titulada «Solicitud de análisis: objeto instantPayment»
CampoTipoDescripción
keyTypestringTipo de clave PIX: cpf, cnpj, phone, email, evp
keyValuestringValor de la clave PIX
endToEndIdstringIdentificador de extremo a extremo proveniente del SPI
originalEndToEndIdstringID E2E original (para devoluciones o reversiones)
reconciliationIdstringIdentificador de conciliación (txid)
initiationMethodstringMétodo de inicio (DICT, QRCODE, MANUAL)
transactionPurposestringCódigo de finalidad de la transacción
isQRCodebooleanSi se inició mediante código QR
isScheduledbooleanSi se trata de un pago programado
payerobjectDatos de la parte pagadora (ver PixParty abajo)
receiverobjectDatos de la parte receptora (ver PixParty abajo)
dictobjectDatos de enriquecimiento del DICT (ver abajo)

Solicitud de análisis: payer / receiver (PixParty)

Sección titulada «Solicitud de análisis: payer / receiver (PixParty)»
CampoTipoDescripción
ispbstringCódigo ISPB de la institución
ispbNamestringNombre de la institución
documentstringCPF o CNPJ
branchstringNúmero de agencia
accountstringNúmero de cuenta
namestringNombre del titular de la cuenta
CampoTipoDescripción
keyCreationDatestringFecha ISO 8601 de creación de la clave PIX
keyOwnershipDatestringFecha ISO 8601 en que se estableció la titularidad
accountTypestringTipo de cuenta (CACC, SVGS, etc.)
accountOpeningDatestringFecha ISO 8601 de apertura de la cuenta
pspNamestringNombre de la institución PSP
pspIspbstringCódigo ISPB del PSP
fraudMarkersCountintegerCantidad de marcadores de fraude (notificaciones de infracción)
infractionCountintegerCantidad de infracciones
lastFraudReportDatestringFecha ISO 8601 del último reporte de fraude
isFlaggedbooleanSi la clave está marcada actualmente
flaggedSincestringFecha ISO 8601 desde la cual la clave está marcada
claimsCountintegerCantidad de reclamos de titularidad
portabilityCountintegerCantidad de eventos de portabilidad
correlationIdstringIdentificador de correlación R6
registeredAccountsstringCantidad de cuentas registradas para el titular de esta clave
lastMarkFraudDatestringFecha ISO 8601 de la última marca de fraude
naturalPersonAntifraudPercentageintegerPorcentaje antifraude para personas físicas
legalPersonAntifraudPercentageintegerPorcentaje antifraude para personas jurídicas
spiobjectEstadísticas del SPI (ver abajo)
reportsobjectReportes de infracción (ver abajo)
fraudsarrayEntradas de fraude por tipo (ver abajo)
CampoTipoDescripción
d90stringTransacciones SPI en los últimos 90 días
m12stringTransacciones SPI en los últimos 12 meses
m60stringTransacciones SPI en los últimos 60 meses
CampoTipoDescripción
openReportsstringCantidad de reportes de infracción abiertos
distinctReportsstringCantidad de instituciones denunciantes distintas
rejectedD90stringTransacciones rechazadas en los últimos 90 días
rejectedM12stringTransacciones rechazadas en los últimos 12 meses
rejectedM60stringTransacciones rechazadas en los últimos 60 meses

Solicitud de análisis: elementos del arreglo dict.frauds

Sección titulada «Solicitud de análisis: elementos del arreglo dict.frauds»
CampoTipoDescripción
fraudTypestringTipo de fraude (por ejemplo, SCAMMER_ACCOUNT, MULE_ACCOUNT)
d90stringOcurrencias en los últimos 90 días
m12stringOcurrencias en los últimos 12 meses
m60stringOcurrencias en los últimos 60 meses
CampoTipoDescripción
ageintegerEdad del cliente
kycStatusstringEstado KYC (approved, pending, rejected)
kycLevelstringNivel KYC (basic, intermediate, complete)
riskScorenumberPuntaje de riesgo preexistente
riskLevelstringNivel de riesgo (low, medium, high)
isPEPbooleanIndicador de Persona Expuesta Políticamente
countrystringPaís del cliente (ISO 3166-1 alfa-2)
accountAgeDaysintegerAntigüedad de la cuenta en días
accountStatusstringEstado de la cuenta (active, suspended, blocked)
hasNegativeBalancebooleanSi la cuenta tiene saldo negativo
isNewCustomerbooleanSi se trata de un cliente incorporado recientemente
CampoTipoDescripción
directionstringDirección de la transacción. Valores canónicos: IN, OUT, SELF. No distingue mayúsculas de minúsculas; INBOUND y OUTBOUND se aceptan como alias de IN y OUT. Un valor no reconocido o ausente se registra como OUT sin error de validación (consulte PIX In).
statusstringEstado de la transacción en el sistema de origen
isInternationalbooleanSi se trata de una transacción transfronteriza
originSystemstringIdentificador del sistema de origen
CampoTipoDescripción
idstringIdentificador del device
typestringTipo de device (mobile, desktop, tablet)
osstringSistema operativo (android, ios, windows)
isNewDevicebooleanPrimera vez que se ve este device
isTrustedDevicebooleanEl device está en la lista de confianza
hasScreenSharingbooleanSe detectó compartición de pantalla
isEmulatorbooleanSe detectó un emulador
isRootedJailbrokenbooleanSe detectó un device con root o jailbreak
ipAddressstringDirección IP de origen
CampoTipoDescripción
namestringNombre de la contraparte
taxIdentifierobject{ "taxId": "...", "country": "..." }
isNewCounterpartbooleanPrimera transacción con esta contraparte
riskScorenumberPuntaje de riesgo preexistente de la contraparte
transactionsCountintegerCantidad histórica de transacciones con esta contraparte
isSanctionedEntitybooleanSi la contraparte está en una lista de sanciones
isSameNetworkbooleanSi la contraparte pertenece a la misma red
MétodoRutaAutenticaciónDescripción
POST/api/v2/decisions/analyzeAPI KeyEnviar una transacción para análisis de fraude
GET/api/v2/decisions/{id}API KeyConsultar una decisión por ID
POST/api/v2/decisions/{id}/cancelAPI KeyCancelar una decisión en REVIEW
GET/api/v2/decisions/notificationsAPI KeyListar las notificaciones no entregadas (sondeo)
POST/api/v2/decisions/notifications/{delivery_id}/ackAPI KeyConfirmar una notificación obtenida por sondeo
GET/api/v2/holidaysAPI Key (holidays.read)Consultar los feriados nacionales y bancarios de un año dado

Versión 18, actualizada el