Cuentas del API Bancario

API 1.0.0

Una herramienta del MCP envuelve esta operación: Herramientas bancarias.

El grupo Accounts cubre la cuenta como recurso: validar una cuenta destino antes de transferir, listar las cuentas accesibles, consultar saldos y pedir estados de cuenta.

POST /api/public/v1/accounts/validate
GET  /api/public/v1/accounts
POST /api/public/v1/accounts/balances
GET  /api/public/v1/accounts/balance
POST /api/public/v1/accounts/statements
GET  /api/public/v1/accounts/statements/{request_id}

Reglas del recurso#

Alcance. El listado devuelve sólo las cuentas que autoriza el token; no se envía tenant_id ni owner_id como parámetro.

Validación previa. Validá la cuenta destino antes de crear un pago: la operación confirma que la cuenta existe y es apta, y devuelve los datos del titular que el servicio expone.

Estados de cuenta asincrónicos. POST /api/public/v1/accounts/statements acepta Idempotency-Key y responde siempre HTTP 202 (ACCEPTED) con request_id y status: PENDING; la generación es asíncrona. Consultá GET /api/public/v1/accounts/statements/{request_id}: responde HTTP 200 con status PENDING, PROCESSING, DONE o ERROR. En DONE incluye download_url, válida por 48 horas. Ver reintentos seguros.

Paginación. GET /api/public/v1/accounts y GET /api/public/v1/accounts/balances usan limit y offset, y devuelven pagination con limit, offset y total.

Operaciones#

Validar cuenta externa para un método de pago

POST /api/public/v1/accounts/validate

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Valida una cuenta de beneficiario (IBAN o teléfono) a través del proveedor SINPE para el método de pago indicado. No valida cuentas internas de la plataforma. Cuando es válida, data.holder.id_type usa las mismas claves del catálogo de identificación que identification.type en POST /payments (ej. cedula, juridica, dimex).

Disponibilidad de campos en SINPE_MOVIL (esperado, estable)

Para payment_method_code = SINPE_MOVIL, la consulta del monedero SINPE Móvil no devuelve el tipo de identificación ni el nombre de la entidad. Una validación exitosa puede entonces devolver:

  • data.holder.id_type = unknown
  • data.financial_institution.entity_name = "" (cadena vacía)

Este comportamiento es esperado y estable, no un error de mapeo ni un error transitorio del proveedor. PIN (la consulta de la cuenta en SINPE) sí completa ambos campos.

No reportés estos valores como defectos ni asumás que holder.id_type o financial_institution.entity_name siempre vienen completos cuando is_valid es true.

Códigos de rechazo SINPE (data.rejection)

Cuando is_valid es false, data.rejection explica por qué (ver el ejemplo rejected en la respuesta 200 más abajo). rejection.code es uno de un conjunto fijo de semánticas normalizadas (ver la tabla de valores más abajo). La mayoría de filas de la tabla NO tienen un `code` propio: solo un subconjunto de valores de reason_code tiene una semántica dedicada; cualquier otro reason_code, incluso uno listado abajo con un message específico, devuelve code = SINPE_REJECTED (ej. reason_code = 21 "fondos insuficientes" igual devuelve SINPE_REJECTED). Este mismo objeto y catálogo los usa también el campo rejection del webhook payment.failed. Un reason_code que no aparece aquí igual produce respuesta: message cae a un texto genérico y code a SINPE_REJECTED.

Cuenta / perfil / límites

