API
Solicita acceso →
Referencia / Cuenta y sistema

Cuenta y sistema

Los endpoints de Cuenta y sistema son la "sala de control" de tu integración con Alibanca: no mueven dinero ni tocan beneficiarios, solo te dicen con quién estás hablando, qué versión de la API está del otro lado y si el servicio está vivo. Son livianos, de bajo riesgo y perfectos para el arranque: los llamas antes de firmar tu primera operación, los usas para poblar un panel interno y los conectas a tu monitoreo. En esta página encontrarás la referencia completa de los tres: GET /v2/me, GET /v2/version y GET /health, con la respuesta entera de cada uno explicada campo por campo.

i
Piénsalo como el tablero de tu carro. No te lleva a ningún lado, pero antes de arrancar miras el nivel de gasolina (/health), confirmas que es tu carro y no el del vecino (/v2/me) y revisas qué modelo estás manejando (/v2/version). Estos tres endpoints hacen exactamente eso para tu integración.

Los tres endpoints de esta sección

Esta sección agrupa los endpoints de identidad y estado del servicio. Dos de ellos son públicos (no requieren llave ni firma) y uno es autenticado (te dice quién eres, así que primero tiene que saber quién eres). Aquí los tienes de un vistazo:

GET/v2/meLa identidad de tu llave: quién eres, en qué entorno, tu huella de llave pública, tu webhook y tus límites. Nunca devuelve un secreto.
GET/v2/versionDescubrimiento (discovery) público: versión, apiVersion, entorno, rieles disponibles y enlaces al OpenAPI y al JWKS.
GET/healthChequeo de salud público: responde 200 cuando el servicio está operativo. Ideal para tu monitoreo.
i
Público vs. autenticado. "Público" significa que puedes llamarlo sin x-api-key, x-nonce ni x-signature — lo abres desde el navegador o desde un healthcheck sin credenciales. "Autenticado" significa que la API necesita tu llave firmada para responder, porque la respuesta es específica de tu cuenta.

GET /v2/me — la identidad de tu llave

GET/v2/me

GET /v2/me te devuelve la identidad asociada a la llave con la que firmaste el request. No es "tu usuario" ni "tu login": es la cédula de la llave que estás usando en ese momento. Esto importa porque una misma organización puede tener varias llaves (una de sandbox, una de producción, quizás una por ambiente de despliegue), y cada request se identifica por la llave que lo firmó. /v2/me te dice, sin ambigüedad, con cuál estás operando ahora mismo.

¿Para qué lo usas?

Es la primera llamada autenticada que deberías hacer al integrarte, por tres razones muy prácticas:

1) Confirmar que tu firma funciona. Como /v2/me exige x-api-key + x-nonce + x-signature pero no mueve dinero, es el "hola mundo" seguro de la autenticación. Si /v2/me te responde 200, tu envelope canónico, tu firma RSA-SHA256 y tu nonce están bien armados. Si falla, arreglas la firma antes de arriesgar un pago.

2) Evitar disparar en el entorno equivocado. El campo environment te dice si estás en sandbox (proveedor simulado, no mueve un centavo real) o en production. Un chequeo defensivo — "si environment no es el que espero, aborto" — te salva de mandar un pago real creyendo que estabas probando.

3) Poblar un panel interno. Nombre de la cuenta, huella de la llave pública, webhook configurado y límites vigentes: todo lo que tu equipo de operaciones necesita ver de un vistazo sale de aquí.

Autenticación

/v2/me es un endpoint autenticado. Cada request lleva x-api-key con tu llave (sk_test_… en sandbox, sk_live_… en producción) y x-signature con la firma RSA-SHA256 del envelope canónico (la concatenación determinística de método, ruta, api-key, idempotency-key, cuerpo crudo y nonce). Tu llave privada nunca sale de tu lado; Alibanca verifica con tu llave pública. Para el detalle completo del envelope y la firma, ve a Autenticación y firma →.

cURLNodeCopiar
# GET /v2/me — necesita x-api-key + x-nonce + x-signature (no mueve dinero)
curl https://alibanca-api-production.up.railway.app/v2/me \
  -H "x-api-key: sk_test_tu_llave_aqui" \
  -H "x-signature: {firma_RSA-SHA256_del_envelope}" \
  -H "x-nonce: 1721683200123456"

Y así se ve la respuesta completa. Fíjate que viene envuelta en el sobre de éxito estándar de Alibanca (status + traceId + payload), y que todo lo interesante está en payload:

