Desarrolladores

Documentación API

Integra kakebo.io con tus propias herramientas usando nuestra API REST. Todas las peticiones requieren autenticación mediante API Key.

Autenticación

La API acepta dos métodos de autenticación: JWT (recomendado para apps móviles) y API Key.

1 JWT (recomendado para apps móviles)

Obtené un token enviando tus credenciales al endpoint de login. El token expira en 24 horas.

Petición
POST https://kakebo.io/api/v1/auth/login
Content-Type: application/json

{
  "username": "tu_usuario",
  "password": "tu_contraseña"
}
Respuesta 200
{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "tokenType": "Bearer",
  "username": "tu_usuario",
  "fullName": "Tu Nombre",
  "role": "ROLE_USER",
  "expiresIn": 86400,
  "language": "ES",
  "numberFormat": "COMMA_DECIMAL",
  "country": "CR",
  "baseCurrency": "CRC",
  "preferredTheme": "DARK",
  "timezone": "America/Costa_Rica",
  "accountPlan": "FREE",
  "planExpiresAt": null
}
Uso en peticiones
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

2 API Key (acceso externo estático)

Encontrá tu API Key en Perfil → Seguridad → API Key. Si no tenés una, generála desde esa pantalla.

HTTP
X-API-Key: YOUR_API_KEY
Nunca compartas tu API Key ni tu token JWT en código público. Trátalos como contraseñas.

URL Base

URL
https://kakebo.io/api/v1

Todas las rutas documentadas son relativas a esta URL base.

Códigos de Error

200Petición exitosa.
400Datos inválidos o faltantes en el cuerpo de la petición.
401API Key ausente o inválida.
403Sin permisos para realizar esta acción.
404Recurso no encontrado.
429Demasiadas peticiones. Límite de tasa excedido.

Registro de usuario

Crea una nueva cuenta de usuario con plan FREE. El usuario recibirá un correo para verificar su email antes de poder iniciar sesión.

Crea una nueva cuenta de usuario con plan FREE. El usuario recibirá un correo para verificar su email antes de poder iniciar sesión.

Parámetros

Campo Tipo Requerido Descripción
username string Nombre de usuario único. Mín. 3 caracteres, máx. 50.
password string Contraseña en texto plano. Mín. 8 caracteres, máx. 100.
fullName string Nombre completo del usuario. Máx. 100 caracteres.
email string Correo electrónico válido. Se usará para la verificación de cuenta.
timezone string No Zona horaria IANA del cliente (ej: America/Costa_Rica). Defecto: America/Costa_Rica.

Petición

HTTP
POST /api/v1/auth/register
Content-Type: application/json

{
  "username": "maria_garcia",
  "password": "MiClaveSegura123",
  "fullName": "María García",
  "email": "maria@correo.com",
  "timezone": "America/Costa_Rica"
}

Respuesta 201

JSON
{
  "message": "Cuenta creada correctamente. Revisa tu correo para verificar tu cuenta.",
  "username": "maria_garcia",
  "email": "maria@correo.com",
  "fullName": "María García",
  "accountPlan": "FREE"
}
Luego del registro, el usuario debe verificar su correo antes de autenticarse con /login.

Errores

400 Datos inválidos o faltantes en el cuerpo de la petición.
409 El nombre de usuario o correo ya está registrado.

Dashboard

Obtén todos los widgets del dashboard en una sola llamada.

Retorna en una sola respuesta: resumen mensual, reporte semanal de los últimos 7 días, avance de presupuestos, saldos de cuentas y patrimonio neto.

Parámetros