CodeMessage
21Cuenta Cliente con fondos insuficientes
22Cuenta Cliente no admite créditos
23Cuenta Cliente cerrada
24Cuenta Cliente inactiva
25Cuenta Cliente no admite débitos
26Cuenta Cliente no es de fondos
27Moneda de la Cuenta Cliente no corresponde
28Cuenta cliente no existe
29Cuenta Cliente no registrada en el SINPE
30Cuenta Cliente no habilitada para el servicio
31Cuenta Cliente bloqueada
32Id cliente destino no coincide con registrado en la entidad
33Nombre del cliente destino no coincide con el registrado en la entidad
34Cuenta Cliente en proceso de cierre
35Cuenta Cliente embargada
36Cuenta Cliente con retención judicial
37Cuenta de expediente simplificado no permite el monto indicado
38Límite transaccional de la Cuenta Cliente excedido
39Cuenta Cliente incorrecta
40IBAN de la cuenta destino inválido
41IBAN de la cuenta origen inválido
42Tipo de cuenta no permite la transacción
43Cuenta Cliente no pertenece a la entidad indicada
44Producto de la cuenta no admite el servicio
45Cuenta Cliente en estado de cancelación
46Cuenta Cliente restringida por política de la entidad
47Cuenta Cliente no permite pagos inmediatos
48Cuenta Cliente no permite SINPE Móvil
49Titular de la cuenta destino fallecido
50Cuenta Cliente consolidada o migrada
51Identificación del cliente origen no coincide
52Identificación del cliente destino inválida
53Cliente destino no autorizado para recibir el pago
54Cliente origen no autorizado para enviar el pago
55Perfil del cliente origen no permite la transacción
56Monto inferior al mínimo permitido
57Monto superior al máximo permitido
58Cantidad de transacciones diarias excedida
59Cantidad de transacciones mensuales excedida
60Límite acumulado diario excedido
61Límite acumulado mensual excedido
62Comisión no pudo ser aplicada
63Tipo de cambio no disponible
64Transacción rechazada por control de lavado de dinero
65Transacción rechazada por listas de control
66Transacción en revisión de cumplimiento
67Documento de respaldo requerido no presente
68Firma o autenticación inválida
69Token o segundo factor inválido
70Sesión de usuario expirada
71Usuario no autorizado para el canal
72Dispositivo no registrado
73Geolocalización no permitida
74Operación no soportada en la moneda indicada
75Operación no soportada para el tipo de cliente
76Problemas de comunicación
77Tiempo de espera agotado en la entidad origen
78Tiempo de espera agotado en el SINPE
79Error interno de la entidad origen
80Error interno de la entidad destino
81Entidad origen no disponible
82Entidad destino no encontrada
83Problemas en la respuesta del destino
84Respuesta de la entidad origen incorrecta
85Mensaje con formato electrónico inválido
86Versión del estándar electrónico no soportada
87Campo obligatorio no informado
88Campo con valor fuera de catálogo
89Checksum o integridad del mensaje inválida
90Referencia SINPE duplicada
91Moneda no corresponde
92Transacción no autorizada por entidad destino
93Transacción no autorizada por cliente destino
94Transacción no autorizada por entidad origen
95Transacción no autorizada por cliente origen
96Reverso no permitido para el estado de la transacción
97Reverso ya aplicado
98Confirmación no permitida para el estado de la transacción
99Liquidación no permitida para el estado de la transacción
100Entidad Destino no disponible para procesar en tiempo real
101Entidad origen no disponible para procesar en tiempo real
102Servicio PIN no habilitado para la entidad destino
103Servicio PIN no habilitado para la entidad origen
104Código de entidad destino inválido
105Código de entidad origen inválido
106Código de país de la entidad destino inválido
107Código de país de la entidad origen inválido
108Número de referencia interna inválido
109Número de referencia SINPE inválido
110Transacción no se encuentra en un estado que permita la consulta

Compensación con entidad destino

CodeMessage
201Tiempo respuesta excedido por la entidad destino
202Respuesta de la entidad destino incorrecta según el estándar electrónico
203Se recibió una excepción de la entidad destino
204Error de comunicación con la entidad destino
205Falló procesamiento en el SINPE
206Transacción no autorizada por cliente destino
207Perfil transaccional del cliente destino no permite recibir el pago
208Operación no autorizada entre las entidades participantes
209Pendientes de Cumplimiento
210Conciliación de la transacción no fue posible

Identificación

