API
Solicita acceso →
Empezar / Versionado

Versionado

El API de Alibanca es v2: una versión mayor, estable y con contrato explícito. Versionar significa que le ponemos un número al comportamiento del API para que tu integración no se rompa cuando nosotros evolucionamos por dentro. En esta página aprendes qué significa apiVersion="v2", cómo usar el endpoint público GET /v2/version para descubrir en vivo qué release estás tocando y qué rieles hay disponibles, dónde vive el contrato completo en /v2/openapi.json, y cuál es nuestra política de cambios y compatibilidad para que integres una sola vez y duermas tranquilo.

Qué significa que el API sea v2

Cuando decimos que corres contra v2, nos referimos a la versión mayor del API. Piénsalo como la portada de un contrato: mientras la portada diga "v2", las reglas del juego que ya conoces —los nombres de los campos, la forma de las respuestas, el significado de cada estado— no cambian debajo de tus pies. Todos los endpoints viven bajo el prefijo /v2 justamente por eso: la versión es parte de la URL, no un detalle escondido en un header.

Esto no es un capricho estético. Una integración de pagos toca dinero real, y lo peor que le puede pasar a tu código es que un cambio nuestro —hecho con buena intención— altere el significado de una respuesta y te haga tomar una decisión equivocada sobre un pago. Versionar es nuestra promesa de que eso no ocurre en silencio: si algo cambia de una forma que rompería tu código, cambia el número mayor de la versión, y tú decides cuándo migrar.

i
La versión vive en la URL. No necesitas mandar ningún header de versión para "elegir" v2: ya estás en v2 por el simple hecho de llamar a /v2/.... El día que exista un v3, será otro prefijo (/v3), y v2 seguirá funcionando durante su ventana de soporte.

apiVersion: la etiqueta que viaja de vuelta

Además de ir en la URL, la versión también regresa en las respuestas del API a través del campo apiVersion, cuyo valor hoy es la cadena "v2". Es una etiqueta de confirmación: te dice, sin ambigüedad, con qué contrato se procesó tu request. Es útil para tus logs y para tu observabilidad —cuando guardas la respuesta de un pago, guardas también contra qué versión del API la obtuviste, y meses después sabes exactamente cómo interpretarla.

La regla mental es sencilla: apiVersion es la versión del contrato (lo que tu código puede asumir), mientras que el campo version que verás en un momento es la versión del release desplegado (qué build específico corre en este instante). El contrato es estable; el release avanza con cada mejora interna. Tu código depende del primero, no del segundo.

GET /v2/version — tu handshake de descubrimiento

Antes de firmar tu primer request, hay un endpoint que quieres conocer de memoria. Es público (no lleva llave ni firma), y sirve para lo que en integraciones se llama discovery: preguntarle al servidor "¿quién eres, qué versión corres y dónde están tus documentos?" en una sola llamada. Es el equivalente a tocar la puerta y confirmar que hay alguien en casa antes de entregar el paquete.

GET/v2/version

No recibe parámetros ni cuerpo. Le pegas directo y te responde con un mapa del terreno: la versión del release, la versión del contrato, en qué entorno estás parado, qué rieles de pago están habilitados y los enlaces directos al contrato OpenAPI y al JWKS (el juego de llaves públicas con el que verificarás los webhooks). Como es público, es la manera más barata y segura de confirmar conectividad: si te responde, tu red llega a Alibanca; si no, el problema es de red o de URL base, y ni te molestas en preparar la firma.

cURLNodeCopiar
# Sandbox — no lleva llave ni firma, es público
curl https://alibanca-api-production.up.railway.app/v2/version
cURLNodeCopiar
// Discovery: confirma conexión y descubre rieles antes de firmar nada
const base = "https://alibanca-api-production.up.railway.app";
const res = await fetch(`${base}/v2/version`);
const body = await res.json();