Parámetro Tipo Requerido Descripción
yearinteger Opcional Año a consultar. Por defecto: año actual.
monthinteger Opcional Mes a consultar (1-12). Por defecto: mes actual.
Petición
GET /api/v1/dashboard
GET /api/v1/dashboard?year=2026&month=5
Authorization: Bearer <token>
Respuesta 200
{
  "period": {
    "year": 2026,
    "month": 5,
    "monthName": "Mayo"
  },
  "summary": {
    "totalIncomeCRC": 850000,
    "totalExpensesCRC": 620000,
    "balanceCRC": 230000,
    "exchangeRate": 520.50,
    "transactionCount": 34,
    "previousMonthTotal": 580000,
    "byMacroCategory": {
      "Alimentación": 120000,
      "Transporte": 80000,
      "Entretenimiento": 45000
    },
    "byCategory": {
      "Supermercado": 85000,
      "Restaurantes": 35000,
      "Gasolina": 50000,
      "Bus": 30000,
      "Netflix": 25000,
      "Cine": 20000
    },
    "dailyExpenses": {
      "1": 15000,
      "5": 32000,
      "12": 18000
    }
  },
  "weeklyReport": {
    "labels": ["Vie", "Sáb", "Dom", "Lun", "Mar", "Mié", "Jue"],
    "income": [0, 0, 0, 50000, 0, 0, 0],
    "expenses": [12000, 0, 8000, 5000, 0, 22000, 0],
    "totalIncome": 50000,
    "totalExpenses": 47000,
    "balance": 3000
  },
  "budgets": [
    {
      "categoryId": "abc123",
      "categoryName": "Supermercado",
      "macroCategory": "Alimentación",
      "amount": 200000,
      "spent": 145000,
      "remaining": 55000,
      "percentage": 72,
      "status": "OK"
    }
  ],
  "accounts": [
    {
      "id": "def456",
      "name": "BAC Colones",
      "type": "BANK_ACCOUNT",
      "currency": "CRC",
      "currentBalance": 400000,
      "creditUsedPct": 0,
      "active": true
    }
  ],
  "netWorth": {
    "totalAssetsCRC": 1200000,
    "totalLiabilitiesCRC": 350000,
    "netWorthCRC": 850000,
    "exchangeRate": 520.50
  }
}

Errores

401API Key ausente o inválida.
429Demasiadas peticiones. Límite de tasa excedido.

Transacciones

Crea, edita y elimina transacciones. Soporta EXPENSE, INCOME y TRANSFER. La cuenta se identifica por su ID interno y la categoría por categoryId o nombre.

Retorna las transacciones del usuario en el rango de fechas indicado. Si no se especifican parámetros, devuelve las del mes en curso.

Parámetros de consulta
Campo Tipo Requerido Descripción
from string Opcional Fecha de inicio en formato yyyy-MM-dd. Por defecto: primer día del mes actual.
to string Opcional Fecha de fin en formato yyyy-MM-dd. Por defecto: último día del mes actual.
Ejemplo de petición
GET /api/v1/transactions
GET /api/v1/transactions?from=2025-01-01&to=2025-01-31
X-API-Key: tu_api_key
Ejemplo de respuesta
[
  {
    "id": "abc123",
    "type": "EXPENSE",
    "date": "2025-01-15",
    "amount": 12500.00,
    "currency": "CRC",
    "amountCRC": 12500.00,
    "exchangeRate": null,
    "accountId": "acc1",
    "accountName": "Cuenta corriente",
    "destinationAccountId": null,
    "destinationAccountName": null,
    "destinationAmount": null,
    "categoryId": "cat1",
    "categoryName": "Alimentación",
    "notes": "Almuerzo",
    "tags": ["trabajo"],
    "recurring": false,
    "ignoredFromBudget": false,
    "createdAt": "2025-01-15T12:30:00"
  }
]

Array JSON con uno o más objetos de transacción.