CodeMessage
801Identificación inválida
802Identificación del cliente origen no encontrada
803Identificación del cliente destino no encontrada
804Identificación no vigente
805Identificación vencida
806Identificación no corresponde al tipo indicado
807Tipo de identificación inválido
808País de la identificación no soportado
809Identificación de menor de edad no permitida
810Identificación de persona jurídica no permitida para el servicio

Validación de formato / Core Bancario

CodeMessage
1002El Id de cliente destino no cumple con el formato esperado por el SINPE
1003El Id de cliente origen no fue informado
1004El Id de cliente origen no cumple con el formato esperado por el SINPE
1005Monto con formato inválido
1006Moneda con formato inválido
1007Problemas de comunicación con el Core Bancario
1008Core Bancario no disponible
1009El valor para el campo no puede ser nulo o infringir su longitud mínima o máxima
1010El valor para el campo no corresponde al tipo de dato esperado
1011El valor para el campo no corresponde al catálogo permitido
1012Fecha con formato inválido
1013Hora con formato inválido
1014Número de referencia con formato inválido
1015IBAN con formato inválido

Canal / tipo de identificación

CodeMessage
1040Canal no informado
1041Canal inválido
1042Canal no corresponde
1043Canal no habilitado para la entidad
1044Canal no habilitado para el servicio
1045El formato de la identificación es inválido
1046Tipo de identificación no informado
1080Tipo de identificación no corresponde al cliente origen
1081Tipo de identificación no corresponde al cliente destino
1082Tipo de identificación no vigente
1083Tipo de identificación no soportado por el servicio
1084Tipo de identificación inválido
1085Tipo de identificación no soportado por la entidad

SINPE Móvil (monedero)

CodeMessage
15300El número de teléfono origen indicado es inválido
15301El número de teléfono origen no tiene activo el Servicio Monedero
15302El número de teléfono destino indicado es inválido
15303El número de teléfono destino no está registrado en el padrón móvil del BCCR
15304No es posible inactivar el monedero indicado pues no existe
15305El número de teléfono indicado ya se encuentra activo como monedero en el padrón local

Valores de `rejection.code`

ValorSignificado
ACCOUNT_CLOSEDCuenta cerrada
ACCOUNT_NOT_FOUNDCuenta no encontrada
ACCOUNT_BLOCKEDCuenta bloqueada
INVALID_ACCOUNTCuenta inválida
IDENT_MISMATCHLa identificación no coincide
IDENT_TYPE_INVALIDTipo de identificación inválido
INVALID_ID_FORMATFormato de identificación inválido
VALIDATION_ERRORError de validación
CURRENCY_MISMATCHLa moneda no corresponde
NOT_AUTHORIZED_BY_RECIPIENTNo autorizado por el destinatario
PROFILE_NOT_ALLOWEDPerfil no permitido
CHANNEL_NOT_RECOGNIZEDCanal no reconocido
COMMUNICATION_ERRORError de comunicación
RETRY_LATERReintentar más tarde
WALLET_PHONE_ORIGIN_INVALIDTeléfono origen inválido (SINPE Móvil)
WALLET_PHONE_ORIGIN_NOT_ENABLEDTeléfono origen sin servicio de monedero
WALLET_PHONE_DEST_INVALIDTeléfono destino inválido (SINPE Móvil)
WALLET_PHONE_NOT_REGISTERED_BCCRTeléfono no registrado en el padrón móvil del BCCR
WALLET_NOT_FOUNDMonedero no encontrado
WALLET_PHONE_ALREADY_ACTIVEEl teléfono ya tiene un monedero activo
PHONE_NOT_REGISTEREDTeléfono no registrado
SINPE_REJECTEDRechazado por SINPE (valor genérico de respaldo)

Actualmente hay límites de tasa en autenticación y validación de cuentas. Superarlos devuelve HTTP 429 (TOO_MANY_REQUESTS). Reintentá con espera exponencial.

El código SINPE 1001 indica que la cuenta existe y está activa; es un resultado válido, no un motivo de rechazo.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.

Cuerpo del request