console.log("release:", body.payload.version);
console.log("contrato:", body.payload.apiVersion);
console.log("rieles:", body.payload.rails); // ["PM","CCE"]

La respuesta llega envuelta en el sobre estándar de éxito de Alibanca —status, traceId y payload— con toda la información de discovery adentro de payload:

RESPUESTA 200 application/json
{
  "status": "success",
  "traceId": "trc_9f2c1a7e4b8d",
  "payload": {
    "version": "0.13.0",          // release desplegado (avanza con cada mejora)
    "apiVersion": "v2",          // versión del contrato (estable)
    "environment": "sandbox",     // dónde estás parado: sandbox | production
    "rails": ["PM", "CCE"],     // rieles habilitados: pago móvil y CCE
    "links": {
      "openapi": "https://alibanca-api-production.up.railway.app/v2/openapi.json",
      "jwks": "https://alibanca-api-production.up.railway.app/v2/webhook/keys"
    }
  }
}

Cada campo del payload tiene un para qué concreto. Esta es la lectura campo por campo:

CampoTipoDescripción
versionstringLa versión del release actualmente desplegado (por ejemplo, 0.13.0). Cambia con cada mejora interna que shippeamos. No debes escribir lógica que dependa de este número; sirve para tus logs, para reportar incidencias y para saber exactamente qué build viste cuando algo se comportó raro.
apiVersionstringLa versión del contrato: hoy siempre "v2". Esta es la que sí importa para tu código, porque es la promesa de estabilidad. Mientras diga v2, los nombres de campos y el significado de los estados no cambian de forma que te rompan.
environmentstringDónde estás parado: sandbox o production. Es tu red de seguridad contra el error clásico de apuntar a la URL equivocada. Verifícalo en tu arranque: si esperabas sandbox y te dice production (o al revés), detente antes de emitir un solo pago.
railsstring[]Los rieles de pago habilitados en este entorno. Un riel es la vía por la que viaja el dinero: PM es pago móvil y CCE es transferencia interbancaria por CCE. Léelo dinámicamente en vez de codificar la lista a mano: el día que sumemos un riel nuevo, tu integración lo descubre sola.
links.openapistringURL del contrato OpenAPI en JSON. Es la fuente de verdad, siempre en sync con lo que está desplegado. Sigue este enlace para generar clientes, validar tus cuerpos o alimentar tu documentación interna.
links.jwksstringURL del JWKS: el juego de llaves públicas con el que verificas la firma de los webhooks entrantes. Apunta al mismo recurso que GET /v2/webhook/keys. Te lo damos aquí para que no tengas que hardcodearlo.
Pruébalo. Pégale a GET /v2/version del sandbox sin llave ni firma. Deberías recibir environment: "sandbox" y rails: ["PM","CCE"]. Recuerda que el sandbox usa un proveedor simulado: descubre y explora todo lo que quieras, que no se mueve un centavo real.

Por qué lo llamas ANTES de firmar nada

Firmar un request en Alibanca tiene su ceremonia: construyes un envelope canónico (método, ruta, api-key, idempotency-key, cuerpo crudo y nonce, en ese orden exacto), lo firmas con tu llave privada RSA-SHA256 y mandas la firma en el header x-signature. Es robusto, pero también es donde se cometen los errores tontos de integración: apuntaste a la URL base equivocada, tu reloj está desfasado, tu red no sale, la llave que cargaste no es la correcta. Si intentas depurar todo eso con la firma de por medio, no sabes si el 401 viene de la firma o de la conexión.

GET /v2/version resuelve ese nudo porque es público: no hay firma, no hay llave, no hay nonce. Si te responde 200, ya sabes tres cosas de golpe: (1) tu red llega a Alibanca, (2) tu URL base es correcta, y (3) estás en el entorno que crees. Recién entonces vale la pena preparar la firma. Es literalmente el "hola, ¿me escuchas?" antes de empezar a hablar en serio.