Campo Tipo Requerido Descripción
type string EXPENSE (gasto) o INCOME (ingreso)
date string Fecha en formato yyyy-MM-dd
amount number Monto mayor a cero
accountId string ID interno de la cuenta origen (visible en GET /api/v1/accounts).
categoryId string No ID de la categoría (preferido). Alternativa: usar categoryName.
categoryName string No Nombre de la categoría (búsqueda sin distinción de mayúsculas)
destinationAccountId string TRANSFER ID de la cuenta destino. Obligatorio para TRANSFER.
currency string No CRC o USD. Si se omite, se usa la moneda de la cuenta.
notes string No Notas adicionales de la transacción
exchangeRate number No Tipo de cambio a aplicar. Si se omite, se usa el del día.
tags string[] No Lista de etiquetas (strings). Ej: ["hogar", "mensual"]
recurring boolean No Marcar como recurrente. Defecto: false
ignoredFromBudget boolean No Excluir del cálculo de presupuestos. Defecto: false
Los adjuntos (imágenes, PDF) no están disponibles vía API JSON. Usa la interfaz web para adjuntar archivos.

Ejemplo de petición

JSON
[
  {
    "type": "EXPENSE",
    "date": "2025-05-15",
    "amount": 12500.00,
    "currency": "CRC",
    "accountId": "664abc...",
    "categoryId": "663def...",
    "notes": "Compras del mes",
    "tags": ["hogar", "mensual"]
  },
  {
    "type": "TRANSFER",
    "date": "2025-05-15",
    "amount": 50000.00,
    "currency": "CRC",
    "accountId": "664abc...",
    "destinationAccountId": "664xyz..."
  }
]

Respuesta 200

JSON
{
  "created": 1,
  "failed": 0,
  "results": [
    {
      "index": 0,
      "status": "ok",
      "id": "6642f3a1c3b4e200..."
    }
  ]
}

Reemplaza todos los campos de la transacción indicada. La cuenta se identifica por accountId y la categoría por categoryId o nombre.

Ejemplo de petición

HTTP
PUT /api/v1/transactions/6642f3a1c3b4e200...
X-API-Key: tu_api_key
Content-Type: application/json

{
  "type": "EXPENSE",
  "date": "2025-05-20",
  "amount": 15000.00,
  "currency": "CRC",
  "accountId": "664abc...",
  "categoryId": "663def...",
  "notes": "Actualizado"
}

Respuesta 200

JSON
{
  "id": "6642f3a1c3b4e200...",
  "type": "EXPENSE",
  "date": "2025-05-20",
  "amount": 15000.00,
  "currency": "CRC",
  "amountCRC": 15000.00,
  "accountId": "acc1",
  "categoryName": "Alimentación",
  "notes": "Actualizado"
}
Errores
404Transacción no encontrada o no pertenece al usuario autenticado.
400Datos inválidos o faltantes en el cuerpo de la petición.

Elimina permanentemente la transacción indicada. Solo puede eliminarse si pertenece al usuario autenticado.

HTTP
DELETE /api/v1/transactions/6642f3a1c3b4e200...
X-API-Key: tu_api_key

→ 204 No Content
Errores
404Transacción no encontrada o no pertenece al usuario autenticado.

Cuentas

Gestiona las cuentas financieras del usuario.

JSON
[
  {
    "id": "664abc...",
    "name": "BAC Visa Oro",
    "type": "CREDIT_CARD",
    "primaryCurrency": "CRC",
    "initialBalance": 0,
    "currentBalance": -125000.00,
    "color": "#7367f0",
    "icon": "fa-solid fa-credit-card",
    "ibanId": "CR21-0152-0001-0261-3392-9",
    "creditLimit": 500000.00,
    "goalAmount": null,
    "annualInterestRate": 36.5,
    "active": true
  }
]

Retorna 404 si la cuenta no existe o no pertenece al usuario autenticado.