CampoTipoObligatorioDescripción
payment_method_codestringsíMétodo de pago usado para enrutar la validación (PIN para IBAN externo, SINPE_MOVIL para monedero telefónico).Valores: PIN, SINPE_MOVIL
accountobjectsí—
account.typestringsí—Valores: IBAN, PHONE
account.valuestringsí—

Ejemplo de request

pin

{
  "payment_method_code": "PIN",
  "account": {
    "type": "IBAN",
    "value": "CR16010400000000000031"
  }
}

sinpe_movil

{
  "payment_method_code": "SINPE_MOVIL",
  "account": {
    "type": "PHONE",
    "value": "88887777"
  }
}

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
is_validbooleanno—
accountobjectno—
account.typestringno—
account.valuestringno—
account.currencystringno—
account.product_namestringno—
holderobjectnoTitular de la cuenta cuando la validación tiene éxito. id_type coincide con PaymentIdentification.type (mismo catálogo que POST /payments). Para SINPE_MOVIL, id_type puede ser unknown porque la consulta del monedero no devuelve el tipo de identificación. Es esperado y estable; no lo tratés como un error.Puede ser null.
holder.namestringno—
holder.id_typestringnoClave del catálogo de identificación (minúsculas), ej. cedula, juridica, dimex. Mismo vocabulario que identification.type al crear un pago. PIN: se obtiene de la consulta de cuenta del proveedor (confirmado por el proveedor). SINPE_MOVIL: la consulta del monedero no devuelve el tipo de identificación, así que este campo puede ser `unknown`. Es un comportamiento esperado y estable por los datos disponibles del proveedor, no un error de mapeo ni transitorio. No asumás que siempre hay un tipo confirmado.Valores: cedula, dimex, gobierno, juridica, institucion_autonoma, didi, pasaporte, unknown
holder.id_numberstringno—
financial_institutionobjectnoEntidad del beneficiario cuando la validación tiene éxito. PIN completa entity_name desde la consulta de cuenta en SINPE. SINPE_MOVIL solo recibe el código de entidad desde la consulta del monedero; no devuelve el nombre de la entidad, así que entity_name puede ser `""`. Es un comportamiento esperado y estable, no un error transitorio. No asumás que entity_name siempre viene completo.Puede ser null.
financial_institution.country_codestringno—
financial_institution.entity_codestringno—
financial_institution.entity_namestringnoNombre legible de la entidad. PIN: se completa desde la consulta de cuenta del proveedor. SINPE_MOVIL: puede ser "" porque la consulta del monedero no expone el nombre. Limitación esperada, no un error.
rejectionobjectnoPresente cuando is_valid es false y el proveedor rechazó la cuenta. null cuando is_valid es true.Puede ser null.
rejection.codestringsíSemántica normalizada de la plataforma derivada de reason_code. Solo un subconjunto de valores de reason_code (ver el catálogo en la descripción de POST /accounts/validate y del endpoint de contrato del webhook payment.failed) tiene entrada propia aquí; para cualquier otro reason_code numérico, code es SINPE_REJECTED aunque message sea específico (ej. reason_code = 21 "fondos insuficientes" igual devuelve code = SINPE_REJECTED, no tiene semántica propia). PHONE_NOT_REGISTERED es el valor de respaldo cuando reason_code no es numérico (flujo del monedero SINPE_MOVIL).Valores: ACCOUNT_CLOSED, ACCOUNT_NOT_FOUND, ACCOUNT_BLOCKED, INVALID_ACCOUNT, IDENT_MISMATCH, IDENT_TYPE_INVALID, INVALID_ID_FORMAT, VALIDATION_ERROR, CURRENCY_MISMATCH, NOT_AUTHORIZED_BY_RECIPIENT, PROFILE_NOT_ALLOWED, CHANNEL_NOT_RECOGNIZED, COMMUNICATION_ERROR, RETRY_LATER, WALLET_PHONE_ORIGIN_INVALID, WALLET_PHONE_ORIGIN_NOT_ENABLED, WALLET_PHONE_DEST_INVALID, WALLET_PHONE_NOT_REGISTERED_BCCR, WALLET_NOT_FOUND, WALLET_PHONE_ALREADY_ACTIVE, PHONE_NOT_REGISTERED, SINPE_REJECTED
rejection.reason_codestringsíMotivo/código crudo devuelto por SINPE. El catálogo completo está en la descripción de POST /accounts/validate (lo comparte este objeto dondequiera que aparezca, incluido el webhook payment.failed). Un código no listado igual produce respuesta: message cae a un texto genérico y code a SINPE_REJECTED.
rejection.messagestringsíTexto descriptivo del Motivo; prefiere el Detalle del proveedor cuando existe.
providerobjectno—
provider.operationstringno—
provider.correlation_idstringno—Puede ser null.
provider.occurred_atstring (date-time)no—Puede ser null.

