Referencia API
El API de BCH Instant se sirve bajo el prefijo /api/v1. Todas las peticiones y respuestas son JSON (Content-Type: application/json) y los importes son cadenas decimales en ehnl (Lempira digital, 2 decimales).
Los ejemplos de esta referencia usan datos de demostración: el banco Banco Demo con usuarios y pagos pre-cargados, y @alias resolubles en otros bancos participantes (
@juanp,@sofiar,@pedroh).
Autenticación
Cada banco participante recibe una clave de API por entorno durante el onboarding. Envíala en todas las peticiones como bearer token:
Authorization: Bearer <tu_clave_de_api>
La clave identifica a tu banco (organización): los usuarios que registras y los pagos que envías quedan asociados a él, y los listados solo devuelven la actividad en la que tu banco participa.
Usuarios — /api/v1/users
Clientes de tu banco registrados en la red de pagos instantáneos.
| Método y ruta | Descripción |
|---|---|
POST /users | Registra un cliente en la red |
GET /users | Lista los usuarios de tu banco |
GET /users/{userId} | Obtiene un usuario |
POST /users/{userId}/alias | Registra o reemplaza el @alias del usuario |
/api/v1/usersRegistra un cliente. alias es opcional: puede reservarse en el alta o registrarse después con POST /users/{userId}/alias.
// Petición
{
"firstName": "Laura",
"lastName": "Castillo",
"displayName": "Laura Castillo", // opcional
"alias": "laurac" // opcional
}
// 201 Created
{
"id": "usr_5f3a9c1e8b2d4706",
"organizationId": "org_2f7c1d8a9b3e4f50",
"organizationName": "Banco Demo",
"firstName": "Laura",
"lastName": "Castillo",
"displayName": "Laura Castillo",
"alias": "laurac",
"status": "ACTIVE",
"createdAt": "2026-07-29T15:04:11.000Z"
}Errores: 400 si faltan campos o el alias es inválido, 409 si el alias ya está registrado.
/api/v1/usersLista paginada de los usuarios registrados por tu banco: { "items": [...], "total": 4, "page": 1, "pageSize": 50 }.
/api/v1/users/{userId}Devuelve el usuario, incluido su status (ACTIVE · SUSPENDED · DELETED) y su @alias actual. 404 si no existe.
/api/v1/users/{userId}/aliasRegistra (o reemplaza) el @alias del usuario. El alias se normaliza a minúsculas y sin la @ inicial.
// Petición
{ "alias": "laurac" }
// 200 OK → el usuario actualizado
{ "id": "usr_5f3a9c1e8b2d4706", "alias": "laurac", ... }Errores: 409 si el alias está ocupado, 400 si no cumple el formato (3–30 caracteres: a-z, 0-9, ., _, -).
Alias — /api/v1/aliases
El directorio de @alias de toda la red, compartido por todos los bancos participantes.
| Método y ruta | Descripción |
|---|---|
GET /aliases/{alias}/availability | Comprueba si un @alias está libre |
GET /aliases/{alias}/resolve | Resuelve un @alias a su titular, en cualquier banco |
/api/v1/aliases/{alias}/availabilityPensado para validar en vivo mientras el cliente teclea. Devuelve el alias normalizado y si puede registrarse:
// 200 OK
{ "alias": "laurac", "available": true }/api/v1/aliases/{alias}/resolveResuelve un @alias a su titular para confirmar el destinatario antes de pagar — funciona igual para alias de tu banco y de cualquier otro banco participante:
// 200 OK
{
"alias": "juanp",
"displayName": "Juan Pérez",
"organizationId": "org_8a1b2c3d4e5f6071",
"organizationName": "Banco Atlántida"
}404 si el alias no está registrado en la red.
Pagos — /api/v1/payments
Envío y consulta de pagos instantáneos. Los pagos dentro de tu banco (INTERNAL) liquidan internamente; entre bancos (CROSS_ORGANIZATION) liquidan on-chain en los rieles CBDC y la respuesta incluye el hash y la altura de bloque de la transacción de liquidación.
| Método y ruta | Descripción |
|---|---|
POST /payments | Envía un pago instantáneo a un @alias |
GET /payments | Lista los pagos de tu banco (paginado, filtrable) |
GET /payments/{paymentId} | Obtiene un pago por id o por id público ip_… |
/api/v1/paymentsEnvía un pago desde uno de tus usuarios a cualquier @alias de la red. Envía siempre un idempotencyKey: si la petición se repite, devuelve el pago original en lugar de crear un duplicado.
// Petición
{
"senderUserId": "usr_5f3a9c1e8b2d4706",
"recipientAlias": "juanp",
"amount": "150.00",
"denom": "ehnl", // opcional, por defecto ehnl
"reference": "Almuerzo", // opcional, concepto libre
"idempotencyKey": "9c2e6a4f-…" // recomendado
}
// 201 Created
{
"id": "pay_1c9e5b7a3f2d8064",
"publicId": "ip_4e8a9f702c5d8b1a",
"status": "FINALIZED",
"kind": "CROSS_ORGANIZATION",
"reference": "Almuerzo",
"sender": { "alias": "laurac", "name": "Laura Castillo",
"organizationName": "Banco Demo", ... },
"recipient": { "alias": "juanp", "name": "Juan Pérez",
"organizationName": "Banco Atlántida", ... },
"amount": { "denom": "ehnl", "amount": "150.00" },
"chainTxHash": "8F4A…C21D",
"chainHeight": "1851204",
"settlement": {
"type": "ON_CHAIN",
"fromBank": "Banco Demo",
"toBank": "Banco Atlántida",
"chainTxHash": "8F4A…C21D",
"chainHeight": "1851204"
},
"timings": { "totalMs": 3120, "settlementMs": 2720 },
"failureCode": null,
"failureMessage": null,
"createdAt": "2026-07-29T15:06:02.000Z",
"completedAt": "2026-07-29T15:06:05.120Z"
}El ciclo de vida del pago es RECEIVED → PREPARED → SIGNED → SUBMITTED → FINALIZED (o FAILED con failureCode). La respuesta se devuelve con el pago ya finalizado.
Errores: 404 si el emisor o el alias destino no existen, 422 si el emisor no tiene @alias o coincide con el destino, 400 si el importe es inválido.
/api/v1/paymentsLista los pagos en los que participa tu banco, del más reciente al más antiguo.
| Parámetro | Descripción |
|---|---|
direction | INBOUND · OUTBOUND · INTERNAL, relativo a tu banco |
alias | Solo pagos enviados o recibidos por ese @alias (historial de un cliente) |
page, pageSize | Paginación (por defecto 1 y 20, máx. 100) |
// 200 OK
{
"items": [ { "publicId": "ip_9f8e7d6c5b4a3921", "direction": "OUTBOUND", ... } ],
"total": 6,
"page": 1,
"pageSize": 20
}/api/v1/payments/{paymentId}Devuelve el pago completo por su id interno o su publicId (familia ip_…, apto para mostrarse y copiarse en tu app). 404 si no existe.
Errores
Todos los errores comparten el mismo cuerpo:
{
"statusCode": 409,
"error": "Conflict",
"message": "Alias @laurac is already registered."
}| Código | Cuándo |
|---|---|
400 Bad Request | Cuerpo o parámetros inválidos (importe mal formado, alias con formato incorrecto…) |
401 Unauthorized | Clave de API ausente o inválida |
404 Not Found | Usuario, pago o @alias inexistente |
409 Conflict | @alias ya registrado por otro usuario |
422 Unprocessable Entity | Pago no procesable (emisor sin @alias, emisor y destino iguales…) |