RESPUESTA 200 application/json
{
  "status": "success",
  "traceId": "trc_9f3a2b7c8d1e4f60",
  "payload": {
    "remitterId": "137",
    "name": "Acme Remesas C.A.",
    "environment": "sandbox",
    "keyType": "test",
    "publicKeyFingerprint": "SHA256:8b2ed669a120e97b8cf0bceb949698e7c26c1b8f1e05c8bc26a9584512f97792",
    "webhook": {
      "url": "https://acme.example.com/hooks/alibanca",
      "pendingChange": null
    },
    "limitsConfigured": true,
    "limits": [
      {
        "payoutType": "*",
        "window": "TX",
        "maxAmountMinor": "…",
        "maxCount": null,
        "isFloor": true
      },
      {
        "payoutType": "PM",
        "window": "DAY",
        "maxAmountMinor": "…",
        "maxCount": null,
        "isFloor": false
      }
    ]
  }
}

Campo por campo

Cada campo de payload tiene un propósito. Aquí está el detalle:

CampoTipoDescripción
remitterIdstringEl identificador estable de tu cuenta (el "remitente" que emite pagos). Es el mismo aunque rotes tus llaves, así que úsalo para atar registros en tu propio sistema. No es un secreto: es un ID de referencia.
namestringEl nombre legible de tu organización tal como está registrado en Alibanca. Útil para mostrar en paneles internos y confirmar visualmente que la llave pertenece a quien crees.
environmentstringEl entorno de la llave: sandbox (proveedor simulado, ningún movimiento real de dinero) o production (dinero real). Chequéalo defensivamente antes de emitir pagos para no cruzar entornos por error.
keyTypestringEl tipo de llave con que firmaste: test (sandbox), live (producción) o legacy (una llave anterior al esquema de prefijos). Sale del prefijo de tu x-api-key: sk_test_test, sk_live_live. legacy es el valor para una llave sin prefijo reconocido y no lo vas a ver: el servidor rechaza esas llaves con 401 antes de llegar acá (sk_test_… / sk_live_…) y te confirma que estás usando la llave correcta para el ambiente correcto.
publicKeyFingerprintstringLa huella (fingerprint) de tu llave pública: SHA256: seguido del SHA-256 del DER en formato SPKI, en 64 dígitos hexadecimales minúsculos. Reprodúcela en dos pasos: openssl pkey -pubin -in tu-publica.pem -outform DER -out tu.der y luego openssl dgst -sha256 tu.der — la huella es el hex que imprime. En un solo pipe no: si el primer comando falla, el segundo igual imprime el digest del vacío con código 0 y lo leerías como un desacuerdo que no existe. No es la huella estilo SSH de ssh-keygen -lf: esa resume el bloque en formato SSH, no el DER SPKI, así que da otro digest —no el mismo en otro alfabeto— y sobre el .pem que te pedimos ni siquiera corre (responde "is not a public key file"). Es un resumen corto y verificable de la llave pública que Alibanca tiene registrada para ti. Compárala con la huella de tu propia llave para confirmar que ambos lados hablan del mismo par de llaves. Es la pública, no la privada: exponerla no compromete nada.
webhookobjectLa configuración actual de tu webhook. Trae url (el endpoint donde recibes los eventos de cambio de estado de un pago) y pendingChange (una URL propuesta que aún no ha sido confirmada/activada, o null si no hay cambios en cola). Es un espejo de solo lectura de lo que administras en la sección de Webhooks →.
limitsConfiguredbooleanEste es el campo sobre el que debes ramificar antes de operar, no el arreglo limits. En false significa que al menos un riel no tiene la política de límites configurada del lado de Alibanca, y los pagos por ese riel responden 422 — no importa el monto. No es «no tienes topes»: es que no podemos dispersar por ahí, y es un problema nuestro, no tuyo. El campo es conservador a propósito: se pone en false si falta la cobertura de cualquiera de los rieles, aunque el que tú uses esté cubierto. La trampa que este campo existe para evitar: un limits vacío parece «sin restricciones» y significa exactamente lo contrario.
limitsarrayLa lista de límites vigentes que aplican a tus operaciones. Incluye tanto los límites propios de tu cuenta como los pisos (mínimos de seguridad) que impone Alibanca. Cada entrada trae payoutType (el riel al que aplica, o * para todos), window (TX es por operación; el resto acumula sobre una ventana), maxAmountMinor (tope de monto en unidades menores, como string, o null si ese límite no acota monto), maxCount (tope de cantidad, o null) y isFloor (true si lo impone Alibanca, false si lo configuraste tú). Un piso de Alibanca lo puedes apretar, nunca aflojar.

