API Monobank на Python: Як отримати баланс та виписку
monobank надає розробникам простий та зручний REST API для доступу до особистих даних. Це дозволяє легко автоматизувати домашню бухгалтерію, створювати Telegram-ботів або імпортувати виписку транзакцій у власні бази даних.
У цій статті ми розглянемо реальний приклад роботи з API на мові Python.
Крок 1. Отримання персонального токена
Для роботи з особистим API вам потрібен секретний токен авторизації:
- Перейдіть на офіційний сайт для розробників: api.monobank.ua.
- Авторизуйтеся, відсканувавши QR-код за допомогою додатку monobank на телефоні.
- Скопіюйте свій унікальний X-Token. Зберігайте його в таємниці!
Крок 2. Особливості формату даних monobank API
Перед написанням коду важливо знати три речі про API:
- Копійки замість гривень: Усі суми (баланси, суми транзакцій, комісії) передаються в API як цілі числа в копійках. Тобто баланс
482150означає4821.50 UAH. - Коди валют ISO 4217: Валюти передаються у вигляді числових кодів (наприклад, гривня UAH —
980, долар USD —840, євро EUR —978). - Ліміти запитів (Rate Limiting): Для персонального API діє жорстке обмеження: не більше 1 запиту на 60 секунд для отримання виписки по одному рахунку. При перевищенні ліміту API поверне статус
429 Too Many Requests.
Крок 3. Написання Python скрипту
Ми напишемо чистий та надійний Python-код, який робить два запити:
- Отримує інформацію про клієнта та баланс карток (
GET /personal/client-info). - Отримує виписку за останні 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:
- Visit the official developer gateway at: api.monobank.ua.
- Authenticate by scanning the onscreen QR code with the monobank app scanner on your phone.
- 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:
- 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
482150means4821.50 UAH. - ISO 4217 Currency Encoding: Currencies are mapped as numerical standards (e.g., UAH is
980, USD is840, EUR is978). - 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 Requestsstatus.
Step 3. Implementation in Python
We will write a standard, dependencies-free Python script that triggers two requests:
- Read account properties, types, and balances (
GET /personal/client-info). - 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.