Saltar al contenido principal

Migración desde AMLBot

Si tu servicio ya verifica direcciones y transacciones con la API de AMLBot, puedes pasar a Leeri sin tocar su código de solicitudes. Leeri expone un endpoint compatible con AMLBot que reproduce el contrato de comunicación campo por campo: las mismas solicitudes en formato de formulario, el mismo token MD5, el mismo sobre de respuesta y el mismo ciclo de pending y recheck. Esta página describe ese contrato tal como lo implementa Leeri.

Cambia en un día​

Cambian tres variables de entorno y nada más.

VariableCámbiala a
AMLBOT_URLhttps://api.leeri.ai/compat/amlbot
AMLBOT_IDEl accessId de tu credencial compat.
AMLBOT_KEYEl secreto de la misma credencial compat.

La construcción de solicitudes, el cálculo del token, la codificación del formulario, los nombres de los campos y tu bucle de pending siguen exactamente como están.

Leeri emite una credencial compat junto con tu cuenta: escribe a hello@leeri.ai. Es independiente de las claves ak_ de la API nativa, y el motivo es técnico. El protocolo exige que el servidor recalcule el token MD5 a partir del secreto en texto claro, mientras que una clave de API se almacena de forma irreversible y no puede recuperarse. Una credencial compat tiene su propio accessId, su propio secreto y su propia rotación. Durante una rotación se aceptan durante un tiempo tanto el secreto antiguo como el nuevo, de modo que pasar tu servicio al nuevo es un cambio de configuración y no una interrupción.

Una credencial compat pertenece a un entorno, sandbox o live, igual que una clave de API. Empieza con una credencial sandbox: consulta Probar el bucle de pending.

Solicitudes​

Ambos tipos de solicitud son un POST con Content-Type: application/x-www-form-urlencoded a la misma URL. Los campos presentes deciden de cuál se trata.

CampoVerificación de direcciónVerificación de transacción
accessIdobligatorioobligatorio
tokenobligatorioobligatorio
hashla dirección a cribarel hash de la transacción
assetobligatorioobligatorio
addressno se envíala dirección de la transacción a cribar
directionno se envíadeposit o withdrawal

asset es un símbolo exactamente como aparece en Activos admitidos. Los campos desconocidos se rechazan. direction acepta el valor abreviado withdrawa que envían algunos clientes y lo lee como withdrawal.

El token​

token = MD5("{hash}:{key}:{accessId}")

hash es el valor del campo hash que envías, key es tu secreto compat y accessId es tu accessId compat. El resultado es el resumen hexadecimal de 32 caracteres en minúsculas.

El token se calcula una sola vez, a partir de la solicitud de verificación original, y se reenvía sin cambios en cada recheck. Nunca se recalcula a partir del uid de la verificación. Tu cliente ya se comporta así; no lo cambies.

TOKEN=$(printf '%s' "$ADDRESS:$AMLBOT_KEY:$AMLBOT_ID" | openssl md5 | awk '{print $NF}')

curl -s -X POST "$AMLBOT_URL" \
--data-urlencode "accessId=$AMLBOT_ID" \
--data-urlencode "token=$TOKEN" \
--data-urlencode "hash=$ADDRESS" \
--data-urlencode "asset=TRX"

Para una verificación de transacción, envía el hash de la transacción como hash y añade address y direction. El token sigue siendo MD5("{hash}:{key}:{accessId}") con ese hash de transacción.

Respuestas​

Solo result y balance están en el nivel superior. La carga útil va anidada en data.