Ejemplo de respuesta — valid

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "is_valid": true,
    "account": {
      "type": "IBAN",
      "value": "CR16010400000000000031",
      "currency": "CRC",
      "product_name": "Cuenta corriente"
    },
    "holder": {
      "name": "Juan Perez",
      "id_type": "cedula"
    },
    "financial_institution": {
      "entity_code": "104",
      "entity_name": "Banco Ejemplo"
    },
    "provider": {
      "reason_code": "0",
      "message": "Cuenta válida",
      "code": null
    },
    "rejection": null
  }
}

Ejemplo de respuesta — rejected

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "is_valid": false,
    "account": {
      "type": "IBAN",
      "value": "CR16010400000000000099",
      "currency": "CRC",
      "product_name": ""
    },
    "holder": null,
    "financial_institution": {
      "entity_code": "104",
      "entity_name": "Banco Ejemplo"
    },
    "provider": {
      "reason_code": "28",
      "message": "Cuenta cliente no existe",
      "code": "ACCOUNT_NOT_FOUND"
    },
    "rejection": {
      "code": "ACCOUNT_NOT_FOUND",
      "reason_code": "28",
      "message": "Cuenta cliente no existe"
    }
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
400INVALID_ACCOUNT_TYPEUnsupported or invalid account type.
400INVALID_ACCOUNT_FORMATInvalid account format.
400INVALID_PAYMENT_METHODInvalid or unsupported payment method.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
422UNPROCESSABLE_ENTITYThe request is well-formed but cannot be processed due to business rules.
429TOO_MANY_REQUESTSToo many requests. Please retry after a short delay.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502PROVIDER_ERRORUnable to complete the request with the payment provider. Please try again later.

Listar saldos de las cuentas accesibles

GET /api/public/v1/accounts/balances

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Devuelve los saldos paginados de las cuentas (account, amounts, as_of). Este endpoint consulta el saldo actual en tiempo real y puede responder más lento que GET /accounts. Para los atributos de la cuenta sin montos, usá GET /accounts.

Los filtros opcionales usan el estándar público de identificación de cuentas: type + value (esquema de identificación + valor). type no es la clasificación interna de la cuenta.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
limitqueryintegerno—
offsetqueryintegerno—
typequerystringnoFiltro opcional por esquema de identificación de la cuenta (ej. IBAN). No es la clasificación interna de la cuenta.
valuequerystringnoFiltro opcional por valor del identificador de la cuenta (los listados admiten coincidencia parcial).

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
itemsarray<object>no—
items[].accountobjectsí—
items[].account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
items[].account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
items[].account.currencystringnoMoneda opcional de la cuenta en las respuestas.
items[].amountsobjectsíSaldos del ledger como textos decimales con 2 decimales (misma escala que los montos públicos de pago). Preferí texto sobre número JSON para montos financieros.
items[].amounts.availablestringno—
items[].amounts.postedstringno—
items[].amounts.inbound_in_transitstringno—
items[].amounts.outbound_in_transitstringno—
items[].as_ofstring (date-time)síMarca de tiempo del ledger cuando se conoce (RFC 3339 UTC, precisión de segundos, Z); null cuando no está disponible.Puede ser null.
paginationobjectno—
pagination.limitintegerno—
pagination.offsetintegerno—
pagination.totalintegerno—

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "items": [
      {
        "account": {
          "type": "IBAN",
          "value": "CR26036900101010588061",
          "currency": "CRC"
        },
        "amounts": {
          "available": "991900.00",
          "posted": "991900.00",
          "inbound_in_transit": "0.00",
          "outbound_in_transit": "0.00"
        },
        "as_of": "2026-01-15T12:00:00Z"
      }
    ],
    "pagination": {
      "limit": 20,
      "offset": 0,
      "total": 1
    }
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
404NOT_FOUNDThe requested resource was not found.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502—Error de dependencia
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Listar cuentas accesibles sin saldos

