API

Referencia de endpoints

Versión 1.0.0 de la API. Todos los endpoints bajo /v1 requieren un token personal.

Base https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api
Auth Authorization: Bearer mfd_...

Los importes van en euros y los apuntes se organizan por año y mes. Si es tu primera vez, empieza por la introducción; para los detalles de los tokens, mira autenticación.

Cuenta

Información del usuario y del token.

GET /v1/me Token

Datos de la cuenta y del token en uso

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/me" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "email": "tu@email.com",
  "created_at": "2026-08-18T09:15:00.000Z",
  "onboarding_completed": true,
  "email_notifications_enabled": true,
  "selected_year": 2026,
  "token": {
    "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
    "scopes": [
      "read"
    ]
  }
}

Códigos de respuesta

  • 200 Perfil del usuario.
  • 401 Token ausente, caducado o revocado.

Categorías

Categorías de ingresos, gastos y patrimonio.

GET /v1/categories Token

Listar categorías

Para income y expense incluye las subcategorías. Si pasas year, solo devuelve las categorías activas en ese año.

Parámetros

Nombre En Tipo Descripción
type obligatorio query string Valores: income, expense, asset
year query integer

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/categories?type=valor&year=2026" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "type": "income",
  "data": [
    {
      "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "name": "Alimentación",
      "type": "cuenta_bancaria",
      "display_order": 0,
      "created_at": "2026-08-18T09:15:00.000Z",
      "subcategories": [
        {
          "id": null,
          "name": null,
          "display_order": null
        }
      ]
    }
  ]
}

Códigos de respuesta

  • 200 Listado de categorías.
  • 400 Parámetros no válidos.
POST /v1/categories Token

Crear una categoría de ingreso o gasto

Requiere un token con scope write.

Cuerpo de la petición

Campo Tipo Descripción
type obligatorio string Valores: income, expense
name obligatorio string
display_order integer
year integer Año en el que la categoría queda activa. Por defecto, el actual.

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/categories" \
  -X POST \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"income","name":"Suscripciones","display_order":0,"year":1}'

Respuesta 201

{
  "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "name": "Alimentación",
  "type": "cuenta_bancaria",
  "display_order": 0,
  "created_at": "2026-08-18T09:15:00.000Z",
  "subcategories": [
    {
      "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "name": "Supermercado",
      "display_order": 0
    }
  ]
}

Códigos de respuesta

  • 201 Categoría creada.
  • 400 Nombre duplicado o datos no válidos.
  • 403 El token no tiene scope `write`.

Apuntes

Ingresos y gastos mensuales.

GET /v1/entries Token

Listar ingresos o gastos

Parámetros

Nombre En Tipo Descripción
type obligatorio query string Valores: income, expense
year query integer
month query integer
category_id query string (uuid)
subcategory_id query string (uuid)
limit query integer por defecto: 50
offset query integer por defecto: 0

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/entries?type=valor&year=2026&month=3" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "type": "income",
  "data": [
    {
      "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "category_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "subcategory_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "year": 2026,
      "month": 8,
      "amount": 42.5,
      "description": "Compra semanal",
      "created_at": "2026-08-18T09:15:00.000Z",
      "updated_at": "2026-08-18T09:15:00.000Z",
      "category": {
        "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
        "name": "Alimentación"
      },
      "subcategory": {
        "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
        "name": "Supermercado"
      }
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "returned": 50,
    "has_more": true
  }
}

Códigos de respuesta

  • 200 Apuntes ordenados del más reciente al más antiguo.
  • 400 Parámetros no válidos.
POST /v1/entries Token

Crear un ingreso o un gasto

Requiere scope write. Si la categoría todavía no estaba activa en ese año, se activa automáticamente para que el apunte se vea en la app.

Cuerpo de la petición

Campo Tipo Descripción
type obligatorio string Valores: income, expense
category_id obligatorio string (uuid)
subcategory_id string (uuid) | null
year obligatorio integer
month obligatorio integer
amount obligatorio number
description string | null

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/entries" \
  -X POST \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"income","category_id":"3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90","subcategory_id":"3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90","year":2026,"month":8,"amount":34.9,"description":"Compra semanal"}'

Respuesta 201

{
  "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "category_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "subcategory_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "year": 2026,
  "month": 8,
  "amount": 42.5,
  "description": "Compra semanal",
  "created_at": "2026-08-18T09:15:00.000Z",
  "updated_at": "2026-08-18T09:15:00.000Z",
  "category": {
    "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
    "name": "Alimentación"
  },
  "subcategory": {
    "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
    "name": "Supermercado"
  }
}