{
"result": true,
"balance": 4210,
"data": {
"status": "success",
"uid": "5b0c3f64-1a52-4c8e-9f3e-2f6c1d7a9e10",
"riskscore": 0.74,
"signals": {
"atm": 0,
"child_exploitation": 0,
"dark_market": 0,
"dark_service": 0,
"decentralized_exchange_contract": 0,
"enforcement_action": 0,
"exchange": 0.05,
"exchange_fraudulent": 0,
"gambling": 0,
"illegal_service": 0,
"infrastructure_as_a_service": 0,
"liquidity_pools": 0,
"malware": 0,
"marketplace": 0,
"merchant_services": 0,
"miner": 0,
"mixer": 0.12,
"other": 0,
"p2p_exchange": 0,
"p2p_exchange_mlrisk_high": 0,
"payment": 0,
"ransom": 0,
"risky_exchange": 0,
"sanctions": 0,
"scam": 0,
"seized_assets": 0,
"stolen_coins": 0,
"terrorism_financing": 0,
"unnamed_service": 0.31,
"wallet": 0,
"unnamed_entity_low_risk": 0,
"unnamed_entity_medium_risk": 0,
"unnamed_entity_high_risk": 0
},
"address": "TEXAMPLEexampleEXAMPLEexample00000",
"fiat_code_effective": "USD",
"counterparty": null,
"reportedAddressBalance": null,
"addressDetailsData": null,
"blackListsConnections": false,
"hasBlackListFlag": false,
"pdfReport": "https://…",
"memo": null,
"asset": "TRX",
"network": "tron",
"timestamp": "2026-10-27 09:14:04"
}
}

Los valores son ilustrativos. Una verificación de transacción responde con los mismos campos y añade amount, risky_volume, risky_volume_fiat, fiat, direction y tx.

Los cuatro campos que usa tu control de flujo​

CampoRama que determina
resultÉxito (true) o fallo (false).
data.statusRespuesta final o todavía pending.
balanceLa rama de saldo agotado.
data.uidLo que consulta el recheck.

Todos los demás campos son datos para mostrar.

Estado​

data.statusSignificado
successLa verificación es definitiva y data lleva el resultado.
pendingLa verificación está en cola. data lleva solo status, uid, asset, network, address y timestamp. Consulta como se describe en Pending y recheck.
failed, errorEstados terminales del contrato. Un recheck posterior nunca los resuelve, así que deja de consultar. Leeri informa de una verificación que terminó sin veredicto mediante result: false, descrito más abajo.

Los fallos responden HTTP 200​

Un fallo no es un error HTTP. El endpoint responde 200 y pone result en false:

{
"result": false,
"balance": 0,
"description": "AML check failed\nInvalid token"
}

description tiene dos líneas. La primera es el texto fijo AML check failed y el motivo está en la segunda línea, que es donde tu cliente ya lo lee.

Motivo en la segunda líneaSignificadoQué hacer
Invalid tokenEl accessId es desconocido, está revocado o caducado, el token no coincide, o un recheck nombra un uid que nunca se aceptó para esta credencial. Todos estos casos responden igual.Revisa la credencial y el cálculo del token. En un recheck, comprueba que reenvías el token original.
Out of balanceTu cuota y tu saldo prepagado están agotados.Recarga y reintenta. Reintentar antes no ayuda.
Analysis unavailable, please retryUna fuente de datos de la que depende el veredicto no estaba disponible. No se cobra nada.Reintenta más tarde.
Service temporarily unavailable, please retryUn fallo inesperado de nuestro lado.Reintenta con retroceso exponencial.
Un mensaje de validaciónEl activo no es admitido, la dirección o el hash de transacción tienen una forma incorrecta para el activo, direction no es una dirección de flujo, o falta un campo o es desconocido.Corrige la solicitud. Reintentar sin cambios devuelve la misma respuesta.
Un mensaje de capacidadLa capacidad para consultas está llena. No se acepta ni se cobra nada.Reintenta tras una breve pausa.

La única respuesta distinta de 200 en este endpoint es la limitación de solicitudes: está tras los mismos limitadores generales que la API nativa y responde 429 con Retry-After. Consulta Límites de solicitudes y cuotas.

Saldo​

balance es el número de verificaciones que Leeri aún te atenderá: la cuota restante de tu plan más lo que el saldo prepagado todavía puede comprar. No es el saldo prepagado literal, que marca 0 durante la mayor parte de un periodo de facturación sano porque la cuota se gasta primero. El saldo prepagado exacto está en tu factura y en tu panel. Tras un fallo de autenticación, balance es 0.