CampoTipoRequeridoDescripción
namestringNombre de la cuenta
typestringCASH, BANK_ACCOUNT, CREDIT_CARD, DEBIT_CARD, LOAN, INVESTMENT, SAVINGS, RETIREMENT, OTHER
primaryCurrencystringMoneda principal: CRC o USD
initialBalancenumberNoSaldo inicial. Defecto: 0
colorstringNoColor hexadecimal para la UI
iconstringNoClase CSS FontAwesome
ibanIdstringNoIBAN u otro identificador bancario
creditLimitnumberNoLímite de crédito — solo CREDIT_CARD
goalAmountnumberNoMeta de ahorro o inversión — solo SAVINGS / INVESTMENT
annualInterestRatenumberNoTasa de interés anual en % — solo LOAN / CREDIT_CARD
JSON
{
  "name": "BAC Ahorros",
  "type": "SAVINGS",
  "primaryCurrency": "CRC",
  "initialBalance": 150000.00,
  "color": "#28a745",
  "icon": "fa-solid fa-piggy-bank",
  "goalAmount": 1000000.00
}

Acepta el mismo cuerpo que POST. Solo se pueden editar cuentas propias.

La cuenta se marca como inactiva y deja de aparecer en listas. Retorna 204 No Content.

Presupuestos

Administra los límites de gasto mensual por categoría.

JSON
[
  {
    "id": "664abc...",
    "categoryId": "663def...",
    "categoryName": "Supermercado",
    "macroCategory": "Alimentación",
    "amount": 200000.00
  }
]

Retorna 404 si el presupuesto no existe o no pertenece al usuario autenticado.

CampoTipoRequeridoDescripción
idstringNoID del presupuesto existente para actualizar. Omitir para crear.
categoryIdstringID de la categoría a presupuestar
amountnumberMonto máximo mensual en la moneda base del usuario
JSON
{
  "categoryId": "663def...",
  "amount": 200000.00
}

Elimina el presupuesto permanentemente. Retorna 204 No Content.

Recordatorios

Gestiona recordatorios de pago mensual.

JSON
[
  {
    "id": "664abc...",
    "name": "BAC Visa",
    "type": "CREDIT_CARD",
    "dayOfMonth": 15,
    "amount": 125000.00,
    "currency": "CRC",
    "notes": null,
    "active": true,
    "dismissed": false,
    "nextPaymentDate": "2025-06-15"
  }
]

Retorna 404 si el recordatorio no existe o no pertenece al usuario autenticado.

CampoTipoRequeridoDescripción
namestringNombre descriptivo del recordatorio
typestringCREDIT_CARD o BILL
dayOfMonthintegerDía del mes del vencimiento (1-31)
amountnumberNoMonto esperado del pago
currencystringNoCRC o USD
notesstringNoNotas adicionales
Los adjuntos no están disponibles vía API. Úsalos desde la interfaz web.
JSON
{
  "name": "BAC Visa",
  "type": "CREDIT_CARD",
  "dayOfMonth": 15,
  "amount": 125000.00,
  "currency": "CRC"
}

Acepta el mismo cuerpo que POST. Retorna 204 No Content si fue exitoso.

Desactiva el recordatorio (soft delete). Retorna 204 No Content.

Marca el recordatorio como pagado en el ciclo actual. La alerta reaparece automáticamente el mes siguiente. Retorna 204 No Content.

Categorías

Gestiona las categorías personales del usuario autenticado y consulta las categorías globales.

Retorna las categorías globales y las personales del usuario autenticado.

Respuesta 200

JSON
[
  {
    "id": "6642f3a1c3b4e2001f8a9c1d",
    "name": "Supermercado",
    "macroCategory": "Alimentación",
    "icon": "fa-solid fa-cart-shopping",
    "color": "#28a745",
    "global": true,
    "active": true
  }
]

Retorna 404 si la categoría no existe o pertenece a otro usuario.

Campo Tipo Requerido Descripción
name string Nombre de la categoría
macroCategory string Macrocategoría o grupo al que pertenece
icon string No Clase CSS FontAwesome. Defecto: fa-solid fa-tag
color string No Color hexadecimal. Defecto: #c0410a

Ejemplo de petición