Si tu huella no coincide, mira primero el alfabeto

Antes de asumir que registramos la llave equivocada, descarta el desacuerdo falso más común: que los dos lados hayan calculado el mismo SHA-256 del DER SPKI y lo hayan escrito distinto. Nuestro publicKeyFingerprint va en hexadecimal — 64 caracteres del 0 a la f —, y muchas librerías entregan ese mismo digest en base64: 44 caracteres, con mayúsculas, +, / y un = al final. Es el mismo número en otra base. Conviértelo a hexadecimal y recién ahí compara.

DE BASE64 A HEXADECIMAL
# el -A es obligatorio y el '=' del final no se toca (ver el aviso de abajo)
echo 'rQrqzbwVJdQnMqRhxRwkpnlLS+yfjpbhCFReyuKXuko=' | openssl base64 -d -A | xxd -p -c 32
# ad0aeacdbc1525d42732a461c51c24a6794b4bec9f8e96e108545ecae297ba4a
!
openssl base64 -d puede devolver cero bytes y salir con código 0. No falla, no escribe nada en stderr, y tú lees ese vacío como «la huella no coincide». Medido con OpenSSL 3.6.3, hay dos caminos distintos que caen ahí: si le quitaste el = del final, decodifica a 0 bytes — y el valor que imprime ssh-keygen viene siempre sin ese relleno, así que pegarlo tal cual cae justo acá; y si pasaste el valor sin salto de línea final, también da 0 bytes, salvo que agregues -A. Por eso el comando de arriba lleva -A y conserva el =. La regla corta: si lo decodificado no mide 32 bytes, no decodificaste nada — no compares.
!
Nunca devuelve un secreto. /v2/me jamás retorna tu llave privada, tu x-api-key completa ni ningún material sensible. Todo lo que ves es identidad y configuración de solo lectura: IDs de referencia, tu nombre, tu entorno, la huella de tu llave pública, tu URL de webhook y tus límites. Es seguro loguearlo o mostrarlo en un panel interno — aun así, trata el remitterId y la huella como datos operativos, no los publiques al mundo sin necesidad.
Pruébalo. En sandbox, tu primera llamada real debería ser GET /v2/me. Si te responde 200 con tu name correcto y environment: "sandbox", tu firma está bien armada y ya puedes pasar a emitir pagos de prueba. Si te da 401, revisa el orden del envelope canónico y que el nonce no esté repetido.

GET /v2/version — descubrimiento (discovery)

GET/v2/version

GET /v2/version es un endpoint público de descubrimiento: no lleva llave ni firma, y te dice qué hay del otro lado de la línea. Su rol en tu integración es ser la primera llamada de todas, antes de firmar nada. Piénsalo como marcar un número y escuchar el tono: confirmas que hay conexión, qué versión atiende, en qué entorno estás y dónde encontrar los recursos que necesitas (el contrato OpenAPI y las llaves públicas de verificación de webhooks).

¿Por qué llamarlo antes de firmar?

Firmar un request tiene varios pasos (armar el envelope, calcular la firma RSA-SHA256, avanzar el nonce). Si algo de red está mal — DNS, un proxy, una URL base equivocada — no quieres descubrirlo después de gastar esfuerzo firmando. /v2/version es la prueba de vida sin credenciales: si te responde, la conectividad y la URL base están bien, y recién entonces te pones a firmar. Además, el campo environment te confirma a qué mundo estás apuntando, y rails te dice qué rieles de dispersión están disponibles hoy.

cURLNodeCopiar
# GET /v2/version — público, sin llave ni firma
curl https://alibanca-api-production.up.railway.app/v2/version
RESPUESTA 200 application/json
{
  "status": "success",
  "traceId": "trc_2b9c5b1986fc",
  "payload": {
    "version": "0.24.0",
    "buildId": "b2760f1414431ed4",
    "apiVersion": "v2",
    "environment": "sandbox",
    "rails": ["PM", "CCE"],
    "simulado": false,
    "links": {
      "openapi": "/v2/openapi.json",
      "jwks": "/v2/webhook/keys"
    }
  }
}

Campo por campo

