Nevlo
Docs
Try it for free

Documentation

Getting StartedAuthenticationAPI ReferenceMCP Setup
© 2026 Nevlo
Terms and ConditionsPrivacy PolicyLegal Notice

API Reference

This page is generated directly from the OpenAPI spec.

Base URL: https://nevlo.io/api/v1

Auth: Authorization: Bearer ACCESS_TOKEN

OpenAPI JSON: /api/openapi.json (Version 1.0.0)

GET/api/v1/accounts

List connected bank accounts

Status codes: 200, 401, 403, 429, 500

Sample response:

{
  "accounts": [
    {
      "id": "string",
      "accountName": "string",
      "iban": "string",
      "accountType": "string",
      "balance": 2450,
      "currency": "EUR",
      "lastSyncedAt": "2026-01-15T08:30:00.000Z",
      "bankConnection": {
        "bankName": "Sparkasse",
        "status": "ACTIVE"
      }
    }
  ]
}
GET/api/v1/cashflow

Monthly cashflow summary

Query parameters:

accountIds(string)optional - Comma-separated bank account IDs. Optional if user has exactly one account.
months(integer)optional - Number of months of history (default 6)

Status codes: 200, 400, 401, 403, 429, 500

Sample response:

{
  "cashflow": [
    {
      "month": "2026-01",
      "income": 3200,
      "expenses": 2100.5,
      "net": 1099.5
    }
  ]
}
GET/api/v1/snapshot

Financial snapshot

Query parameters:

accountIds(string)optional - Comma-separated bank account IDs. Optional if user has exactly one account.

Status codes: 200, 400, 401, 403, 429, 500

Sample response:

{
  "totalBalance": 4200.5,
  "accountCount": 2,
  "accounts": [
    {
      "name": "Girokonto",
      "bank": "Sparkasse",
      "balance": 3200.5,
      "currency": "EUR"
    }
  ],
  "last30Days": {
    "totalExpenses": 1850,
    "topCategories": [
      {
        "category": "RENT",
        "amount": 750,
        "percentage": 41
      }
    ]
  }
}
GET/api/v1/subscriptions

Detected recurring payments

Query parameters:

accountIds(string)optional - Comma-separated bank account IDs. Optional if user has exactly one account.

Status codes: 200, 400, 401, 403, 429, 500

Sample response:

{
  "subscriptions": [
    {
      "merchantName": "Netflix",
      "amount": 12.99,
      "currency": "EUR",
      "frequency": "weekly",
      "lastCharged": "2026-01-15T08:30:00.000Z",
      "occurrences": 6
    }
  ]
}
POST/api/v1/sync

Trigger bank data sync

Request body:

accountIds(array<string>)optional - Bank account IDs to sync. Only the bank connections containing these accounts will be refreshed. If omitted, all bank connections are synced. Use `GET /accounts` to find available account IDs. Maximum 50 IDs per request.

Status codes: 202, 401, 403, 404, 429, 500

Sample response:

{
  "syncJobs": [
    {
      "syncId": "cmxyz456",
      "status": "syncing",
      "error": "string"
    }
  ],
  "skippedConnections": 1
}
GET/api/v1/sync/{syncId}

Get sync job status

Status codes: 200, 401, 403, 404, 500

Sample response:

{
  "syncId": "cmxyz456",
  "status": "pending",
  "newTransactions": 12,
  "error": "string",
  "createdAt": "2026-01-15T08:30:00.000Z",
  "updatedAt": "2026-01-15T08:30:00.000Z"
}
GET/api/v1/transactions

List transactions

Query parameters:

accountIds(string)optional - Comma-separated bank account IDs. Optional if user has exactly one account.
category(enum(GROCERIES, RENT, SALARY, TRANSPORT, SUBSCRIPTION, ENTERTAINMENT, TRANSFER, INSURANCE, HEALTH, DINING, SHOPPING, SAVINGS, OTHER))optional - Filter by transaction category
dateFrom(string (date))optional - Start date (ISO 8601)
dateTo(string (date))optional - End date (ISO 8601)
search(string)optional - Text search across merchant name, counterpart name, and purpose
page(integer)optional - Page number (default 1)
perPage(integer)optional - Results per page (default 50, max 100)

Status codes: 200, 400, 401, 403, 429, 500

Sample response:

{
  "transactions": [
    {
      "id": "string",
      "amount": -42.5,
      "currency": "EUR",
      "bookingDate": "2026-01-15T08:30:00.000Z",
      "valueDate": "2026-01-15T08:30:00.000Z",
      "merchantName": "string",
      "counterpartName": "string",
      "counterpartIban": "string",
      "counterpartMandateReference": "string",
      "type": "direct_debit"
    }
  ],
  "pagination": {
    "page": 1,
    "perPage": 50,
    "total": 142,
    "pageCount": 3
  }
}
GET/api/v1/transactions/{id}

Get a single transaction

Status codes: 200, 401, 403, 404, 429, 500

Sample response:

{
  "id": "clx1abc123",
  "amount": -42.5,
  "currency": "EUR",
  "bookingDate": "2026-03-15T00:00:00.000Z",
  "valueDate": "2026-03-15T00:00:00.000Z",
  "merchantName": "REWE",
  "counterpartName": "REWE Markt GmbH",
  "counterpartIban": "DE89370400440532013000",
  "counterpartBic": "COBADEFFXXX",
  "counterpartBankName": "Commerzbank",
  "counterpartMandateReference": "MR-2026-001",
  "counterpartCreditorId": "DE98ZZZ09999999999",
  "counterpartDebitorId": null,
  "type": "card_payment",
  "category": "GROCERIES",
  "purpose": "Einkauf REWE Markt",
  "bankTransactionCode": "PMNT-CCRD-POSD",
  "sepaPurposeCode": null,
  "isPotentialDuplicate": false,
  "isAdjustingEntry": false,
  "createdAt": "2026-03-15T10:30:00.000Z",
  "bankAccount": {
    "id": "clx2def456",
    "iban": "DE27100777770209299700",
    "accountName": "Girokonto",
    "bankConnection": {
      "bankName": "Sparkasse"
    }
  }
}

Error codes

400Bad request (e.g., multiple accounts without specifying accountIds)
401Missing or invalid access token
403Insufficient scope or no active subscription
404Transaction not found
429Rate limit exceeded (60 requests/minute)
500Internal server error