JSON
[
  {
    "name": "Netflix",
    "macroCategory": "Entretenimiento",
    "icon": "fa-brands fa-netflix",
    "color": "#e50914"
  }
]

Respuesta 200

JSON
{
  "created": 1,
  "failed": 0,
  "results": [
    {
      "index": 0,
      "status": "ok",
      "id": "6642f3a1c3b4e200..."
    }
  ]
}

Acepta el mismo cuerpo que POST. Solo se pueden editar categorías propias (no globales). Retorna 400 si la validación falla o la categoría no te pertenece.

La categoría no se elimina físicamente; se marca como inactiva y deja de aparecer en las listas. Retorna 204 No Content si fue exitoso.

Perfil

Consulta y actualiza los datos del usuario autenticado.

Retorna todos los datos del perfil del usuario autenticado.

Petición
GET /api/v1/profile
Authorization: Bearer <token>
Respuesta 200
{
  "id": "abc123",
  "username": "octavio",
  "fullName": "Octavio Soto",
  "firstName": "Octavio",
  "lastName": "Soto",
  "email": "octavio@ejemplo.com",
  "phone": "88001234",
  "phoneCountryCode": "+506",
  "country": "CR",
  "state": "San José",
  "address": "Av. Central",
  "zipCode": "10101",
  "organization": "Acme S.A.",
  "birthDate": "1990-05-15",
  "preferredLanguage": "ES",
  "preferredTheme": "DARK",
  "preferredNumberFormat": "COMMA_DECIMAL",
  "timezone": "America/Costa_Rica",
  "baseCurrency": "CRC",
  "accountPlan": "FREE",
  "planExpiresAt": null,
  "role": "ROLE_USER",
  "profilePhoto": "data:image/jpeg;base64,/9j/4AAQSkZJRgAB..."
}

Actualiza los campos editables del perfil. Los campos username, role y plan son de solo lectura.

Petición
PUT /api/v1/profile
Authorization: Bearer <token>
Content-Type: application/json

{
  "fullName": "Octavio Soto",
  "firstName": "Octavio",
  "lastName": "Soto",
  "email": "octavio@ejemplo.com",
  "phone": "88001234",
  "phoneCountryCode": "+506",
  "country": "CR",
  "state": "San José",
  "address": "Av. Central",
  "zipCode": "10101",
  "organization": "Acme S.A.",
  "birthDate": "1990-05-15",
  "preferredLanguage": "ES",
  "preferredTheme": "DARK",
  "preferredNumberFormat": "COMMA_DECIMAL",
  "timezone": "America/Costa_Rica",
  "baseCurrency": "CRC",
  "profilePhoto": "data:image/jpeg;base64,/9j/4AAQSkZJRgAB..."
  // null = no modificar foto | "" = eliminar foto | data URI = nueva foto
}
Respuesta 200
{ /* perfil actualizado, misma estructura que GET */ }

Cambia la contraseña verificando la actual. La nueva debe tener al menos 8 caracteres, una letra, un número y un carácter especial.

Petición
PUT /api/v1/profile/password
Authorization: Bearer <token>
Content-Type: application/json

{
  "currentPassword": "miContraseñaActual",
  "newPassword": "miNuevaContraseña123"
}
Respuesta 200
{ "message": "Contraseña actualizada correctamente" }
400Contraseña actual incorrecta o nueva contraseña no cumple los requisitos (letras, números, carácter especial, mínimo 8 caracteres)
401API Key ausente o inválida.

Layout del Dashboard

Consulta y personaliza el orden y visibilidad de los widgets del dashboard.

Retorna el layout personalizado del usuario. Si no tiene configuración guardada, retorna el layout por defecto con todos los widgets activos.