CampoTipoDescripción
versionstringLa versión concreta del servicio desplegado (por ejemplo 0.13.0). Sube con cada release. Útil para diagnósticos ("¿qué build estaba corriendo cuando pasó esto?") y para tu monitoreo de despliegues.
apiVersionstringLa versión mayor del contrato de la API: v2. Es la que aparece en el prefijo de todas las rutas (/v2/…). No cambia con cada release; solo cambiaría en un salto de contrato mayor.
environmentstringEl entorno que atiende esta URL base: sandbox o production. Te sirve para confirmar, sin autenticarte, que estás apuntando a donde crees.
railsarrayLos rieles de dispersión habilitados en este entorno: "PM" (pago móvil) y/o "CCE" (transferencia interbancaria). Léelo dinámicamente y no lo asumas: un entorno puede tener un riel cerrado, y el sandbox puede anunciar rieles que un despliegue de producción tiene deshabilitados. Al emitir un pago con destino en línea, rail tiene que ser uno de los que este endpoint devuelve.
simuladobooleanSi es true, este entorno fabrica el resultado de los pagos y no se mueve ni un céntimo real: un pago te va a decir completed igual. Si es false, los rieles están conectados a un banco de verdad y un pago mueve dinero. Míralo antes de creer que una prueba salió bien — es el único campo que distingue los dos casos: rails publica lo mismo en ambos.
links.openapistringLa URL del contrato completo de la API en formato OpenAPI (/v2/openapi.json, también público). Es la fuente de verdad de cada endpoint, campo y esquema — ideal para generar clientes o validar tu integración contra el contrato.
links.jwksstringLa URL del JWKS (JSON Web Key Set): el conjunto de llaves públicas con las que verificas la firma de los webhooks entrantes. Como los webhooks van firmados con RSA asimétrica, no necesitas ningún secreto compartido: descargas estas llaves públicas y validas.
i
Discovery = "descúbrelo, no lo hardcodees". En vez de escribir a mano en tu código las URLs del OpenAPI o del JWKS, léelas de links. Así, si mañana cambian, tu integración las sigue encontrando sola. Es el mismo patrón que usan las APIs grandes para no romperte cuando reorganizan sus recursos.
Pruébalo. Abre https://alibanca-api-production.up.railway.app/v2/version en tu navegador ahora mismo — como es público, no necesitas llave. Deberías ver environment: "sandbox" y rails: ["PM","CCE"]. Ese es el "tono de línea" que confirma que el sandbox está de tu lado.

GET /health — ¿está viva la API?

GET/health

GET /health es un chequeo de salud público: responde 200 cuando el servicio está operativo y puede dispersar, y 503 con un status que distingue la causa. No lleva llave, no lleva firma, no revela nada de tu cuenta — su único trabajo es decir "estoy viva". Está pensado para conectarlo a tu sistema de monitoreo (uptime, balanceadores de carga, alertas): un sondeo cada cierto tiempo que espera un 200 y levanta una alarma si deja de recibirlo.

i
/health vs. /v2/version. Los dos son públicos, pero cumplen roles distintos. /health responde ¿está arriba? — y es barato de sondear seguido. /v2/version te da metadata (versión, entorno, rieles, enlaces): lo llamas una vez al arrancar, no en un bucle de monitoreo. Nota además que /health no lleva el prefijo /v2: es un endpoint a nivel de servicio, no del contrato de la API.
cURLNodeCopiar
# GET /health — público, para tu monitoreo
curl https://alibanca-api-production.up.railway.app/health
RESPUESTA 200 application/json
{ "status": "ok" }

La regla para tu monitoreo: trata cualquier cosa que no sea un 200 como "servicio degradado" y dispara tu alerta — pero sí parsea el cuerpo, porque el 503 tiene dos causas muy distintas y una de ellas no es una caída:

statusqué pasóqué hacer
db_unavailableLa API no puede hablar con su base. Esto sí es una caída.Espera y reintenta; nosotros ya estamos alertados.
dispersal_blocked_no_limits_floorLa API está viva —lee, lista, autentica— pero hay al menos un riel por el que nadie puede dispersar: le falta su piso de límites de nuestro lado, así que todo POST /v2/payments por ese riel responde 422. No es una caída y no se arregla reintentando. Para saber si te toca a ti, mira limitsConfigured en GET /v2/me: ese campo responde por tu llave, este status responde por la plataforma.No entres en tu camino de recuperación: no hay pagos en vuelo que reconciliar, porque no salió ninguno. Escríbenos.

Ese 503 con la API viva es deliberado: sin él, una parada total de dispersión sería silenciosa de nuestro lado y te enterarías tú, con 422 en cada pago.

Cómo encajan los tres en tu integración

Estos endpoints no compiten: se complementan en una secuencia natural de arranque y operación. Este es el flujo recomendado la primera vez que te conectas:

1