Puntuación de riesgo y señales​

  • riskscore es una fracción de 0 a 1, escalada a partir de la puntuación de 0 a 100 de Leeri. Nunca es un número entero sobre 100.
  • signals contiene el vocabulario fijo de 33 claves mostrado arriba. Cada clave está presente en cada respuesta y la mayoría vale 0. Cada valor es una fracción de exposición. Los hallazgos y la exposición de Leeri se agrupan en estas claves por compatibilidad de protocolo; es una agrupación y no una correspondencia uno a uno de categorías.
  • Cuando la propia dirección verificada tiene una designación que explica la mayor parte de la puntuación, por ejemplo la dirección de una entidad sancionada, signals nombra esa categoría con 1 y todas las demás claves con 0. riskscore no cambia.
  • Un aviso de seguridad de la wallet, que advierte al propietario de la dirección y no dice nada sobre su riesgo, nunca se refleja en riskscore ni en signals.
  • blackListsConnections es false, no un array vacío, cuando no hay coincidencias. Comprueba específicamente false, ya que un array vacío es verdadero.
  • timestamp es una cadena con el formato YYYY-MM-DD HH:MM:SS, nunca un número Unix.

El informe de evidencias​

data.pdfReport es un enlace permanente al informe de evidencias de la verificación, incluido en el precio de la verificación. El PDF se genera al abrir el enlace por primera vez. El enlace es null en el raro caso de que no se pudiera construir el informe, y el resto de la respuesta no se ve afectado. Una verificación pending aún no tiene pdfReport. Cualquiera que tenga el enlace puede leer el informe, así que trátalo como tratas el informe.

Campos que quedan vacíos​

reportedAddressBalance, addressDetailsData y memo son siempre null. counterparty es null salvo que un hallazgo nombre a un exchange como propietario de la dirección. Los saldos de la dirección verificada en el momento de la verificación están en el informe de evidencias.

Pending y recheck​

Cuando una verificación no puede terminar dentro de la solicitud, la respuesta trae result: true, data.status: "pending" y un uid. Consulta con:

POST https://api.leeri.ai/compat/amlbot/recheck

La ruta no lleva barra final. Los campos del formulario son accessId, uid y el token original.

curl -s -X POST "$AMLBOT_URL/recheck" \
--data-urlencode "accessId=$AMLBOT_ID" \
--data-urlencode "uid=$UID" \
--data-urlencode "token=$TOKEN"
  • La respuesta es el mismo sobre que la verificación original: todavía pending, un resultado final o result: false.
  • Un recheck lee la verificación ya aceptada. No inicia nada nuevo y no se cobra.
  • El token debe coincidir con el presentado en la solicitud original. Un token distinto, o un uid que esta credencial nunca aceptó, responde Invalid token.
  • El bucle que ya ejecuta tu cliente consulta cada 30 segundos hasta 10 intentos, un presupuesto de 5 minutos. Leeri conserva la asociación entre el uid y el token original durante 30 minutos tras aceptar la verificación, así que ese bucle cabe de sobra. Pasado ese plazo, un recheck responde Invalid token.

Probar el bucle de pending​

Con una credencial sandbox, una verificación de dirección para el activo BTC y la dirección 1PENDNGCHECKADDRESSFRSANDBXTEST99 siempre responde pending, así que puedes ejercitar todo el bucle desde el primer día. Consulta Sandbox y live. La misma dirección con una credencial live se completa con normalidad.

Facturación​

Una verificación compat se factura con las mismas reglas que una nativa. Se paga primero con la cuota restante y después con el saldo prepagado. Repetir la verificación de la misma dirección en la misma cadena en un plazo de 7 días es gratis. Una verificación fallida, una solicitud rechazada y un veredicto parcial porque una fuente de datos estaba caída no se cobran. El informe de evidencias forma parte de la verificación. Los detalles están en Límites de solicitudes y cuotas. Los planes y precios están en la página de precios.

Cuando tengas tiempo: la API nativa​

El endpoint compatible deja tu integración sin cambios. La API nativa es a lo que conviene pasar cuando quieres más de cada veredicto:

  • Cada hallazgo enlaza la fuente en la que se apoya, y el veredicto queda fijado para poder reproducirlo después. Consulta Verificaciones de dirección y Rederive.
  • Un webhook entrega cada verificación terminada, así que no hay nada que consultar.

Ambas superficies funcionan sobre el mismo motor y el mismo ruleset, y puedes usarlas a la vez con la misma cuenta. Preguntas sobre la migración: hello@leeri.ai.