Petición
GET /api/v1/dashboard/layout
Authorization: Bearer <token>
Respuesta 200
{
  "widgets": [
    { "type": "INCOME_KPI",       "enabled": true,  "colClass": "col-sm-6 col-xl-3", "icon": "fa-solid fa-arrow-trend-down" },
    { "type": "EXPENSES_KPI",     "enabled": true,  "colClass": "col-sm-6 col-xl-3", "icon": "fa-solid fa-arrow-trend-up" },
    { "type": "BALANCE_KPI",      "enabled": true,  "colClass": "col-sm-6 col-xl-3", "icon": "fa-solid fa-scale-balanced" },
    { "type": "VS_PREV_MONTH",    "enabled": true,  "colClass": "col-sm-6 col-xl-3", "icon": "fa-solid fa-calendar-days" },
    { "type": "CATEGORY_DONUT",   "enabled": true,  "colClass": "col-md-5 col-xl-4", "icon": "fa-solid fa-chart-pie" },
    { "type": "BUDGET_PROGRESS",  "enabled": false, "colClass": "col-12",            "icon": "fa-solid fa-bullseye" },
    { "type": "WEEKLY_REPORT",    "enabled": true,  "colClass": "col-12 col-xl-8",   "icon": "fa-solid fa-chart-bar" }
  ]
}

Tipos disponibles: INCOME_KPI, EXPENSES_KPI, BALANCE_KPI, VS_PREV_MONTH, CATEGORY_DONUT, TOP_CATEGORIES, BY_ACCOUNT_BARS, DAILY_HISTOGRAM, ACCOUNT_BALANCES, BUDGET_PROGRESS, USD_EXPENSES, BY_MEMBER, NET_WORTH, EXCHANGE_RATE, WEEKLY_REPORT, INVESTMENT_PROGRESS, LOAN_PROGRESS

Guarda el orden y visibilidad de los widgets. El orden de la lista determina la posición en pantalla. Los tipos desconocidos se ignoran.

Petición
PUT /api/v1/dashboard/layout
Authorization: Bearer <token>
Content-Type: application/json

{
  "widgets": [
    { "type": "INCOME_KPI",      "enabled": true  },
    { "type": "EXPENSES_KPI",    "enabled": true  },
    { "type": "BALANCE_KPI",     "enabled": true  },
    { "type": "VS_PREV_MONTH",   "enabled": false },
    { "type": "WEEKLY_REPORT",   "enabled": true  },
    { "type": "BUDGET_PROGRESS", "enabled": true  }
  ]
}
Respuesta 200
{ /* layout guardado, misma estructura que GET */ }
400Lista vacía o sin tipos de widget válidos
401API Key ausente o inválida.

Vouchers

Administra los comprobantes bancarios recibidos por email y pendientes de revisión.

Registra un comprobante manualmente sin pasar por el flujo de email/S3. El voucher queda pendiente de revisión para ser confirmado o descartado. Retorna el voucher creado con código 201.

Campo Tipo Requerido Descripción
amount number Monto definitivo en la moneda indicada. Debe ser mayor a cero (obligatorio)
currency string Moneda de la transacción: CRC o USD (obligatorio)
date string No Fecha definitiva del gasto en formato yyyy-MM-dd (obligatorio)
merchant string No Nombre del comercio o descripción del pago (opcional)
notes string No Notas adicionales del usuario (opcional)

Ejemplo de petición

JSON
POST /api/v1/vouchers
X-API-Key: tu_api_key

{
  "date": "2025-05-20",
  "amount": 12500.00,
  "currency": "CRC",
  "merchant": "Super Mas",
  "notes": "Compras de la semana"
}

Respuesta 201

JSON
{
  "id": "6642f3a1c3b4e200...",
  "date": "2025-05-20",
  "amount": 12500.00,
  "currency": "CRC",
  "merchant": "Super Mas",
  "notes": "Compras de la semana",
  "sourceEmail": null,
  "createdAt": "2025-05-20T14:30:00"
}

Retorna los vouchers bancarios detectados por la IA que aún no han sido confirmados ni descartados. Ordenados de más reciente a más antiguo.