Confirma la conexión con GET /v2/version

Antes de firmar nada, llama al endpoint público de discovery. Si responde 200, tu URL base y tu red están bien. De paso, guarda links.openapi y links.jwks para no hardcodearlos, y verifica que environment sea el que esperas.

2

Prueba tu firma con GET /v2/me

Ahora sí, arma tu envelope canónico, firma con RSA-SHA256 y llama a /v2/me. Como no mueve dinero, es el lugar seguro para validar autenticación. Un 200 con tu name y keyType correctos significa que tu firma, tu api-key y tu nonce están perfectos.

3

Chequea environment y límites antes de operar

Con la respuesta de /v2/me en mano, valida defensivamente: ¿estás en el environment correcto? ¿limitsConfigured viene en true? (si viene en false, al menos un riel no tiene política configurada de nuestro lado y ningún monto va a pasar por él — no lo deduzcas de que limits venga vacío, que parece justo lo contrario). ¿tus limits permiten el monto que vas a mover? ¿tu webhook.url es la que esperas y pendingChange está en null? Recién entonces emite tu primer pago.

4

Conecta GET /health a tu monitoreo

En paralelo, deja /health sondeándose desde tu sistema de uptime. Así, si el servicio se degrada, te enteras tú antes que tus usuarios, y puedes correlacionar cualquier unknown de un pago con una ventana de indisponibilidad.

Buenas prácticas

Usa /v2/me como prueba de humo, no como parte del camino caliente. Es ideal al arrancar tu proceso o en un test de integración para verificar credenciales. No lo llames antes de cada pago: no aporta nada al camino de emisión y agrega latencia.

Chequea environment defensivamente. Antes de emitir en producción, confirma que environment de /v2/me (o de /v2/version) sea production. Ese pequeño if es la diferencia entre "mandé un pago de prueba" y "mandé un pago real por error".

Lee los recursos desde links, no los hardcodees. Toma las URLs de openapi y jwks del cuerpo de /v2/version. Es el punto de discovery precisamente para que tu código no se rompa si esas rutas cambian.

Registra el traceId. Cuando /v2/me te responde, guarda su traceId en tus logs. Si algo sale raro y necesitas soporte, ese identificador de traza le permite a Alibanca ubicar exactamente tu request.

Sondea /health con moderación. Un intervalo razonable (por ejemplo cada 30–60 segundos) es suficiente para monitoreo. No lo martilles cada segundo: no gana precisión y sí gana ruido.

!
No confundas "servicio arriba" con "pago resuelto". Que /health responda 200 dice que la API está operativa — no dice nada sobre el estado de un pago puntual. El estado de un pago se consulta con GET /v2/payments/:id y vive en su propio ciclo, que atraviesa cinco valores:
pending processing completed unknown failed
Un unknown se resuelve por conciliación de saldo, no mirando el healthcheck.

Errores comunes

401 en /v2/me

Si /v2/me te responde 401, el problema es de autenticación, no del endpoint. Las causas más frecuentes: (a) el orden del envelope canónico no coincide — recuerda que es método, ruta, api-key, idempotency-key, cuerpo crudo y nonce, en ese orden; (b) el nonce no creció respecto al anterior (la marca de agua creciente por llave rechaza replays); o (c) la llave pública que Alibanca tiene registrada no corresponde a la privada con la que firmaste — compara publicKeyFingerprint con la huella de tu propia llave. La respuesta de error viene en el formato estándar:

RESPUESTA 401 application/json
{ "error": "firma inválida" }

Llamar a /v2/me sin firma

A diferencia de /v2/version y /health, /v2/me no es público. Si lo abres en el navegador sin x-api-key, x-nonce ni x-signature, obtendrás un error de autenticación. Es a propósito: la respuesta describe tu cuenta, así que la API tiene que saber quién eres primero.

Apuntar a la URL base equivocada

Si /v2/version te devuelve un environment que no esperabas, revisa tu URL base: el sandbox es https://alibanca-api-production.up.railway.app (proveedor simulado, no mueve dinero real) y producción es https://api.alibanca.com. Cruzarlas es la causa número uno de "mi llave de test no funciona en prod" y viceversa: una llave sk_test_… solo opera contra el sandbox, y una sk_live_… solo contra producción.

i
Regla mnemotécnica. /v2/version primero (¿hay línea?), /v2/me después (¿soy yo, y en qué mundo?), /health siempre de fondo (¿sigue viva?). Con esos tres reflejos incorporados, tu integración arranca sobre terreno firme y opera con la red de seguridad puesta.