Назад до monobank Back to monobank

API Monobank на Python: Як отримати баланс та виписку

monobank надає розробникам простий та зручний REST API для доступу до особистих даних. Це дозволяє легко автоматизувати домашню бухгалтерію, створювати Telegram-ботів або імпортувати виписку транзакцій у власні бази даних.

У цій статті ми розглянемо реальний приклад роботи з API на мові Python.

Крок 1. Отримання персонального токена

Для роботи з особистим API вам потрібен секретний токен авторизації:

  1. Перейдіть на офіційний сайт для розробників: api.monobank.ua.
  2. Авторизуйтеся, відсканувавши QR-код за допомогою додатку monobank на телефоні.
  3. Скопіюйте свій унікальний X-Token. Зберігайте його в таємниці!

Крок 2. Особливості формату даних monobank API

Перед написанням коду важливо знати три речі про API:

  1. Копійки замість гривень: Усі суми (баланси, суми транзакцій, комісії) передаються в API як цілі числа в копійках. Тобто баланс 482150 означає 4821.50 UAH.
  2. Коди валют ISO 4217: Валюти передаються у вигляді числових кодів (наприклад, гривня UAH — 980, долар USD — 840, євро EUR — 978).
  3. Ліміти запитів (Rate Limiting): Для персонального API діє жорстке обмеження: не більше 1 запиту на 60 секунд для отримання виписки по одному рахунку. При перевищенні ліміту API поверне статус 429 Too Many Requests.

Крок 3. Написання Python скрипту

Ми напишемо чистий та надійний Python-код, який робить два запити:

  1. Отримує інформацію про клієнта та баланс карток (GET /personal/client-info).
  2. Отримує виписку за останні 5 днів (GET /personal/statement/{account}/{from}/{to}).

Для відправки запитів використаємо стандартну бібліотеку urllib.request (щоб код працював без встановлення сторонніх бібліотек).

import urllib.request
import json
import time
from datetime import datetime, timedelta

# Вставте сюди свій реальний токен авторизації
X_TOKEN = "YOUR_REAL_X_TOKEN_HERE"

def make_monobank_request(endpoint):
    url = f"https://api.monobank.ua{endpoint}"
    req = urllib.request.Request(url)
    req.add_header("X-Token", X_TOKEN)
    
    try:
        with urllib.request.urlopen(req) as response:
            if response.status == 200:
                return json.loads(response.read().decode('utf-8'))
    except urllib.error.HTTPError as e:
        if e.code == 429:
            print("[Помилка] Перевищено ліміт запитів (429). Спробуйте знову через 60 секунд.")
        else:
            print(f"[Помилка] API повернув статус {e.code}: {e.read().decode('utf-8')}")
    except Exception as e:
        print(f"[Помилка] Не вдалося з'єднатися: {e}")
    return None

def main():
    print("=== Запит інформації про клієнта ===")
    client_info = make_monobank_request("/personal/client-info")
    
    if not client_info:
        return
        
    print(f"Клієнт: {client_info.get('name')}")
    
    # Знайдемо гривневий рахунок
    uah_account_id = None
    print("\nВаші рахунки:")
    for acc in client_info.get("accounts", []):
        currency_code = acc.get("currencyCode")
        
        # 980 - код гривні
        if currency_code == 980:
            uah_account_id = acc.get("id")
            
        balance = acc.get("balance", 0) / 100.0
        cashback_type = acc.get("cashbackType", "Немає")
        print(f"- ID: {acc.get('id')[:8]}... | Валюта: {currency_code} | Баланс: {balance:.2f} UAH | Кешбек: {cashback_type}")
    
    # Отримаємо виписку за останні 5 днів, якщо знайшли гривневий рахунок
    if uah_account_id:
        print("\nЗачекайте 60 секунд перед наступним запитом, щоб уникнути ліміту (Rate Limit)...")
        time.sleep(10) # У реальному коді зачекайте хоча б 60 секунд, якщо ви робили запити нещодавно
        
        print("\n=== Запит виписки транзакцій ===")
        now = int(time.time())
        five_days_ago = now - (5 * 24 * 60 * 60)
        
        statement = make_monobank_request(f"/personal/statement/{uah_account_id}/{five_days_ago}/{now}")
        
        if statement:
            print(f"Отримано {len(statement)} транзакцій:")
            for tx in statement[:10]: # Покажемо перші 10 транзакцій
                tx_time = datetime.fromtimestamp(tx.get("time")).strftime('%Y-%m-%d %H:%M:%S')
                amount = tx.get("amount", 0) / 100.0
                desc = tx.get("description", "Без опису")
                mcc = tx.get("mcc")
                print(f"[{tx_time}] {desc} (MCC: {mcc}) | {amount:+.2f} UAH")
        else:
            print("Не вдалося отримати виписку транзакцій.")

if __name__ == "__main__":
    main()

Крок 4. Робота в реальному часі через Webhooks

Якщо ви будуєте систему обліку витрат у реальному часі, постійне опитування (polling) не підійде через ліміти. Замість цього monobank дозволяє встановити Webhook.

При налаштуванні Webhook банк надсилатиме POST запит на вказану вами адресу щоразу, коли по карті відбувається будь-яка транзакція.

Встановити Webhook можна відправивши запит:

POST https://api.monobank.ua/personal/webhook