GET /api/public/v1/accounts

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Devuelve las cuentas accesibles paginadas sin consultar saldos actuales. Cada ítem trae solo atributos de la cuenta (account.type, account.value, account.currency). No incluye amounts ni as_of; usá GET /accounts/balances o POST /accounts/balance.

Los filtros opcionales usan el estándar público de identificación de cuentas: type + value (esquema de identificación + valor). type no es la clasificación interna de la cuenta.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
limitqueryintegerno—
offsetqueryintegerno—
typequerystringnoFiltro opcional por esquema de identificación de la cuenta (ej. IBAN). No es la clasificación interna de la cuenta.
valuequerystringnoFiltro opcional por valor del identificador de la cuenta (los listados admiten coincidencia parcial).

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
itemsarray<object>no—
items[].accountobjectsí—
items[].account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
items[].account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
items[].account.currencystringnoMoneda opcional de la cuenta en las respuestas.
paginationobjectno—
pagination.limitintegerno—
pagination.offsetintegerno—
pagination.totalintegerno—

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "items": [
      {
        "account": {
          "type": "IBAN",
          "value": "CR26036900101010588061",
          "currency": "CRC"
        }
      }
    ],
    "pagination": {
      "limit": 20,
      "offset": 0,
      "total": 1
    }
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
404NOT_FOUNDThe requested resource was not found.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502—Error de dependencia
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Obtener saldo de una cuenta

POST /api/public/v1/accounts/balance

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Devuelve la foto actual de una cuenta con amounts y as_of. Para los atributos de la cuenta sin saldos, usá GET /accounts.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.

Cuerpo del request

CampoTipoObligatorioDescripción
accountobjectsí—
account.typestringsíEsquema de identificación de la cuenta. Aquí solo se admite IBAN. No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN
account.valuestringsíIBAN (se permiten espacios; se normaliza en el servidor)

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
accountobjectsí—
account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
account.currencystringnoMoneda opcional de la cuenta en las respuestas.
amountsobjectsíSaldos del ledger como textos decimales con 2 decimales (misma escala que los montos públicos de pago). Preferí texto sobre número JSON para montos financieros.
amounts.availablestringno—
amounts.postedstringno—
amounts.inbound_in_transitstringno—
amounts.outbound_in_transitstringno—
as_ofstring (date-time)síMarca de tiempo del ledger cuando se conoce (RFC 3339 UTC, precisión de segundos, Z); null cuando no está disponible.Puede ser null.

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "account": {
      "type": "IBAN",
      "value": "CR26036900101010588061",
      "currency": "CRC"
    },
    "amounts": {
      "available": "991900.00",
      "posted": "991900.00",
      "inbound_in_transit": "0.00",
      "outbound_in_transit": "0.00"
    },
    "as_of": "2026-01-15T12:00:00Z"
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
404ACCOUNT_NOT_FOUNDAccount not found.
422ACCOUNT_NOT_CONFIGUREDThis account is not mapped in the system. Please contact support to configure it correctly.
422UNPROCESSABLE_ENTITYThe request is well-formed but cannot be processed due to business rules.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502PROVIDER_ERRORUnable to complete the request with the payment provider. Please try again later.
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Solicitar generación de estado de cuenta