1

Pega a /v2/version al arrancar

En el startup de tu servicio, haz una llamada de discovery. Si falla, tu problema es de red o de URL base — arréglalo antes de seguir.

2

Verifica el entorno

Confirma que environment coincide con lo que esperabas. Esto te salva del error de apuntar a producción creyendo que estás en sandbox.

3

Lee los rieles disponibles

Carga rails en tu configuración en vez de codificar la lista. Así, cuando habilitemos un riel nuevo, tu integración lo ve sin que toques código.

4

Guarda los links

Toma links.openapi y links.jwks de aquí. Son las URLs canónicas del contrato y de las llaves de verificación de webhooks; no las hardcodees.

5

Ahora sí, firma

Con la conexión y el entorno confirmados, construye el envelope canónico, fírmalo y empieza a emitir requests autenticados.

El contrato: /v2/openapi.json

Si /v2/version es el saludo, /v2/openapi.json es el contrato completo por escrito. Es un documento OpenAPI —el estándar de la industria para describir un API REST de forma legible por máquinas— que enumera cada endpoint, cada parámetro, cada campo de respuesta y cada código de error, todo en un solo JSON. También es público: lo consultas sin llave.

GET/v2/openapi.json

La palabra clave aquí es sin drift. La referencia se genera automáticamente a partir de lo que está desplegado, así que el contrato nunca "se atrasa" respecto al comportamiento real del API. Lo que lees en /v2/openapi.json es, byte por byte, lo que el servidor va a hacer. Esto no es garantía menor: en muchos APIs la documentación y el código divergen con el tiempo, y terminas integrando contra una mentira amable. Aquí no.

Con ese contrato en mano puedes hacer cosas muy prácticas sin escribir código a mano: generar un cliente tipado en tu lenguaje, validar que los cuerpos que envías respetan la forma esperada antes de mandarlos, o construir mocks para tus tests. En vez de copiar campos leyendo docs a ojo, dejas que la máquina lea el contrato por ti.

cURLNodeCopiar
# El contrato completo, siempre en sync con lo desplegado
curl https://alibanca-api-production.up.railway.app/v2/openapi.json

# O descúbrelo desde version, sin hardcodear la URL:
curl -s https://alibanca-api-production.up.railway.app/v2/version | jq -r '.payload.links.openapi'
i
Un solo lugar de verdad. Cuando dudes de la forma exacta de un campo, no adivines: mira el contrato OpenAPI →. Como se genera de lo desplegado, gana siempre contra cualquier ejemplo que puedas tener cacheado o cualquier suposición.

Cómo manejamos cambios y compatibilidad

Un API vivo cambia. La pregunta no es si cambia, sino cómo te enteras y qué te obliga a hacer. Nuestra política parte de una distinción que conviene que interiorices desde el día uno: hay cambios que no rompen tu integración y cambios que sí rompen, y los tratamos de forma radicalmente distinta.

Cambios compatibles — no tocan tu código

Estos ocurren dentro de v2 sin cambiar el número de contrato, porque no pueden romper una integración que ya funciona. Por ejemplo: agregar un campo nuevo a una respuesta, agregar un endpoint nuevo, agregar un riel a la lista de rails, o sumar un valor nuevo a un enum manteniendo los existentes. La regla de oro para consumir un API sin sobresaltos aplica aquí: ignora los campos que no conoces en vez de reventar cuando aparecen. Si tu parser tolera propiedades extra, un campo nuevo nuestro simplemente pasa desapercibido para tu código.

Estos avances se reflejan en el número de version (el release) que ves en /v2/version, mientras apiVersion se queda quieto en "v2". Traducción: puedes ver subir version muchas veces y no tener que hacer absolutamente nada.

Cambios que rompen — cambian el número mayor