Códigos de respuesta

  • 201 Apunte creado.
  • 400 Datos no válidos.
  • 403 El token no tiene scope `write`.
  • 404 La categoría o subcategoría no existe.
PATCH /v1/entries/{id} Token

Modificar un apunte

Requiere scope write. Envía solo los campos que quieras cambiar.

Parámetros

Nombre En Tipo Descripción
id obligatorio ruta string (uuid)
type obligatorio query string Indica en qué tabla buscar el apunte. Valores: income, expense

Cuerpo de la petición

Campo Tipo Descripción
category_id string (uuid)
subcategory_id string (uuid) | null
year integer
month integer
amount number
description string | null

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/entries/:id?type=valor" \
  -X PATCH \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"category_id":"3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90","subcategory_id":"3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90","year":1,"month":1,"amount":0,"description":"texto"}'

Respuesta 200

{
  "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "category_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "subcategory_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "year": 2026,
  "month": 8,
  "amount": 42.5,
  "description": "Compra semanal",
  "created_at": "2026-08-18T09:15:00.000Z",
  "updated_at": "2026-08-18T09:15:00.000Z",
  "category": {
    "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
    "name": "Alimentación"
  },
  "subcategory": {
    "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
    "name": "Supermercado"
  }
}

Códigos de respuesta

  • 200 Apunte actualizado.
  • 403 El token no tiene scope `write`.
  • 404 El apunte no existe.
DELETE /v1/entries/{id} Token

Borrar un apunte

Requiere scope write.

Parámetros

Nombre En Tipo Descripción
id obligatorio ruta string (uuid)
type obligatorio query string Indica en qué tabla buscar el apunte. Valores: income, expense

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/entries/:id?type=valor" \
  -X DELETE \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "deleted": true
}

Códigos de respuesta

  • 200 Apunte borrado.
  • 403 El token no tiene scope `write`.
  • 404 El apunte no existe.

Resúmenes

Totales calculados y evolución.

GET /v1/summary Token

Totales de ingresos, gastos y ahorro

Sin month devuelve el año completo con desglose mes a mes. Con month, solo ese mes.

Parámetros

Nombre En Tipo Descripción
year query integer Por defecto, el año actual.
month query integer

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/summary?year=2026&month=3" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "period": {
    "year": 1,
    "month": 1
  },
  "income": {
    "total": 28450.12,
    "by_category": [
      {
        "category_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
        "name": "Alimentación",
        "total": 4820.9
      }
    ],
    "by_month": [
      {
        "month": 3,
        "total": 2350.4
      }
    ]
  },
  "expenses": {
    "total": 28450.12,
    "by_category": [
      {
        "category_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
        "name": "Alimentación",
        "total": 4820.9
      }
    ],
    "by_month": [
      {
        "month": 3,
        "total": 2350.4
      }
    ]
  },
  "savings": {
    "total": 13549.88,
    "rate": 0.3226,
    "by_month": [
      {
        "month": 3,
        "total": 2350.4
      }
    ]
  }
}

Códigos de respuesta

  • 200 Resumen del periodo.
GET /v1/net-worth Token

Foto del patrimonio en un mes

Sin parámetros usa el último mes con datos. Las categorías de tipo deuda restan.

Parámetros

Nombre En Tipo Descripción
year query integer
month query integer

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/net-worth?year=2026&month=3" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "as_of": {
    "year": 1,
    "month": 1
  },
  "total": 84210.55,
  "assets": 96210.55,
  "liabilities": 12000,
  "by_category": [
    {
      "category_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "name": "Cuenta corriente",
      "type": "cuenta_bancaria",
      "amount": 8200,
      "net_amount": 8200
    }
  ]
}

Códigos de respuesta

  • 200 Patrimonio neto y desglose por categoría.
GET /v1/net-worth/history Token

Evolución mensual del patrimonio

Parámetros

Nombre En Tipo Descripción
from_year query integer
to_year query integer

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/net-worth/history?from_year=2020&to_year=2026" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "data": [
    {
      "year": 2026,
      "month": 3,
      "total": 81340.2
    }
  ]
}

Códigos de respuesta

  • 200 Serie ordenada cronológicamente.

Inversiones

Posiciones, movimientos y efectivo.

GET /v1/holdings Token

Listar posiciones