Ejemplo de petición

HTTP
GET /api/v1/vouchers
X-API-Key: tu_api_key

Respuesta 200

JSON
[
  {
    "id": "6642f3a1c3b4e200...",
    "date": "2025-05-20",
    "amount": 12500.00,
    "currency": "CRC",
    "merchant": "Super Mas",
    "notes": "Compra en Super Mas por ₡12500",
    "sourceEmail": "usuario@gmail.com",
    "createdAt": "2025-05-20T14:30:00"
  }
]

Convierte el voucher en una transacción registrada con los datos revisados por el usuario. El voucher se elimina de la lista pendiente. Retorna la transacción creada con código 200.

Parámetros de consulta
Campo Tipo Requerido Descripción
accountId string ID de la cuenta origen del gasto (obligatorio)
date string Fecha definitiva del gasto en formato yyyy-MM-dd (obligatorio)
amount number Monto definitivo en la moneda indicada. Debe ser mayor a cero (obligatorio)
currency string Moneda de la transacción: CRC o USD (obligatorio)
categoryId string No ID de la categoría a asignar (opcional)
notes string No Notas adicionales del usuario (opcional)
counterAmount number No Monto equivalente en la moneda opuesta (opcional; usar solo si la cuenta maneja una moneda distinta al gasto)

Ejemplo de petición

JSON
POST /api/v1/vouchers/6642f3a1c3b4e200.../confirm
X-API-Key: tu_api_key

{
  "accountId": "acc123",
  "categoryId": "cat456",
  "date": "2025-05-20",
  "amount": 12500.00,
  "currency": "CRC",
  "notes": "Compras del mes"
}

Respuesta 200

JSON
{
  "id": "6642f3a1c3b4e201...",
  "type": "EXPENSE",
  "date": "2025-05-20",
  "amount": 12500.00,
  "currency": "CRC",
  "amountCRC": 12500.00,
  "exchangeRate": 1,
  "accountId": "acc123",
  "accountName": "BAC Corriente",
  "categoryId": "cat456",
  "categoryName": "Supermercado",
  "notes": "Compras del mes",
  "recurring": false,
  "ignoredFromBudget": false,
  "createdAt": "2025-05-20T14:35:00"
}

Elimina el voucher de la lista pendiente sin crear ninguna transacción. Útil para comprobantes que no corresponden a gastos reales. Retorna 204 No Content.

HTTP
DELETE /api/v1/vouchers/6642f3a1c3b4e200...
X-API-Key: tu_api_key

→ 204 No Content

Envía una imagen de comprobante bancario en base64; la IA extrae las transacciones y crea un voucher pendiente por cada una.

Campo
Campo Tipo Requerido Descripción
image string Imagen del comprobante en base64 puro o como data URI completo (data:image/jpeg;base64,...).
mimeType string No Tipo MIME de la imagen: image/jpeg, image/png, image/gif o image/webp. Se puede omitir si se envía como data URI.

Ejemplo de petición

JSON
{
  "image": "data:image/jpeg;base64,/9j/4AAQSkZ...",
  "mimeType": "image/jpeg"
}

Respuesta 200

JSON
[
  {
    "id": "664abc...",
    "date": "2025-05-20",
    "amount": 15800.00,
    "currency": "CRC",
    "merchant": "WALMART LINDORA",
    "notes": "Compra en WALMART LINDORA",
    "sourceEmail": null,
    "createdAt": "2025-05-20T18:32:00"
  }
]
La IA no detectó transacciones válidas en la imagen. Retorna lista vacía.

Tipo de Cambio USD → CRC

Consulta y actualiza el tipo de cambio registrado por el usuario para una fecha específica.

Retorna el tipo de cambio USD → CRC registrado para la fecha indicada. Si no se especifica fecha, usa la fecha de hoy en la zona horaria del usuario.

