Огляд
Manilo API — це JSON REST API для програмного керування тим самим обліком, який ви бачите в застосунку для iOS: рахунками, категоріями, бюджетами, спільними групами та транзакціями. Використовуйте його, щоб створювати імпортери, експортери, мости синхронізації, дашборди чи власні автоматизації.
- Базовий URL:
https://api.manilo.app— попередній базовий URLapi.ledgy.appпродовжує працювати. - Префікс версії: усі ендпоїнти в цьому документі розміщено під
/api/v1/. - Транспорт: лише HTTPS. HTTP-запити не приймаються.
- Кодування: тіла запитів і відповідей у JSON. UTF-8. Назви властивостей у
camelCase. - Автентифікація:
Authorization: Bearer …у кожному запиті. - Підписка Cloud: потрібна для кожного ендпоїнта v1. Див. Обмеження за підпискою.
https://api.manilo.app/mcp — див. Інтеграції. Описаний тут REST API призначений для коду, який ви пишете самі.
Швидкий старт
Три кроки до вашого першого автентифікованого запиту.
1. Створіть Personal Access Token
- Увійдіть у дашборд Manilo і відкрийте Налаштування → API Access.
- Натисніть + Новий токен.
- Дайте токену описову назву (наприклад, «Zapier — щотижневий експорт»), оберіть потрібні скоупи (див. Скоупи) і за бажанням задайте термін дії.
- Скопіюйте токен. Він показується лише один раз. Токени починаються з префікса
lgpat_, за яким ідуть 64 шістнадцяткові символи.
На тій самій сторінці перелічено ваші активні токени з часом останнього використання та кількістю дозволів, показано попередження «Закінчується через 30 днів» і можна миттєво відкликати будь-який токен через іконку кошика. Один акаунт може одночасно мати до 25 активних токенів.
2. Виконайте запит
# Replace lgpat_… with your token curl "https://api.manilo.app/api/v1/accounts" \ -H "Authorization: Bearer lgpat_a1b2c3d4e5…"
3. Перевірте відповідь
{
"items": [
{
"id": "acc_01HK8V…",
"name": "Wise EUR",
"currencyCode": "EUR",
"initialBalance": 1240.50,
"icon": "wallet",
"color": "#4A90E2",
"order": 0,
"createdAt": "2026-04-12T08:13:09Z",
"updatedAt": "2026-05-01T17:02:31Z"
}
],
"totalCount": 1
}
Автентифікація
Кожен запит до /api/v1/ має містити заголовок Authorization. Приймаються два типи токенів:
- Personal Access Token (PAT) — довгоживучий bearer-токен, який ви створюєте в дашборді на сторінці Налаштування → API Access. Формат:
lgpat_+ 64 шістнадцяткові символи. Обмежений скоупами, відкликається, за бажанням із терміном дії. Рекомендовано для всіх сторонніх інтеграцій. - Session JWT — короткоживучий токен, що видається власним застосункам (iOS, дашборд). Не має обмежень за скоупами. Його можна використати для разового тестування, якщо вдасться дістати його із сеансу зі входом, але підтримуваний шлях — це PAT.
Формат заголовка
Authorization: Bearer lgpat_a1b2c3d4e5f6…
Обмеження токенів
- До 25 активних PAT на один акаунт Manilo.
- Під час створення можна задати необов’язковий термін дії. Прострочені токени повертають
401 Unauthorized. - Відкликані токени перестають працювати негайно — Manilo зберігає лише SHA-256-хеш токена, а не саме значення, тож токен, що витік, неможливо відновити: його можна лише відкликати й замінити.
Типові помилки автентифікації
- 401
- Токен відсутній, має неправильний формат, прострочений або відкликаний.
- 403
- Токен дійсний, але запитаний ендпоїнт потребує скоупа, якого немає у вашого PAT, або ваша підписка Cloud неактивна.
Скоупи
PAT працюють за моделлю deny-by-default. Токен може викликати лише ті ендпоїнти, потрібний скоуп яких він має; усе інше повертає 403 Forbidden. Надавайте найвужчий набір скоупів, який справді потрібен вашій інтеграції.
Доступні скоупи:
accounts:read
accounts:write
categories:read
categories:write
budgets:read
budgets:write
groups:read
groups:write
transactions:read
transactions:write
tags:read
tags:write
recurring:read
recurring:write
settings:read
settings:write
Кожен наведений нижче ендпоїнт показує потрібний скоуп як невеликий фіолетовий чип. Скоупи :write не передбачають :read — запитуйте обидва, якщо потрібні обидва.
Обмеження за підпискою
Усі ендпоїнти v1 — зокрема й ті, що лише читають дані, — вимагають, щоб користувач, який виконує запит, мав активну підписку Manilo Cloud. Якщо підписку скасовано, її термін минув або її ніколи не було оформлено, API відповідає:
HTTP/1.1 403 Forbidden
X-Subscription-Required: true
Content-Type: application/json
{ "error": "Active cloud subscription required" }
Заголовок X-Subscription-Required дозволяє клієнтам відрізнити блокування через підписку від звичайної відмови в доступі. Щоб відновити доступ, повторно активуйте Cloud у застосунку для iOS або на dashboard.manilo.app/upgrade.
Помилки
Помилки використовують стандартні коди стану HTTP. Тіло відповіді — це JSON-об’єкт з одним полем:
{ "error": "Human-readable message" }
Коди стану, які варто обробляти:
- 200
- OK — повернуто ресурс або список.
- 201
- Created — створено новий ресурс. Заголовок
Locationвказує на канонічний URL. - 204
- No Content — успішне видалення; тіла немає.
- 400
- Валідація не пройдена — відсутнє обов’язкове поле, значення поза діапазоном, некоректний JSON.
- 401
- Автентифікація не вдалася — див. Автентифікація.
- 403
- Доступ заборонено — недостатній скоуп або неактивна підписка.
- 404
- Ресурс не знайдено або він прихований авторизацією.
- 409
- Conflict — наприклад, порушення обмеження унікальності.
- 5xx
- Збій на стороні сервера. Ідемпотентні читання безпечно повторювати з експоненційною затримкою.
Пагінація та фільтри
Ендпоїнти списків за замовчуванням повертають усі відповідні елементи. Транзакції — єдиний ресурс, який може сильно зрости, — підтримують курсорну пагінацію.
Курсор транзакцій
curl "https://api.manilo.app/api/v1/transactions?limit=50&type=expense&dateFrom=2026-01-01" \ -H "Authorization: Bearer lgpat_…"
Відповідь містить nextCursor. Передайте його назад як query-параметр cursor, щоб отримати наступну сторінку; коли nextCursor дорівнює null, ви досягли кінця.
limit— розмір сторінки, обмежений діапазоном1..200. За замовчуванням50.cursor— непрозорий токен. Ставтеся до нього як до чорної скриньки.type,dateFrom,dateTo,categoryId,accountId,groupId— необов’язкові фільтри; див. ендпоїнт Список транзакцій.
Типи та формати
- Ідентифікатори — непрозорі рядки. Не розбирайте їх; вважайте їх чутливими до регістру ідентифікаторами в UTF-8.
- Часові позначки — ISO-8601 в UTC із завершальним
Z, наприклад"2026-05-13T10:30:00Z". - Дати (наприклад,
dateтранзакції) — той самий формат ISO-8601, але значущою є лише частина з датою. - Грошові суми — числа JSON в основних одиницях з точністю до 4 знаків після коми (наприклад,
12.50). Ніколи не в мінорних одиницях. Завжди в парі зcurrencyCode. - Коди валют — ISO-4217, рівно три великі літери (наприклад,
"EUR","USD","GBP"). - Видалення — усі операції видалення є м’якими видаленнями. Видалені елементи перестають з’являтися у відповідях списку та отримання; партнери зі спільного доступу й історичні чеки зберігаються.
- Побічні ефекти — видалення рахунку, категорії чи групи залишає залежні транзакції недоторканими; їхні посилання від’єднуються. Ендпоїнт Видалити рахунок приймає явну стратегію.
Рахунки
Рахунки — це контейнери, що зберігають баланси: банківський рахунок, кредитна картка, готівковий гаманець, брокерський рахунок. Кожна транзакція прив’язана до одного рахунку (або до двох — для переказів).
/api/v1/accounts
accounts:read
Повертає кожен рахунок, яким володіє автентифікований користувач або до якого він має доступ.
/api/v1/accounts/{id}
accounts:read
Отримати один рахунок за ідентифікатором. Якщо не знайдено — 404.
/api/v1/accounts
accounts:write
Створити новий рахунок. Повертає 201 зі створеним об’єктом і заголовком Location.
| Поле | Тип | Опис |
|---|---|---|
| name | string | обов’язковеВідображувана назва. Максимум 100 символів. |
| currencyCode | string | обов’язковеISO-4217. Рівно 3 літери. |
| initialBalance | number | обов’язковеПочатковий баланс у currencyCode. |
| order | integer | обов’язковеПозиція сортування. Менше значення — вище. |
| icon | string | необов’язковеІдентифікатор іконки з /api/v1/icons. Максимум 50. |
| color | string | необов’язковеКолір у HEX, наприклад "#4A90E2". Максимум 20. |
| iconColor | string | необов’язковеПеревизначає відтінок іконки. |
POST /api/v1/accounts
{
"name": "Cash",
"currencyCode": "EUR",
"initialBalance": 50.00,
"order": 2,
"icon": "wallet",
"color": "#22C55E"
}
{
"id": "acc_01HK8V…",
"name": "Cash",
"currencyCode": "EUR",
"initialBalance": 50.00,
"order": 2,
"icon": "wallet",
"color": "#22C55E",
"iconColor": null,
"shareInviteToken": null,
"createdAt": "2026-05-13T10:30:00Z",
"updatedAt": "2026-05-13T10:30:00Z"
}
/api/v1/accounts/{id}
accounts:write
Замінити наявний рахунок. Тіло запиту ідентичне до Створити; потрібно передати всі поля.
/api/v1/accounts/{id}
accounts:write
М’яко видалити рахунок. Долю його транзакцій визначає query-параметр action.
| Поле | Тип | Опис |
|---|---|---|
| action | enum | необов’язковеDetach (за замовчуванням): очистити посилання на рахунок у кожній транзакції. Move: перепризначити транзакції на moveTargetAccountId. DeleteAll: м’яко видалити кожну пов’язану транзакцію, якою ви володієте. |
| moveTargetAccountId | string | необов’язковеОбов’язковий, коли action=Move. Ідентифікатор рахунку призначення. |
Категорії
Категорії позначають, на що спрямована транзакція (продукти, оренда, дохід від фрилансу). Системні категорії доступні лише для читання і є спільними для всіх користувачів; користувацькими категоріями керуєте ви. Групи категорій об’єднують споріднені категорії.
/api/v1/categories/system-categories
categories:read
Повертає підібраний набір «загальновідомих» категорій Manilo — стартовий набір, з яким постачається застосунок для iOS. Вони версіонуються глобально, тож їх безпечно кешувати за version.
Користувацькі категорії
/api/v1/categories
categories:read
Список усіх визначених користувачем категорій.
/api/v1/categories/{id}
categories:read
Отримати одну користувацьку категорію за ідентифікатором.
/api/v1/categories
categories:write
Створити користувацьку категорію.
| Поле | Тип | Опис |
|---|---|---|
| name | string | обов’язковеВідображувана назва. Максимум 100. |
| type | string | обов’язкове"income" або "expense". |
| order | integer | обов’язковеПозиція сортування в межах своєї групи. |
| isPinned | boolean | обов’язковеЗакріпити вгорі списку вибору. |
| categoryGroupId | string | необов’язковеІдентифікатор батьківської групи або null для категорій без групи. |
| icon | string | необов’язковеІдентифікатор іконки. |
| color | string | необов’язковеКолір у HEX. |
/api/v1/categories/{id}
categories:write
Замінити користувацьку категорію. Тіло запиту ідентичне до Створити.
/api/v1/categories/{id}
categories:write
М’яко видалити користувацьку категорію. Транзакції не видаляються; їхнє поле categoryId очищається.
Групи категорій
/api/v1/categories/groups
categories:read
Список ваших груп категорій.
/api/v1/categories/groups/{id}
categories:read
Отримати одну групу категорій.
/api/v1/categories/groups
categories:write
Створити групу категорій.
| Поле | Тип | Опис |
|---|---|---|
| name | string | обов’язковеВідображувана назва. Максимум 100. |
| order | integer | обов’язковеПозиція сортування. |
| icon | string | необов’язковеІдентифікатор іконки. |
| color | string | необов’язковеКолір у HEX. |
/api/v1/categories/groups/{id}
categories:write
Замінити групу категорій.
/api/v1/categories/groups/{id}
categories:write
М’яко видалити групу. Дочірні категорії залишаються — їхнє поле categoryGroupId очищається.
Бюджети
Бюджет обмежує витрати за категорією (або, коли categoryId дорівнює null, за всім обліком) у межах повторюваного вікна. Щоб поділитися бюджетом із групою, задайте groupId.
/api/v1/budgets
budgets:read
Список усіх бюджетів.
/api/v1/budgets/{id}
budgets:read
Отримати один бюджет.
/api/v1/budgets
budgets:write
Створити бюджет.
| Поле | Тип | Опис |
|---|---|---|
| amount | number | обов’язковеЛіміт на період. Має бути більшим за 0. |
| currencyCode | string | обов’язковеISO-4217. |
| period | integer | обов’язкове0 — тиждень · 1 — місяць · 2 — квартал · 3 — рік. |
| startDate | string (ISO-8601) | обов’язковеПочаток першого періоду. |
| isActive | boolean | обов’язковеЧи діє цей бюджет наразі. |
| endDate | string (ISO-8601) | необов’язковеПрипинити відстеження після цієї дати. |
| name | string | необов’язковеПідпис. Максимум 200. |
| categoryId | string | необов’язковеКатегорія для відстеження. Пропустіть, щоб охопити бюджетом усі витрати. |
| groupId | string | необов’язковеГрупа, з якою поділитися. Пропустіть для особистого бюджету. |
/api/v1/budgets/{id}
budgets:write
Замінити бюджет.
/api/v1/budgets/{id}
budgets:write
М’яко видалити бюджет.
Групи
Групи — це спільні обліки: домогосподарство, подорож, спільна квартира. Кожен учасник бачить ті самі транзакції; власність залишається особистою. Членством і запрошеннями керують у застосунку для iOS; тут API надає лише сам ресурс.
/api/v1/groups
groups:read
Список груп, якими ви володієте або в яких перебуваєте.
/api/v1/groups/{id}
groups:read
Отримати одну групу.
/api/v1/groups
groups:write
Створити групу. Ви стаєте її власником; запрошуйте учасників із застосунку для iOS.
| Поле | Тип | Опис |
|---|---|---|
| name | string | обов’язковеВідображувана назва. Максимум 100. |
| description | string | необов’язковеДовільний текст. Максимум 500. |
| icon | string | необов’язковеІдентифікатор іконки. |
| color | string | необов’язковеКолір у HEX. |
/api/v1/groups/{id}
groups:write
Замінити метадані групи.
/api/v1/groups/{id}
groups:write
М’яко видалити групу. Учасники втрачають видимість; відповідні транзакції повертаються до особистих.
Транзакції
Транзакції — це дієслова обліку. Вони бувають чотирьох видів: income, expense, transfer (з рахунку на рахунок) і adjustment (разове вирівнювання балансу). Базовий ендпоїнт створює income/expense; для переказів є власний ендпоїнт; для імпортерів великих обсягів існують пакетні варіанти.
/api/v1/transactions
transactions:read
Список транзакцій із курсорною пагінацією та фільтрами.
| Поле | Тип | Опис |
|---|---|---|
| limit | integer | необов’язковеРозмір сторінки. 1..200. За замовчуванням 50. |
| cursor | string | необов’язковеНепрозорий токен продовження з попередньої відповіді. |
| type | string | необов’язкове"income", "expense", "transfer" або "adjustment". |
| dateFrom | string (ISO-8601) | необов’язковеНижня межа включно. |
| dateTo | string (ISO-8601) | необов’язковеВерхня межа включно. |
| categoryId | string | необов’язковеФільтр за однією категорією. |
| accountId | string | необов’язковеФільтр за одним рахунком. |
| groupId | string | необов’язковеФільтр за спільною групою. |
{
"items": [ /* TransactionDto[] */ ],
"totalCount": 317,
"nextCursor": "eyJrIjoiMjAyNi0wNS0xM1QxMDoz…"
}
/api/v1/transactions/{id}
transactions:read
Отримати одну транзакцію.
/api/v1/transactions
transactions:write
Створити одну транзакцію доходу або витрати. Для переказів використовуйте /transfer.
| Поле | Тип | Опис |
|---|---|---|
| type | string | обов’язкове"income" або "expense". |
| amount | number | обов’язковеДодатна сума в currencyCode. |
| currencyCode | string | обов’язковеISO-4217. |
| date | string (ISO-8601) | обов’язковеКоли відбулася транзакція (UTC). |
| accountId | string | необов’язковеРахунок джерела або призначення. |
| categoryId | string | необов’язковеПідпис категорії. |
| payee | string | необов’язковеПродавець або контрагент. Максимум 200. |
| note | string | необов’язковеДовільна нотатка. Максимум 2000. |
| groupId | string | необов’язковеПоділитися з групою. |
| exchangeRate | number | необов’язковеКурс обміну, коли currencyCode ≠ основній валюті користувача. |
| convertedAmount | number | необов’язковеСума в основній валюті користувача. |
POST /api/v1/transactions
{
"type": "expense",
"amount": 8.50,
"currencyCode": "EUR",
"date": "2026-05-12T09:14:00Z",
"accountId": "acc_01HK8V…",
"categoryId": "cat_food_drinks",
"payee": "Pret",
"note": "Flat white"
}
/api/v1/transactions/{id}
transactions:write
Замінити транзакцію. Тіло запиту ідентичне до Створити.
/api/v1/transactions/{id}
transactions:write
М’яко видалити одну транзакцію.
/api/v1/transactions/transfer
transactions:write
Створити переказ між двома рахунками. Без категорії. Для міжвалютних переказів передайте exchangeRate і convertedAmount у валюті призначення.
| Поле | Тип | Опис |
|---|---|---|
| fromAccountId | string | обов’язковеРахунок джерела. |
| toAccountId | string | обов’язковеРахунок призначення. Має відрізнятися від джерела. |
| amount | number | обов’язковеНадіслана сума в currencyCode. |
| currencyCode | string | обов’язковеВалюта джерела, ISO-4217. |
| date | string (ISO-8601) | обов’язковеДата переказу. |
| exchangeRate | number | необов’язковеОбов’язковий, коли валюти джерела й призначення відрізняються. |
| convertedAmount | number | необов’язковеСума, зарахована на рахунок призначення, у його валюті. |
| note | string | необов’язковеМаксимум 2000. |
Пакетні операції
Розроблено для імпортерів. Кожен пакет обмежено 100 елементами і виконується за принципом best-effort: один хибний рядок не відкочує решту. Успішні елементи та помилки по кожному рядку повідомляються окремо, тож невдалі можна повторити.
/api/v1/transactions/bulk
transactions:write
Створити до 100 транзакцій одним викликом.
{
"items": [ /* successful TransactionDto[] */ ],
"errors": [
{ "index": 3, "error": "Invalid currency code" }
]
}
/api/v1/transactions/bulk
transactions:write
Оновити до 100 транзакцій одним викликом. Кожен елемент має містити свій id разом із повним тілом транзакції.
/api/v1/transactions/bulk-delete
transactions:write
М’яко видалити до 100 транзакцій одним викликом. Використовує POST замість DELETE, щоб тіло запиту приймали всі HTTP-клієнти.
| Поле | Тип | Опис |
|---|---|---|
| ids | string[] | обов’язковеВід 1 до 100 ідентифікаторів транзакцій. |
{
"deleted": 97,
"notFound": [ "tx_old1", "tx_old2", "tx_old3" ]
}
Об’єкт транзакції
| Поле | Тип | Опис |
|---|---|---|
| id | string | Непрозорий ідентифікатор. |
| type | string | income · expense · transfer · adjustment. |
| amount | number | У currencyCode. |
| currencyCode | string | ISO-4217. |
| exchangeRate | number | null | Задається для міжвалютних записів. |
| convertedAmount | number | null | Те саме значення в основній валюті користувача. |
| date | string | ISO-8601 UTC. |
| accountId | string | null | Для переказів це рахунок джерела. |
| toAccountId | string | null | Рахунок призначення — лише для переказів. |
| categoryId | string | null | Null для переказів. |
| groupId | string | null | Задається, якщо є спільний доступ для групи. |
| payee | string | null | Продавець або контрагент. |
| note | string | null | Довільний текст. |
| receiptImagePath | string | null | Шлях до прикріпленого чека. Отримується через ендпоїнт чеків (окремий від v1). |
| recurringTransactionId | string | null | Задається, якщо цей рядок згенеровано з правила повторення. |
| source | string | Позначка походження — api, mobile, web, import тощо. |
| createdAt | string | ISO-8601 UTC. |
| updatedAt | string | ISO-8601 UTC. |
Іконки
Manilo постачається з підібраним набором іконок і палітрою кольорів, які використовуються всюди — для рахунків, категорій, груп. Отримайте каталог один раз, закешуйте його й повторно використовуйте ідентифікатори під час створення ресурсів.
/api/v1/icons
Повертає повну бібліотеку іконок, згруповану за категоріями, разом із підтримуваною палітрою кольорів. Версіонується — безпечно кешувати за полем version.
{
"version": "2026.05.10",
"library": "font-awesome-6",
"categories": [
{
"id": "finance",
"name": "Finance",
"icons": [ "wallet", "credit-card", "piggy-bank" ]
}
],
"colors": [
{ "name": "Blue", "hex": "#4A90E2" },
{ "name": "Green", "hex": "#22C55E" }
]
}
Версіонування
- Жодних ламких змін у межах v1. Ми додаватимемо лише нові ендпоїнти, нові необов’язкові поля та нові значення переліків. Тип поля, його допустимість null чи обов’язковість не змінюватимуться.
- Нові значення переліків не є ламкою зміною. Ставтеся до невідомих значень
type,sourceчиactionяк до «не відображати», а не завершуйте роботу аварійно — ми додаватимемо їх у міру розвитку продукту. - Ламкі зміни (якщо колись знадобляться) вийдуть під
/api/v2/із щонайменше 6 місяцями паралельної доступності та заголовком про застарілість у відповідях v1.
Підтримка
Знайшли помилку, потрібен новий ендпоїнт або натрапили на щось недокументоване? Відкрийте центр допомоги або напишіть на support@manilo.app — повідомляючи про проблему, вкажіть, будь ласка, ідентифікатор запиту (він дублюється в заголовку відповіді X-Request-Id).
Щодо повідомлень, чутливих до безпеки (витік токена, обхід дозволів, несанкціоноване читання), пишіть на security@manilo.app.