POST /api/public/v1/accounts/statements

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>. Acepta Idempotency-Key.

Crea una solicitud asíncrona de estado de cuenta para un rango de fechas (máximo 60 días). Identificá la cuenta con account.type + account.value (esquema de identificación + valor, ej. IBAN). Sigue el estándar público de identificación de cuentas. account.type no es la clasificación interna de la cuenta. Devuelve {request_id, status: PENDING} de inmediato. Consultá GET /accounts/statements/{request_id} para el estado; cuando es DONE, la respuesta incluye una download_url firmada.

Siempre devuelve HTTP 202 (ACCEPTED) con request_id y status PENDING. La generación es asíncrona. Consultá GET /api/public/v1/accounts/statements/{request_id}: HTTP 200 con PENDING, PROCESSING, DONE o ERROR. DONE incluye download_url, válida por 48 horas.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
Idempotency-Keyheaderstringno—

Cuerpo del request

CampoTipoObligatorioDescripción
accountobjectsí—
account.typestringsíEsquema de identificación de la cuenta. Aquí solo se admite IBAN. No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN
account.valuestringsíIBAN (se permiten espacios; se normaliza en el servidor)
date_fromstring (date-time)síMarca de tiempo RFC 3339 aceptada en solicitudes. Se permite UTC Z u offset numérico. Las fracciones de segundo opcionales se aceptan y se truncan a segundos.
date_tostring (date-time)síRFC 3339 (máximo 60 días después de date_from)
notify_emailbooleanno—

Respuesta 202

Solicitud de estado de cuenta aceptada para generación asíncrona.

response_code: ACCEPTED

CampoTipoObligatorioDescripción
request_idstring (uuid)sí—
statusstringsí—Valores: PENDING

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 202,
  "response_code": "ACCEPTED",
  "message": "Statement request accepted.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "request_id": "5f3b2c1d-9e8a-4b7c-8d6e-5f4a3b2c1d0e",
    "status": "PENDING"
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
404NOT_FOUNDThe requested resource was not found.
409IDEMPOTENCY_CONFLICTIdempotency conflict: the same Idempotency-Key was reused with a different request body, or a previous request is still in progress.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502—Error de dependencia
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Consultar estado de la solicitud de estado de cuenta

GET /api/public/v1/accounts/statements/{request_id}

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Devuelve el estado de la solicitud. Cuando es DONE, incluye una download_url firmada y temporal (48 h desde su generación) y expires_at. Cuando es ERROR, incluye un message genérico sin detalles internos. Un request_id desconocido o no autorizado devuelve 404.

Devuelve HTTP 200 con status PENDING, PROCESSING, DONE o ERROR. DONE incluye download_url, válida por 48 horas.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
request_idpathstring (uuid)sí—

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
request_idstring (uuid)sí—
statusstringsí—Valores: PENDING, PROCESSING, DONE, ERROR
download_urlstring (uri)noURL de descarga firmada, presente con status DONE; válida por 48 horas desde su generación.
expires_atstring (date-time)noVencimiento de download_url (48 h desde su generación)
messagestringnoMensaje genérico de error cuando el estado es ERROR

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "request_id": "5f3b2c1d-9e8a-4b7c-8d6e-5f4a3b2c1d0e",
    "status": "DONE",
    "download_url": "https://storage.example.com/statements/5f3b2c1d.pdf?signature=example",
    "expires_at": "2026-01-17T12:00:00Z",
    "message": null
  }
}

Respuestas de error

HTTPresponse_codeDescripción
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
404NOT_FOUNDThe requested resource was not found.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Validación y códigos SINPE#

El código 1001 indica que la cuenta existe y está activa: no es un rechazo. 208 significa «Operación no autorizada entre las entidades participantes» y 209, «Pendientes de Cumplimiento».

La validación de cuentas tiene límites de tasa: al superarlos responde 429 (TOO_MANY_REQUESTS). Reintentá con espera exponencial.

Última verificación: 2026-10-22

Ver como Markdown crudo