з тілом запиту {"webHookUrl": "https://yourserver.com/callback"}.

Це надійний спосіб миттєво реагувати на транзакції без порушення Rate Limiting правил.

Monobank API with Python: How to Get Balance and Statements

monobank provides developers with a clean and simple REST API to interact with personal account logs. This allows you to easily automate home bookkeeping, program Telegram balance bots, or aggregate statement data into custom dashboards.

In this guide, we will implement a real-world Python script to authenticate and read client balances and statements.

Step 1. Acquiring Your Auth Token

To start querying the private endpoints, you need a secret X-Token authorization header:

  1. Visit the official developer gateway at: api.monobank.ua.
  2. Authenticate by scanning the onscreen QR code with the monobank app scanner on your phone.
  3. Copy your unique X-Token. Keep it secure and never share it publicly!

Step 2. Understanding monobank API Data Formats

Before writing code, make sure to consider three core design choices of monobank's API:

  1. Integer Scale Payouts: All financial amounts (balances, transaction sums, fee rates) are returned as integer values multiplied by 100 (i.e. represented in cents). A balance response of 482150 means 4821.50 UAH.
  2. ISO 4217 Currency Encoding: Currencies are mapped as numerical standards (e.g., UAH is 980, USD is 840, EUR is 978).
  3. Strict Rate Limiting: The personal API enforces a restriction: no more than 1 request per 60 seconds per account for statement queries. Exceeding this triggers a 429 Too Many Requests status.

Step 3. Implementation in Python

We will write a standard, dependencies-free Python script that triggers two requests:

  1. Read account properties, types, and balances (GET /personal/client-info).
  2. Read transaction statement logs for the past 5 days (GET /personal/statement/{account}/{from}/{to}).

We will use Python's built-in urllib.request standard library module.

import urllib.request
import json
import time
from datetime import datetime

# Place your actual X-Token developer string here
X_TOKEN = "YOUR_REAL_X_TOKEN_HERE"

def make_monobank_request(endpoint):
    url = f"https://api.monobank.ua{endpoint}"
    req = urllib.request.Request(url)
    req.add_header("X-Token", X_TOKEN)
    
    try:
        with urllib.request.urlopen(req) as response:
            if response.status == 200:
                return json.loads(response.read().decode('utf-8'))
    except urllib.error.HTTPError as e:
        if e.code == 429:
            print("[Error] Rate limit hit (429). Wait 60 seconds and retry.")
        else:
            print(f"[Error] API returned status {e.code}: {e.read().decode('utf-8')}")
    except Exception as e:
        print(f"[Error] Connection failed: {e}")
    return None

def main():
    print("=== Requesting Client Info ===")
    client_info = make_monobank_request("/personal/client-info")
    
    if not client_info:
        return
        
    print(f"Client Name: {client_info.get('name')}")
    
    # Locate UAH account ID
    uah_account_id = None
    print("\nAvailable Accounts:")
    for acc in client_info.get("accounts", []):
        currency_code = acc.get("currencyCode")
        
        # 980 is the numeric ISO code for UAH
        if currency_code == 980:
            uah_account_id = acc.get("id")
            
        balance = acc.get("balance", 0) / 100.0
        cashback_type = acc.get("cashbackType", "None")
        print(f"- ID: {acc.get('id')[:8]}... | Currency: {currency_code} | Balance: {balance:.2f} UAH | Cashback: {cashback_type}")
    
    # Fetch statements if a UAH account was found
    if uah_account_id:
        print("\nNote: Please wait 60s between statement requests to respect Rate Limiting...")
        time.sleep(10) # In production code, delay for 60s if you queried recently
        
        print("\n=== Requesting Statements (Last 5 Days) ===")
        now = int(time.time())
        five_days_ago = now - (5 * 24 * 60 * 60)
        
        statement = make_monobank_request(f"/personal/statement/{uah_account_id}/{five_days_ago}/{now}")
        
        if statement:
            print(f"Retrieved {len(statement)} transactions:")
            for tx in statement[:10]: # Print top 10 logs
                tx_time = datetime.fromtimestamp(tx.get("time")).strftime('%Y-%m-%d %H:%M:%S')
                amount = tx.get("amount", 0) / 100.0
                desc = tx.get("description", "No description")
                mcc = tx.get("mcc")
                print(f"[{tx_time}] {desc} (MCC: {mcc}) | {amount:+.2f} UAH")
        else:
            print("Failed to retrieve transaction statements.")

if __name__ == "__main__":
    main()

Step 4. Real-time Notifications via Webhooks

If you are developing a real-time ledger, polling is discouraged because of the rate limits. Instead, monobank supports custom Webhooks.

Once a Webhook is configured, monobank will push a POST request to your server endpoint immediately when any event happens.

You can set up a Webhook by sending a POST query:

POST https://api.monobank.ua/personal/webhook

with the body {"webHookUrl": "https://yourserver.com/callback"}.

This allows instant processing without violating API rate limit rules.

Реферальна акція 2026
Referral Promo 2026

Бажаєте відкрити безкоштовну картку?

Want to Open a Free Account?

Отримайте 50 ₴ бонусу на кешбек при реєстрації за посиланням.

Get 50 ₴ signup cashback reward by opening a card via our link.

Отримати картку з бонусом 50 ₴ Claim Card + 50 ₴ Bonus