Un cambio que rompe es cualquiera que invalide una suposición razonable de tu código: renombrar o eliminar un campo, cambiar el significado de un estado, volver obligatorio un parámetro que era opcional, o alterar la forma del sobre de respuesta. Esto no ocurre dentro de v2. Un cambio así viviría bajo un prefijo nuevo (por ejemplo /v3), como un contrato nuevo al lado del viejo, y v2 seguiría corriendo durante su ventana de soporte para darte tiempo de migrar cuando decidas, no cuando nosotros deployeemos.

!
Nunca hardcodees lo que puedes descubrir. El error de compatibilidad más común no es nuestro cambio: es tu suposición rígida. Codificar rails: ["PM","CCE"] a mano, asumir que un enum solo tendrá los valores de hoy, o explotar ante un campo desconocido son bombas de tiempo. Lee rails desde /v2/version, tolera campos extra y trata cualquier valor de estado inesperado con prudencia. Un integrador defensivo casi nunca necesita migrar por sorpresa.

Dónde ver el changelog

El changelog es la bitácora de qué cambió en cada release: qué se agregó, qué se corrigió, qué está en camino. Como el contrato OpenAPI se mantiene en sync con lo desplegado sin drift, tu fuente primaria para saber "qué es nuevo" es comparar el /v2/openapi.json actual contra el que ya conocías: los endpoints y campos añadidos aparecen ahí de forma autoritativa. El número de version que devuelve /v2/version te dice, en cualquier momento, exactamente qué release estás tocando —dato clave cuando reportas una incidencia o cuando quieres confirmar que un despliegue nuevo ya está arriba.

La práctica recomendada es registrar en tus propios logs, junto a cada respuesta importante, el par version + apiVersion con el que la obtuviste. Así, si meses después revisas un pago viejo, sabes con qué contrato y qué build fue procesado, sin depender de tu memoria.

Buenas prácticas de versionado

Estas son las costumbres que separan una integración que envejece bien de una que se rompe al primer despliegue nuestro:

Integra contra apiVersion, no contra version. Tu lógica de negocio depende del contrato (v2), no del build. El release sube solo; el contrato es tu ancla estable.

Descubre, no adivines. Lee environment, rails y los links desde /v2/version al arrancar. Todo lo que descubres en vivo es una cosa menos que se te queda desactualizada en el código.

Tolera lo desconocido. Que tu parser JSON ignore campos que no conoce. Un campo nuevo nuestro nunca debería tumbar tu integración.

Usa el discovery como health-check. Como /v2/version es público y barato, es un excelente chequeo de conectividad en tu monitoreo, separado del endpoint GET /health (también público) que te dice si el servicio está vivo.

Registra la versión en tus logs. Guarda version + apiVersion + traceId junto a cada respuesta relevante. Es tu caja negra para depurar y para soporte.

Errores comunes

Apuntar a la URL base equivocada. El síntoma clásico: firmas todo perfecto pero recibes errores raros, porque estás pegándole a producción creyendo que estás en sandbox (o viceversa). Solución: verifica environment en /v2/version antes de emitir. Sandbox es https://alibanca-api-production.up.railway.app; producción es https://api.alibanca.com.

Poner llave o firma en /v2/version. No hace falta y solo añade puntos de falla: es público. Úsalo justo para descartar problemas de firma, no para meterlos.

Hardcodear la lista de rieles. Si escribes ["PM","CCE"] a mano y mañana habilitamos otro riel, tu integración se lo pierde hasta que toques código. Léelo de rails.

Confundir version con apiVersion. Ver subir version y salir corriendo a "migrar" es trabajo perdido: mientras apiVersion siga en "v2", no hay nada que migrar. El release avanza; el contrato es el que manda sobre tu código.

i
Próximo paso. Con el discovery claro, sigue con Autenticación → para armar tu llave, el envelope canónico y la firma x-signature. Cuando tengas GET /v2/version devolviéndote 200 desde tu entorno, estás listo para firmar tu primer request de verdad.