Parámetros de consulta
Campo Tipo Requerido Descripción
date string No Fecha del tipo de cambio en formato yyyy-MM-dd. Si se omite, usa la fecha de hoy.

Ejemplo de petición

HTTP
GET /api/v1/exchange-rate
GET /api/v1/exchange-rate?date=2026-06-02
X-API-Key: tu_api_key

Respuesta 200

JSON
{
  "date": "2026-06-02",
  "rate": 519.50,
  "userId": "abc123"
}

Registra o actualiza el tipo de cambio para la fecha indicada. Si ya existe un registro para esa fecha, lo reemplaza.

Campo
Campo Tipo Requerido Descripción
rate number Cantidad de colones equivalentes a 1 dólar (mayor a cero).
date string No Fecha del tipo de cambio en formato yyyy-MM-dd. Si se omite, usa la fecha de hoy.

Ejemplo de petición

JSON
PUT /api/v1/exchange-rate
X-API-Key: tu_api_key

{
  "rate": 519.50,
  "date": "2026-06-02"
}

Respuesta 200

JSON
{
  "date": "2026-06-02",
  "rate": 519.50,
  "userId": "abc123"
}
Errores
400Datos inválidos o faltantes en el cuerpo de la petición.

Asesor Financiero IA

Consulta y regenera los consejos del asesor financiero con inteligencia artificial.

Retorna los consejos almacenados en caché para el usuario y contexto indicados. Si no existen consejos previos, devuelve una lista vacía junto con los metadatos de control de actualización.

Parámetros de consulta
Campo Tipo Requerido Descripción
contextId string Contexto del análisis: "personal" para datos propios del usuario, o el ID de un grupo compartido.

Ejemplo de petición

HTTP
GET /api/v1/advice?contextId=personal
Authorization: Bearer <token>

Respuesta 200

JSON
{
  "userId": "abc123",
  "contextId": "personal",
  "advices": [
    {
      "title": "Reduce gastos en comida",
      "description": "Tus gastos en alimentación representan el 40% de tus ingresos mensuales.",
      "actionItem": "Prepara al menos 3 comidas en casa por semana.",
      "category": "FOOD",
      "priority": "HIGH"
    }
  ],
  "canRefresh": false,
  "nextRefreshAt": "2026-06-09T10:30:00"
}
Errores
403El usuario autenticado no coincide con el userId solicitado.

Fuerza la regeneración de consejos con IA para el userId y contextId indicados. Respeta el límite de una actualización cada 7 días.

Parámetros de consulta
Campo Tipo Requerido Descripción
contextId string Contexto del análisis: "personal" para datos propios del usuario, o el ID de un grupo compartido.
Solo se permite una regeneración cada 7 días por usuario y contexto. Si el intervalo no ha transcurrido, el API retorna 429 Too Many Requests.

Ejemplo de petición

HTTP
PUT /api/v1/advice?contextId=personal
Authorization: Bearer <token>

Respuesta 200

JSON
{
  "userId": "abc123",
  "contextId": "personal",
  "advices": [
    {
      "title": "Fondo de emergencia insuficiente",
      "description": "Tu ahorro actual cubre solo 0.5 meses de gastos.",
      "actionItem": "Destina el 10% de tus ingresos mensuales a una cuenta de ahorro dedicada.",
      "category": "SAVINGS",
      "priority": "HIGH"
    }
  ],
  "canRefresh": false,
  "nextRefreshAt": "2026-06-09T10:30:00"
}

Respuesta 429

JSON
{
  "error": "No puedes actualizar los consejos hasta el 2026-06-09",
  "nextRefreshAt": "2026-06-09T10:30:00"
}
Errores
403El usuario autenticado no coincide con el userId solicitado.
429El período mínimo de 7 días entre actualizaciones no ha transcurrido. El campo nextRefreshAt indica cuándo estará disponible.
¿Dudas o necesitás acceso a la API? Escríbenos a soporte@kakebo.io.