Incluye la valoración de cada posición y los totales de la cartera. Si no hay precio actual se usa el coste medio, igual que en la app.

Parámetros

Nombre En Tipo Descripción
source query string Valores: ibkr, myinvestor, manual, binance, revolutx, sego
asset_type query string Valores: etf, stock, fund, crypto, bond, other

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/holdings" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "data": [
    {
      "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "symbol": "VUAA",
      "isin": "IE00B3XXRP09",
      "name": "Vanguard S&P 500 UCITS ETF",
      "source": "ibkr",
      "asset_type": "etf",
      "account_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "quantity": 120.5,
      "cost_basis": 78.4,
      "current_price": 92.15,
      "currency": "EUR",
      "exchange": "AEB",
      "last_price_update": "2026-08-18T09:15:00.000Z",
      "price_as_of": "2026-08-18",
      "position_value": 11104.08,
      "cost_value": 9447.2,
      "pnl": 1656.88,
      "pnl_percent": 17.54
    }
  ],
  "totals": {
    "count": 12,
    "value": 84210.55,
    "cost": 71300,
    "pnl": 12910.55,
    "pnl_percent": 18.11
  }
}

Códigos de respuesta

  • 200 Posiciones y totales.
GET /v1/holdings/{id} Token

Detalle de una posición

Parámetros

Nombre En Tipo Descripción
id obligatorio ruta string (uuid)

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/holdings/:id" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "symbol": "VUAA",
  "isin": "IE00B3XXRP09",
  "name": "Vanguard S&P 500 UCITS ETF",
  "source": "ibkr",
  "asset_type": "etf",
  "account_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
  "quantity": 120.5,
  "cost_basis": 78.4,
  "current_price": 92.15,
  "currency": "EUR",
  "exchange": "AEB",
  "last_price_update": "2026-08-18T09:15:00.000Z",
  "price_as_of": "2026-08-18",
  "position_value": 11104.08,
  "cost_value": 9447.2,
  "pnl": 1656.88,
  "pnl_percent": 17.54
}

Códigos de respuesta

  • 200 La posición con su valoración.
  • 404 La posición no existe.
GET /v1/holdings/{id}/transactions Token

Movimientos de una posición

Parámetros

Nombre En Tipo Descripción
id obligatorio ruta string (uuid)
limit query integer por defecto: 50
offset query integer por defecto: 0

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/holdings/:id/transactions" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "data": [
    {
      "id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "holding_id": "3f6b1c2e-9a4d-4c1f-8b7e-2d5a6c8e1f90",
      "type": "buy",
      "quantity": 12.5,
      "price": 88.2,
      "amount": 1102.5,
      "transaction_date": "2026-08-18",
      "description": "Aportación mensual",
      "imported_from": "ibkr_sync",
      "created_at": "2026-08-18T09:15:00.000Z"
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "returned": 50,
    "has_more": true
  }
}

Códigos de respuesta

  • 200 Compras, ventas, dividendos y traspasos.
  • 404 La posición no existe.
GET /v1/cash Token

Saldos de efectivo por bróker y divisa

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/cash" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "data": [
    {
      "source": "ibkr",
      "currency": "EUR",
      "amount": 1520.33,
      "last_sync_at": "2026-08-18T09:15:00.000Z",
      "updated_at": "2026-08-18T09:15:00.000Z"
    }
  ],
  "by_currency": [
    {
      "currency": "EUR",
      "total": 1520.33
    }
  ]
}

Códigos de respuesta

  • 200 Saldos sincronizados.

Referencia

Índices de mercado y estado del servicio.

GET /health Público

Estado del servicio

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/health" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "status": "ok",
  "time": "2026-08-18T09:15:00.000Z"
}

Códigos de respuesta

  • 200 El servicio responde.
GET /v1/benchmarks Token

Histórico de índices de mercado

Parámetros

Nombre En Tipo Descripción
name query string
from query string (date)
to query string (date)
limit query integer por defecto: 365

Ejemplo

curl "https://enjcwrocbfwhtofxfjyo.supabase.co/functions/v1/api/v1/benchmarks?name=SP500" \
  -H "Authorization: Bearer $MISFINANZAS_API_KEY"

Respuesta 200

{
  "data": [
    {
      "benchmark_name": "SP500",
      "date": "2026-08-18",
      "close_value": 5487.03,
      "change_percent": 0.42
    }
  ]
}

Códigos de respuesta

  • 200 Valores de cierre, del más reciente al más antiguo.