> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sure.am/llms.txt
> Use this file to discover all available pages before exploring further.

# Monobank

> Connect your Monobank (Ukraine) account to Sure

Monobank is a Ukrainian neobank. Sure connects to it directly using Monobank's personal API, syncing your cards, jars, balances, and transactions automatically. You bring your own token — no third-party aggregator sits in between.

<Note>
  This integration uses Monobank's **personal** API. Its documentation states that a service which stores other people's data on its own servers must use the corporate (service provider) API instead, and that programs used by clients personally — where the data never passes through the developer's nodes — do not. A self-hosted Sure instance is the latter. If you run Sure as a hosted service for other people, read [Monobank's API terms](https://api.monobank.ua/docs/index.html) first.
</Note>

<Note>
  The personal API is not available to clients under 16. Data for a child's accounts is available from the parent's account.
</Note>

## How it works

1. Generate a personal token at [api.monobank.ua](https://api.monobank.ua/)
2. Paste the token into Sure
3. Sure discovers your cards and jars and begins syncing balances and transactions
4. MCC codes on transactions are mapped to your Sure categories automatically on import

## Setting up Monobank

1. Go to [api.monobank.ua](https://api.monobank.ua/) and sign in by scanning the QR code with the Monobank app
2. Generate a personal token and copy it. It is shown only once
3. In Sure, go to **Settings > Providers**, find the **Monobank** panel, and paste the token
4. Link each discovered card or jar to an existing Sure account or create a new one. Skip anything you don't want to track

Cards become checking accounts; jars become savings accounts. A card's balance reflects your own funds — Monobank includes the credit limit inside the reported balance, and Sure subtracts it.

## Features

### Account syncing

* **Cards and jars**: All Monobank cards and jars with current balances
* **Transaction history**: Transactions are imported with date, amount, description, and category
* **Deduplication**: Transactions are matched by their Monobank ID, so re-syncing never creates duplicates

### Pending transactions

Held (unsettled) authorisations are imported and marked **Pending**. When a hold settles, Monobank may issue the settled record under a different ID. Sure matches it to the pending entry by amount and date, and the settled record inherits the pending entry's category and notes.

A hold that disappears from the statement (cancelled rather than settled) has its pending entry removed — unless:

* The statement request did not actually reach the hold's date. It stays visible while the funds are still blocked. Pre-authorisations for hotels, car hire, and fuel routinely outlive the few days a sync re-reads by default.
* You have taken over the entry yourself (excluded, edited, or split). It only loses its pending badge, so your edits, splits, and transfers survive.

To import only settled transactions, set `MONOBANK_INCLUDE_PENDING=0` in your environment.

### Category mapping

Monobank does not categorise transactions directly; it reports the merchant's MCC code. Sure maps codes with a clear equivalent (groceries, restaurants, fuel, pharmacies, and others) onto your existing Sure categories, matching by the category name in your own language. Codes without a clear equivalent — cash withdrawals, transfers, gambling — are left uncategorised for your own rules to handle.

Category mapping only applies to your existing Sure categories. If you have already set or locked a category on a transaction in Sure, a re-sync will not overwrite it.

To turn off automatic category mapping, open the account in Sure, go to its settings, and disable the **Automatic category mapping** toggle. When disabled, imported transactions carry no auto-assigned category and are left for your rules or the AI categorizer to handle. The raw transaction data and MCC code are still imported; only the auto-category assignment is skipped.

### Syncing cadence

Monobank's rate limit shapes how syncing works. Each personal endpoint accepts one request per minute, and a single statement request may cover at most 31 days. So:

* Every sync fetches your account list once, then reads statements account by account
* A sync spends a fixed budget of statement requests (4 by default). Accounts that don't fit are picked up by the next sync, least-recently-synced first
* History older than one statement window is backfilled over successive syncs, walking backwards 31 days at a time
* Each sync also re-reads the last few days, and any older hold that is still unsettled, so pending transactions stay accurate

Because of the throttle, a sync sleeps between requests. With four accounts, expect it to take a few minutes.

## Configuration

The following environment variables are available for self-hosted deployments:

| Variable                                   | Default | Purpose                                                                                  |
| ------------------------------------------ | ------- | ---------------------------------------------------------------------------------------- |
| `MONOBANK_INCLUDE_PENDING`                 | `1`     | Import held transactions and badge them as pending                                       |
| `MONOBANK_MAX_STATEMENT_REQUESTS_PER_SYNC` | `4`     | Statement requests one sync may spend. Each costs about a minute                         |
| `MONOBANK_PENDING_LOOKBACK_DAYS`           | `3`     | Minimum period every sync re-reads. A hold older than this extends the window on its own |
| `MONOBANK_INITIAL_HISTORY_DAYS`            | `31`    | History a new connection reaches for when no start date is set                           |
| `MONOBANK_MIN_REQUEST_INTERVAL`            | `60`    | Seconds enforced between requests to the same endpoint                                   |
| `MONOBANK_DEBUG_RAW`                       | unset   | Log raw API payloads. Development only — the dump contains personal data                 |

## Foreign currency operations

When a transaction is made in a currency other than the account's own currency — for example, paying in EUR from a UAH card — Monobank includes the operation currency code (`currencyCode`) and the operation amount (`operationAmount`) alongside the account-currency `amount`. Sure records the account-currency `amount` as the transaction amount and stores the foreign-currency detail as `fx_from` (the operation currency) and `fx_amount` (the operation amount in that currency), following the same convention used by the Up Bank integration.

Both `fx_from` and `fx_amount` are set only when the operation currency is recognized and differs from the account currency. An operation in the account's own currency, or one whose currency code Sure does not recognize, leaves both unset. The raw `operationAmount` is always recorded in `operation_amount` for reference when it differs from `amount`.

If the `operationAmount` cannot be parsed, `fx_amount` is left unset and the incident is captured as a `provider_sync_error` in the debug log (visible at **Settings > Debug**, filtered by the `monobank` provider key).

## Limitations

* Ukrainian accounts only
* Personal tokens are scoped to a single Monobank account holder
* Data is read-only; Sure never writes anything back to Monobank (the token can also register a statement webhook, but Sure does not use that capability)

## Troubleshooting

**Connection requires update**: The token was revoked or is invalid. Generate a new one at [api.monobank.ua](https://api.monobank.ua/) and update it in the provider panel.

**A sync says accounts were skipped**: Either the statement request budget ran out for this run, or Monobank throttled the request. One request per minute per endpoint means a manual sync started right after a scheduled one collides. These are normal and leave the connection healthy. The next sync continues where this one stopped. Raise `MONOBANK_MAX_STATEMENT_REQUESTS_PER_SYNC` if you would rather trade a longer sync for fewer runs.

**Older transactions are missing**: History arrives in 31-day steps, one step per sync. Set a start date on the connection to bound how far back it goes, then let it run.

**Sync errors**: Provider sync failures and notes are captured in Sure's debug log. Super admins can find them at **Settings > Debug**, filtered by the `monobank` provider key. This includes cases where a foreign-currency operation amount could not be parsed — the transaction still imports with the correct account-currency amount, but the FX detail (`fx_from`/`fx_amount`) is omitted.

For more detail, see the [Monobank personal API documentation](https://api.monobank.ua/docs/).
