Введение
API Aynes — REST-интерфейс организации для учётных систем, CRM, систем бронирования и своих скриптов. Через него можно читать операции, заявки на оплату, справочники и отчёты, создавать заявки на оплату, передавать брони и оплаты по ним, а вебхуки сами сообщат вашей системе о событиях в Aynes — опрашивать не нужно.
- Операции — список с фильтрами экрана «Операции».
- Заявки на оплату — чтение с ходом согласования и создание: новая заявка сразу уходит на согласование.
- Справочники — направления, юрлица, категории, контрагенты, счета и кассы, проекты.
- Отчёты — ДДС и ПиУ за период, теми же числами, что на экранах.
- Брони — передача броней и оплат из системы бронирования и сверка принятого.
- Вебхуки — новая операция, смена статуса и изменение заявки, ошибка загрузки выписки, оплата брони найдена в выписке.
| Базовый адрес | https://aynes.pro/api/v1 |
| Протокол | Только HTTPS |
| Формат | JSON в кодировке UTF-8; тело запроса — с заголовком Content-Type: application/json |
| Суммы | Целые числа в минимальных единицах валюты — тыйынах, центах, копейках: 12 500,50 сома — 1250050. Рядом всегда код валюты ISO 4217: KGS, USD, RUB… |
| Эквивалент | baseAmount — сумма в базовой валюте организации, exchangeRate — курс к ней строкой (десятичная дробь без потери точности). Курс фиксируется в момент проведения и задним числом не меняется. |
| Даты | ГГГГ-ММ-ДД, например 2026-10-08 |
| Моменты времени | ISO 8601. В ответах — UTC (2026-10-08T09:30:00.000Z), в запросах — с любым поясом (2026-10-08T15:30:00+06:00). Календарная дата операции в ответе — полночь UTC этого дня. |
| Часовой пояс | Дни и месяцы отчётов — в поясе организации: tenant.timezone в GET /me |
| Идентификаторы | Строки вида cm2opr9e6k0009m1n3p5q7r9s: храните как есть, не разбирайте |
| Описание OpenAPI | /api/v1/openapi.json — те же методы в формате OpenAPI 3.0, без токена: для генераторов клиентов и Postman |
Версия API — в адресе: v1. В неё могут добавляться методы, необязательные параметры и поля ответа — разбирайте ответ, пропуская незнакомые поля. Несовместимые изменения выйдут новой версией; что менялось — в разделе «Изменения API».
Проверить токен одной командой:
export AYNES_TOKEN="fsk_…"
curl "https://aynes.pro/api/v1/me" -H "Authorization: Bearer $AYNES_TOKEN"Авторизация
Каждый запрос несёт токен организации в заголовке Authorization:
Authorization: Bearer fsk_…Токен работает от имени организации; заявки, созданные через API, идут от имени того, кто токен выпустил. Храните токен на сервере — не в браузере и не в мобильном приложении. Без токена, с неверным или отозванным — 401 unauthorized.
Где выпустить
- Настройки → API и вебхуки → Токены API — владелец или администратор организации задаёт название, скоупы и, по желанию, срок действия. Секрет
fsk_…показывается один раз: в Aynes хранится только его хеш, и потерянный токен не восстановить — выпустите новый. - Брони → Настройки броней → «Ключ для системы бронирования» — ключ со скоупами
bookings:readиbookings:writeдля Voyz или другой системы бронирования. Там же — адрес API, который вставляют в систему вместе с ключом.
Скоупы
Токен получает только выбранные скоупы. Метод без нужного скоупа отвечает 403 forbidden с details.required — каким скоупом его открыть. GET /me открыт любому действующему токену.
| Скоуп | Что открывает | Методы |
|---|---|---|
operations:read | Чтение операций | GET /operations |
operations:write | Создание операций | POST /operations |
payment-requests:read | Чтение заявок на оплату | GET /payment-requests, GET /payment-requests/{id} |
payment-requests:write | Создание заявок на оплату | POST /payment-requests |
references:read | Чтение справочников | GET /references/units, GET /references/legal-entities, GET /references/categories, GET /references/contractors, GET /references/bank-accounts, GET /references/projects |
reports:read | Чтение отчётов | GET /reports/cashflow, GET /reports/pnl |
bookings:read | Чтение броней и оплат (сверка) (функция тарифа «Брони») | GET /bookings, GET /bookings/{source}/{externalId}, GET /bookings/{source}/{externalId}/payments/{paymentId} |
bookings:write | Передача броней и оплат по ним (функция тарифа «Брони») | PUT /bookings/{source}/{externalId}, PUT /bookings/{source}/{externalId}/payments/{paymentId} |
Тариф
- Внешний API и вебхуки — функция тарифа «API». На тарифе без неё запрос отвечает
403 forbiddenсdetails.feature = "api"иdetails.requiredPlan— названием тарифа, где функция есть. - Ключ, у которого все скоупы —
bookings:*, требует не «API», а функцию «Брони»: систему бронирования можно подключить на любом тарифе с бронями (details.feature = "bookings"). - Токен с любым другим скоупом требует «API» и на методах броней. Ключу броней на тарифе без «API»
GET /meотвечает403.
Срок жизни и отзыв
- Токен действует, пока не отозван, не истёк его срок (если задан) и пока тот, кто его выпустил, — владелец или администратор организации. Выпустивший ушёл или стал обычным участником — интеграция получает
401, пока действующий администратор не выпустит новый токен. - Отзыв — кнопкой «Отозвать» на экране токенов или ключей броней — действует сразу: следующий запрос получит
401 unauthorized. - Организация в режиме чтения (подписка не оплачена или на паузе): чтение работает, запись отвечает
403 read_only.
Общие правила
Формат ответа
Ответ всегда JSON в конверте. Успех — ok: true и данные в data; у списков и записей броней — ещё meta:
{
"ok": true,
"data": [
{
"id": "cm2opr9e6k0009m1n3p5q7r9s"
}
],
"meta": {
"page": 1,
"pageSize": 50,
"total": 1,
"pages": 1
}
}Ошибка — ok: false и объект error:
{
"ok": false,
"error": {
"code": "validation_error",
"message": "Проверьте параметры запроса",
"details": [
{
"path": "amount",
"message": "Сумма > 0"
}
]
}
}code— машинный код ошибки: набор фиксирован, ветвитесь по нему.message— текст для человека по-русски; он может меняться, не сравнивайте его в коде.details— подробности, если есть: поля с ошибками уvalidation_error, нужный скоуп уforbidden, текущая версия брони уconflict.- HTTP-код ответа соответствует коду ошибки (таблица ниже). Успешная запись нового объекта —
201, остальное —200.
Коды ошибок
| HTTP | Код | Когда | Что делать |
|---|---|---|---|
| 401 | unauthorized | Токен не передан, неверен, отозван или истёк; выпустивший токен больше не владелец и не администратор организации. | Повтор не поможет: проверьте заголовок Authorization или выпустите новый токен. |
| 403 | forbidden | У токена нет нужного скоупа (details.required, details.granted) или в тарифе организации нет нужной функции (details.feature, details.requiredPlan — тариф, где она есть). При записи операции — исчерпан лимит тарифа (details.limit, details.max, details.used) или у выпустившего токен нет права или доступа к счёту и направлению. | Выпустите токен с нужным скоупом, смените тариф или проверьте права выпустившего токен. |
| 403 | read_only | Запись в организации, которая в режиме чтения: подписка не оплачена или на паузе. Чтение при этом работает. | Запись снова станет доступна после оплаты; повторите позже. |
| 404 | not_found | Объекта нет — или он принадлежит другой организации: чужое и несуществующее отвечают одинаково. | Проверьте идентификатор; у оплаты брони — что сама бронь уже передана. |
| 409 | conflict | Пришла старая версия брони (details.currentVersion), та же версия с другими данными или правка оплаты, которая уже в учёте; Idempotency-Key операции, которую создали и потом удалили. | Перечитайте объект (GET) и не отправляйте устаревшее; при изменении брони поднимайте version. |
| 422 | validation_error | Неверные параметры или тело запроса; тело — не JSON. В details — список { path, message } по полям. | Исправьте запрос по details; повтор без исправления даст ту же ошибку. |
| 429 | rate_limited | Превышен лимит частоты запросов токена или организации. | Подождите столько секунд, сколько в заголовке Retry-After, и повторите. |
| 500 | internal_error | Сбой на стороне Aynes. | Повторите позже с паузой. Записи броней и оплат идемпотентны — их повтор безопасен. |
Лимиты частоты
Не больше 120 запросов в минуту на токен и 600 в минуту на организацию — на все её токены вместе. Окно — календарная минута: счётчик обнуляется в начале каждой минуты.
| Заголовок | Что значит |
|---|---|
X-RateLimit-Limit | Лимит токена в минуту |
X-RateLimit-Remaining | Сколько запросов осталось в этой минуте — меньшее из остатков токена и организации |
Retry-After | Только в ответе 429: через сколько секунд повторить |
Заголовки X-RateLimit-* приходят в успешных ответах и в ответе 429. Превышение:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
Retry-After: 17
{"ok":false,"error":{"code":"rate_limited","message":"Слишком много запросов, попробуйте позже"}}Для выгрузки истории идите страницами по 200 записей и делайте паузу по Retry-After; для новых событий подпишитесь на вебхуки вместо частого опроса.
Постраничная выдача
Списки GET /operations, GET /payment-requests и GET /bookings отдаются страницами: page — номер с 1, pageSize — от 1 до 200, по умолчанию 50. В meta — номер и размер страницы, всего записей под фильтры и всего страниц. Справочники отдаются целиком; контрагентов — не больше 500 первых по алфавиту, остальных находит параметр search.
// Node.js 18+: все операции за октябрь
const base = "https://aynes.pro/api/v1";
const headers = { Authorization: `Bearer ${process.env.AYNES_TOKEN}` };
const operations = [];
for (let page = 1; ; page++) {
const url = `${base}/operations?from=2026-10-01&to=2026-10-31&pageSize=200&page=${page}`;
const res = await fetch(url, { headers });
const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
operations.push(...body.data);
if (page >= body.meta.pages) break;
}Пока вы идёте по страницам, в организации могут появиться новые операции, и записи сдвинутся. Для сверки сужайте период или берите новые операции из вебхука operation.created.
Идемпотентность и версии
PUTброни и оплаты брони идемпотентны: ключ — путь (source,externalId,paymentId). Повтор того же тела —200иmeta.changed = false, ничего не задваивается; новая запись —201иmeta.created = true. После таймаута или ответа5xxтакой запрос можно смело повторить.- Бронь несёт
version— число, которое растёт при каждом изменении брони в вашей системе. Версия старше той, что в Aynes, или та же версия с другими данными —409 conflictсdetails.currentVersion. БезversionсравниваетсяupdatedAt(время изменения у вас); без обоих побеждает последний запрос. - Оплату, которая уже проведена в кассу или склеена с выпиской, поменять нельзя (сумма, валюта, способ, вид, комиссия, дата) —
409 conflict;providerиpayoutRefменяются всегда. POST /operationsидемпотентен по заголовкуIdempotency-Key: повтор с тем же ключом —200,meta.repeated = trueи первая операция, вторая не заводится. Ключ живёт у токена бессрочно — берите свой на каждую операцию, например номер документа. Без заголовка повтор создаст вторую операцию.POST /payment-requestsне идемпотентен: повтор создаст вторую заявку. После таймаута проверьтеGET /payment-requests?createdFrom=….
Профиль
get/me
Токен и организация
- Скоуп:
- любой действующий токен
- Функция тарифа:
- «API»
Первый запрос интеграции: проверяет токен и возвращает его скоупы и организацию — базовую валюту, страну и часовой пояс. Нужен любой действующий токен; ключу броней на тарифе без функции «API» метод отвечает 403.
Пример запроса
curl "https://aynes.pro/api/v1/me" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": {
"token": {
"id": "cm2tok8x1a0001d4n7q2k5v9b",
"name": "Выгрузка в 1С",
"scopes": [
"operations:read",
"references:read",
"reports:read"
]
},
"tenant": {
"id": "cm2tnt3p0b0000a1b2c3d4e5f",
"name": "Ала-Тоо Сервис",
"baseCurrency": "KGS",
"country": "KG",
"timezone": "Asia/Bishkek"
}
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
token | object | Токен запроса. Поля: id, name, scopes. |
tenant | object | Организация токена. Поля: id, name, baseCurrency, country, timezone. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
Операции
Операции — факт и план движения денег: приходы, расходы и переводы между своими счетами. Через API их читают (operations:read) и заводят (operations:write) — так же, как форма операции в Aynes.
get/operations
Список операций
- Скоуп:
operations:read- Функция тарифа:
- «API»
Тот же список, что на экране «Операции»: те же фильтры и сортировка. Удалённые операции не отдаются. Сумма — в валюте счёта (amount, currency), эквивалент — в базовой валюте организации по курсу на дату операции (baseAmount, exchangeRate).
type:INCOME— приход,OUTCOME— расход,TRANSFER— перевод между своими счетами (counterAccount— счёт получателя).- Обмен валюты —
TRANSFERмежду счетами разных валют:amountсписано в валюте счёта,counterAmountзачислено в валюте получателя (counterCurrency),counterBaseAmount − baseAmount— курсовая разница в базовой валюте. У обычного перевода эти поляnull. status:ACTUAL— факт,PLANNED— план (ожидаемый платёж).source— откуда операция:MANUAL— введена вручную,BANK_STATEMENT— из выписки,MINIAPP— из мини-приложения Telegram и другие.- Новые операции удобнее получать вебхуком
operation.created, а не опросом.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
from | string (date) | нет | Дата операции с этого дня. День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Формат ГГГГ-ММ-ДД. |
to | string (date) | нет | Дата операции по этот день включительно. День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Формат ГГГГ-ММ-ДД. |
dateBasis | string | нет | По какой дате резать from и to: дата операции или дата начисления (без неё — дата операции). Значения: operation, accrual. По умолчанию operation. |
status | string | нет | План или факт. Значения: PLANNED, ACTUAL. |
type | string | нет | Приход, расход или перевод. Значения: INCOME, OUTCOME, TRANSFER. |
unitId | string | нет | Направление. |
legalEntityId | string | нет | Юрлицо. |
bankAccountId | string | нет | Счёт или касса. |
contractorId | string | нет | Контрагент. |
categoryId | string | нет | Категория. |
projectId | string | нет | Проект. |
directionId | string | нет | Участок работ проекта. |
tag | string | нет | Метка операции. |
noCategory | string | нет | Только операции без категории. Значения: 1, true. |
noUnit | string | нет | Только приходы и расходы без направления. Значения: 1, true. |
search | string | нет | Слова назначения и имени контрагента, сумма, номер документа, ИНН. |
sort | string | нет | Сортировка; сумма — по эквиваленту в базовой валюте. Значения: date, amount, category, contractor, account, status. По умолчанию date. |
dir | string | нет | Направление сортировки. Значения: asc, desc. По умолчанию desc. |
page | integer | нет | Номер страницы. По умолчанию 1. |
pageSize | integer | нет | Записей на странице. По умолчанию 50. Не больше 200. |
Пример запроса
curl -G "https://aynes.pro/api/v1/operations" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-d from=2026-10-01 -d to=2026-10-31 \
-d type=OUTCOME -d status=ACTUAL \
-d page=1 -d pageSize=50Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2opr9e6k0009m1n3p5q7r9s",
"type": "OUTCOME",
"status": "ACTUAL",
"amount": 4500000,
"currency": "KGS",
"exchangeRate": "1",
"baseAmount": 4500000,
"counterAccount": null,
"counterAmount": null,
"counterCurrency": null,
"counterBaseAmount": null,
"operationDate": "2026-10-03T00:00:00.000Z",
"accrualDate": "2026-10-01T00:00:00.000Z",
"description": "Аренда офиса за октябрь 2026",
"source": "BANK_STATEMENT",
"unit": {
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис"
},
"bankAccount": {
"id": "cm2acc9u6e0004y5z7a9b2c4d",
"name": "MBANK, расчётный KGS"
},
"contractor": {
"id": "cm2cnt3y0g0006n7p9q2r4s6t",
"name": "ОсОО «Бизнес Центр Орион»"
},
"category": {
"id": "cm2cat5a2h0007u8w1x3y5z7a",
"name": "Аренда"
},
"project": null,
"tags": [
"офис"
],
"createdAt": "2026-10-03T08:12:44.512Z"
}
],
"meta": {
"page": 1,
"pageSize": 50,
"total": 1,
"pages": 1
}
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
type | string | Значения: INCOME, OUTCOME, TRANSFER. |
status | string | Значения: PLANNED, ACTUAL. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
currency | string | |
exchangeRate | string | Курс к базовой валюте организации, Decimal строкой. |
baseAmount | integer | Эквивалент в базовой валюте организации. |
counterAccount | object | Счёт получателя перевода. Может быть null. Поля: id, name. |
counterAmount | integer | Обмен валюты: сколько зачислено на счёт получателя в его валюте; null — не обмен. Может быть null. |
counterCurrency | string | Обмен валюты: валюта зачисления. Может быть null. |
counterBaseAmount | integer | Обмен валюты: эквивалент зачисленного в базовой валюте; минус baseAmount — курсовая разница. Может быть null. |
operationDate | string (date-time) | ISO 8601. |
accrualDate | string (date-time) | ISO 8601. Может быть null. |
description | string | Может быть null. |
source | string | |
unit | object | Может быть null. Поля: id, name. |
bankAccount | object | Может быть null. Поля: id, name. |
contractor | object | Может быть null. Поля: id, name. |
category | object | Может быть null. Поля: id, name. |
project | object | Может быть null. Поля: id, name. |
tags | array<string> | Метки операции. |
createdAt | string (date-time) | ISO 8601. |
meta.page | integer | Номер страницы, с 1. |
meta.pageSize | integer | Записей на странице. |
meta.total | integer | Всего записей под фильтры. |
meta.pages | integer | Всего страниц. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
post/operations
Создать операцию
- Скоуп:
operations:write- Функция тарифа:
- «API»
Операция заводится от имени того, кто выпустил токен, и с его правами: нужно право «Создавать операции», счёт и направление — из доступных ему. Проверки те же, что у формы операции в Aynes: справочники этой организации, направление у прихода и расхода, у перевода — счёт получателя той же валюты, категория того же типа, счёт не закрыт и не «не учитывать».
- Валюта операции — валюта счёта. Эквивалент в базовой валюте (
baseAmount) считается по курсу справочника на дату операции и потом не пересчитывается. Курса на дату нет —422сdetails[].path = "exchangeRate": передайте курс вexchangeRate. - Лимит операций в месяц по тарифу —
403 forbiddenсdetails.limit = "operations". Организация в режиме чтения —403 read_only. - Чужой или несуществующий счёт, направление, категория, проект или контрагент —
404 not_found. - Подписчикам уходит вебхук
operation.created; в журнале Aynes — «из API» с токеном.
Передавайте заголовок Idempotency-Key — свой у каждой операции (например, номер документа в вашей системе). Повтор с тем же ключом вернёт 200 и первую операцию (meta.repeated = true), вторая не заведётся. Без ключа повтор после таймаута создаст вторую операцию.
Заголовки запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
Idempotency-Key | string | нет | Ключ запроса: до 200 печатных символов ASCII без пробелов, свой у каждой операции. Повтор с тем же ключом — 200 и первая операция (meta.repeated = true), вторая не заводится. До 200 символов. |
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
type | string | да | Приход, расход или перевод между своими счетами. Значения: INCOME, OUTCOME, TRANSFER. |
status | string | нет | Факт или план (ожидаемый платёж). Значения: ACTUAL, PLANNED. По умолчанию ACTUAL. |
amount | integer | да | Сумма в минимальных единицах валюты счёта, больше нуля. |
operationDate | string (date) | да | Дата операции. День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Формат ГГГГ-ММ-ДД. |
accrualDate | string (date) | нет | Дата начисления для «Прибылей и убытков» по начислению; пусто — дата операции. Формат ГГГГ-ММ-ДД. Может быть null. |
bankAccountId | string | да | Счёт или касса — из GET /references/bank-accounts; валюта операции — валюта счёта. |
counterAccountId | string | нет | Счёт получателя — обязателен у перевода, той же валюты. Может быть null. |
unitId | string | нет | Направление — обязательно у прихода и расхода. Может быть null. |
categoryId | string | нет | Категория того же типа, что операция. Может быть null. |
projectId | string | нет | Проект. Может быть null. |
directionId | string | нет | Участок работ проекта. Может быть null. |
contractorId | string | нет | Контрагент. Может быть null. |
description | string | нет | Назначение. До 500 символов. Может быть null. |
tags | array<string> | нет | Метки операции. |
exchangeRate | string | нет | Курс к базовой валюте строкой, например "89.5"; пусто — курс справочника на дату. Курса на дату нет — 422 «укажите курс вручную». Может быть null. |
Пример запроса
curl -X POST "https://aynes.pro/api/v1/operations" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-H "Idempotency-Key: erp-2026-10-03-118" \
-H "Content-Type: application/json" \
-d '{
"type": "OUTCOME",
"status": "ACTUAL",
"amount": 4500000,
"operationDate": "2026-10-03",
"accrualDate": "2026-10-01",
"bankAccountId": "cm2acc9u6e0004y5z7a9b2c4d",
"unitId": "cm2unt5r2c0003h6j8k1m3n5p",
"categoryId": "cm2cat5a2h0007u8w1x3y5z7a",
"contractorId": "cm2cnt3y0g0006n7p9q2r4s6t",
"description": "Аренда офиса за октябрь 2026",
"tags": [
"офис"
]
}'Пример ответа · 200
{
"ok": true,
"data": {
"id": "cm2opr9e6k0009m1n3p5q7r9s",
"type": "OUTCOME",
"status": "ACTUAL",
"amount": 4500000,
"currency": "KGS",
"exchangeRate": "1",
"baseAmount": 4500000,
"counterAccount": null,
"counterAmount": null,
"counterCurrency": null,
"counterBaseAmount": null,
"operationDate": "2026-10-03T00:00:00.000Z",
"accrualDate": "2026-10-01T00:00:00.000Z",
"description": "Аренда офиса за октябрь 2026",
"source": "MANUAL",
"unit": {
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис"
},
"bankAccount": {
"id": "cm2acc9u6e0004y5z7a9b2c4d",
"name": "MBANK, расчётный KGS"
},
"contractor": {
"id": "cm2cnt3y0g0006n7p9q2r4s6t",
"name": "ОсОО «Бизнес Центр Орион»"
},
"category": {
"id": "cm2cat5a2h0007u8w1x3y5z7a",
"name": "Аренда"
},
"project": null,
"tags": [
"офис"
],
"createdAt": "2026-10-03T08:12:44.512Z"
},
"meta": {
"repeated": false
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
type | string | Значения: INCOME, OUTCOME, TRANSFER. |
status | string | Значения: PLANNED, ACTUAL. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
currency | string | |
exchangeRate | string | Курс к базовой валюте организации, Decimal строкой. |
baseAmount | integer | Эквивалент в базовой валюте организации. |
counterAccount | object | Счёт получателя перевода. Может быть null. Поля: id, name. |
counterAmount | integer | Обмен валюты: сколько зачислено на счёт получателя в его валюте; null — не обмен. Может быть null. |
counterCurrency | string | Обмен валюты: валюта зачисления. Может быть null. |
counterBaseAmount | integer | Обмен валюты: эквивалент зачисленного в базовой валюте; минус baseAmount — курсовая разница. Может быть null. |
operationDate | string (date-time) | ISO 8601. |
accrualDate | string (date-time) | ISO 8601. Может быть null. |
description | string | Может быть null. |
source | string | |
unit | object | Может быть null. Поля: id, name. |
bankAccount | object | Может быть null. Поля: id, name. |
contractor | object | Может быть null. Поля: id, name. |
category | object | Может быть null. Поля: id, name. |
project | object | Может быть null. Поля: id, name. |
tags | array<string> | Метки операции. |
createdAt | string (date-time) | ISO 8601. |
meta.repeated | boolean | true — повтор по Idempotency-Key, операция создана раньше. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden, read_only | У токена нет нужного скоупа, тариф без нужной функции или (для записи) организация в режиме чтения |
| 404 | not_found | Счёт, направление, категория, проект или контрагент не найдены в организации |
| 409 | conflict | Операция с этим Idempotency-Key создана и удалена — нужен новый ключ |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
Заявки на оплату
Заявка — просьба оплатить расход: её согласуют по маршруту организации, потом склеивают с операцией оплаты. Статусы: PENDING — на согласовании, APPROVED — согласована, REJECTED — отклонена, PAID — оплачена, CANCELLED — отменена. Черновики (DRAFT) — личная заготовка автора, во внешний API они не попадают.
get/payment-requests
Список заявок на оплату
- Скоуп:
payment-requests:read- Функция тарифа:
- «API»
Заявки всей организации без черновиков, свежие сверху, с ходом согласования и вложениями. approval — маршрут: сколько шагов, чей шаг сейчас (isCurrent) и кто уже решил; null — заявка согласуется в один шаг. Вложения отдаются именем, размером и типом, без самих файлов.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
status | string | нет | Статус заявки; ALL — все, кроме черновиков. Значения: PENDING, APPROVED, REJECTED, PAID, CANCELLED, ALL. По умолчанию ALL. |
unitId | string | нет | Направление. |
createdFrom | string (date) | нет | Созданные с этой даты включительно (UTC). Формат ГГГГ-ММ-ДД. |
createdTo | string (date) | нет | Созданные по эту дату включительно (UTC). Формат ГГГГ-ММ-ДД. |
page | integer | нет | Номер страницы. По умолчанию 1. |
pageSize | integer | нет | Записей на странице. По умолчанию 50. Не больше 200. |
Пример запроса
curl -G "https://aynes.pro/api/v1/payment-requests" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-d status=PENDING -d createdFrom=2026-10-01Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2req1g8m0010t2v4w6x8y1z",
"status": "PENDING",
"amount": 1250000,
"currency": "USD",
"exchangeRate": "87.45",
"baseAmount": 109312500,
"description": "Предоплата за оборудование по счёту № 118",
"dueDate": "2026-10-15T00:00:00.000Z",
"expectedPaidAt": null,
"paidAt": null,
"decisionAt": null,
"rejectionReason": null,
"requester": {
"id": "cm2usr3h9n0011a3b5c7d9e1f",
"name": "Айгуль Сыдыкова"
},
"approver": null,
"unit": {
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис"
},
"category": {
"id": "cm2cat5a2h0007u8w1x3y5z7a",
"name": "Оборудование"
},
"project": {
"id": "cm2prj7c4j0008b9d2f4g6h8k",
"name": "Открытие филиала в Оше"
},
"contractor": {
"id": "cm2cnt4z1h0016p8q1r3s5t7u",
"name": "ОсОО «ТехноСнаб»"
},
"bankAccount": {
"id": "cm2acc9u6e0004y5z7a9b2c4d",
"name": "MBANK, расчётный USD"
},
"matchedOperationId": null,
"hasMatchConflict": false,
"approval": {
"routeId": "cm2rte5k2q0014n5p7q9r2s4t",
"routeName": "Крупные расходы",
"totalSteps": 2,
"currentStep": 2,
"steps": [
{
"order": 1,
"approverRole": "UNIT_HEAD",
"approverName": null,
"decision": "APPROVED",
"decidedAt": "2026-10-06T10:02:11.000Z",
"decidedByName": "Бакыт Осмонов",
"comment": null,
"isCurrent": false
},
{
"order": 2,
"approverRole": null,
"approverName": "Нурлан Абдыкадыров",
"decision": null,
"decidedAt": null,
"decidedByName": null,
"comment": null,
"isCurrent": true
}
]
},
"attachments": [
{
"id": "cm2att6m3r0015u6v8w1x3y5z",
"filename": "schet-118.pdf",
"size": 184320,
"mime": "application/pdf"
}
],
"createdAt": "2026-10-06T09:41:27.330Z",
"updatedAt": "2026-10-06T10:02:11.000Z"
}
],
"meta": {
"page": 1,
"pageSize": 50,
"total": 1,
"pages": 1
}
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
status | string | Значения: PENDING, APPROVED, REJECTED, PAID, CANCELLED. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
currency | string | |
exchangeRate | string | Курс к базовой валюте организации, Decimal строкой. |
baseAmount | integer | Эквивалент в базовой валюте организации. |
description | string | |
dueDate | string (date-time) | ISO 8601. Может быть null. |
expectedPaidAt | string (date-time) | ISO 8601. Может быть null. |
paidAt | string (date-time) | ISO 8601. Может быть null. |
decisionAt | string (date-time) | ISO 8601. Может быть null. |
rejectionReason | string | Может быть null. |
requester | object | Может быть null. Поля: id, name. |
approver | object | Может быть null. Поля: id, name. |
unit | object | Может быть null. Поля: id, name. |
category | object | Может быть null. Поля: id, name. |
project | object | Может быть null. Поля: id, name. |
contractor | object | Может быть null. Поля: id, name. |
bankAccount | object | Может быть null. Поля: id, name. |
matchedOperationId | string | Операция, которой заявка оплачена. Может быть null. |
hasMatchConflict | boolean | |
approval | object | Ход согласования по маршруту; null — заявка согласуется в один шаг. Может быть null. Поля: routeId, routeName, totalSteps, currentStep, steps. |
attachments | array<object> | Поля элемента: id, filename, size, mime. |
createdAt | string (date-time) | ISO 8601. |
updatedAt | string (date-time) | ISO 8601. |
meta.page | integer | Номер страницы, с 1. |
meta.pageSize | integer | Записей на странице. |
meta.total | integer | Всего записей под фильтры. |
meta.pages | integer | Всего страниц. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
post/payment-requests
Создать заявку на оплату
- Скоуп:
payment-requests:write- Функция тарифа:
- «API»
Заявка создаётся от имени того, кто выпустил токен, и сразу уходит на согласование по маршруту организации — согласующие увидят её в Aynes и в Telegram. Справочники проверяются: направление, категория, проект, контрагент и счёт должны быть этой организации, иначе 422.
Метод не идемпотентен: повтор создаст вторую заявку. После таймаута сначала проверьте GET /payment-requests?createdFrom=…, не появилась ли заявка.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
amount | integer | да | Сумма в минимальных единицах валюты заявки, больше нуля. |
currency | string | нет | Код ISO 4217; пусто — валюта счёта, а без счёта — базовая. Может быть null. |
exchangeRate | string | нет | Курс к базовой валюте строкой, например "89.5"; пусто — курс справочника на срок заявки. Может быть null. |
description | string | да | Назначение платежа. До 500 символов. |
unitId | string | да | Направление — из GET /references/units. |
categoryId | string | нет | Категория расхода. Может быть null. |
projectId | string | нет | Проект. Может быть null. |
directionId | string | нет | Участок работ проекта; обязателен, если у проекта участки есть. Может быть null. |
contractorId | string | нет | Получатель платежа. Может быть null. |
bankAccountId | string | нет | Счёт, с которого платить. Может быть null. |
dueDate | string (date) | нет | Срок оплаты: не раньше года назад и не позже трёх лет вперёд. Формат ГГГГ-ММ-ДД. Может быть null. |
payrollEmployeeId | string | нет | Сотрудник для выплаты зарплаты — только у категории с признаком «Зарплата». Может быть null. |
payrollMonth | string | нет | Месяц выплаты зарплаты, «ГГГГ-ММ». Может быть null. |
Пример запроса
curl -X POST "https://aynes.pro/api/v1/payment-requests" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 1250000,
"currency": "USD",
"description": "Предоплата за оборудование по счёту № 118",
"unitId": "cm2unt5r2c0003h6j8k1m3n5p",
"categoryId": "cm2cat5a2h0007u8w1x3y5z7a",
"projectId": "cm2prj7c4j0008b9d2f4g6h8k",
"contractorId": "cm2cnt4z1h0016p8q1r3s5t7u",
"bankAccountId": "cm2acc9u6e0004y5z7a9b2c4d",
"dueDate": "2026-10-15"
}'Пример ответа · 201
{
"ok": true,
"data": {
"id": "cm2req1g8m0010t2v4w6x8y1z",
"status": "PENDING",
"amount": 1250000,
"currency": "USD",
"baseAmount": 109312500,
"dueDate": "2026-10-15T00:00:00.000Z",
"description": "Предоплата за оборудование по счёту № 118",
"createdAt": "2026-10-08T07:30:12.004Z"
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
status | string | Значения: PENDING. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
currency | string | |
baseAmount | integer | Эквивалент в базовой валюте организации. |
dueDate | string (date-time) | ISO 8601. Может быть null. |
description | string | |
createdAt | string (date-time) | ISO 8601. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden, read_only | У токена нет нужного скоупа, тариф без нужной функции или (для записи) организация в режиме чтения |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/payment-requests/{id}
Одна заявка на оплату
- Скоуп:
payment-requests:read- Функция тарифа:
- «API»
Одна заявка в той же форме, что в списке. Её перечитывают после вебхуков payment_request.status_changed и payment_request.updated: в теле события — только идентификатор и что изменилось. Чужая заявка и черновик отвечают 404.
Параметры пути
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
id | string | да | Идентификатор заявки. |
Пример запроса
curl "https://aynes.pro/api/v1/payment-requests/cm2req1g8m0010t2v4w6x8y1z" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": {
"id": "cm2req1g8m0010t2v4w6x8y1z",
"status": "PENDING",
"amount": 1250000,
"currency": "USD",
"exchangeRate": "87.45",
"baseAmount": 109312500,
"description": "Предоплата за оборудование по счёту № 118",
"dueDate": "2026-10-15T00:00:00.000Z",
"expectedPaidAt": null,
"paidAt": null,
"decisionAt": null,
"rejectionReason": null,
"requester": {
"id": "cm2usr3h9n0011a3b5c7d9e1f",
"name": "Айгуль Сыдыкова"
},
"approver": null,
"unit": {
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис"
},
"category": {
"id": "cm2cat5a2h0007u8w1x3y5z7a",
"name": "Оборудование"
},
"project": {
"id": "cm2prj7c4j0008b9d2f4g6h8k",
"name": "Открытие филиала в Оше"
},
"contractor": {
"id": "cm2cnt4z1h0016p8q1r3s5t7u",
"name": "ОсОО «ТехноСнаб»"
},
"bankAccount": {
"id": "cm2acc9u6e0004y5z7a9b2c4d",
"name": "MBANK, расчётный USD"
},
"matchedOperationId": null,
"hasMatchConflict": false,
"approval": {
"routeId": "cm2rte5k2q0014n5p7q9r2s4t",
"routeName": "Крупные расходы",
"totalSteps": 2,
"currentStep": 2,
"steps": [
{
"order": 1,
"approverRole": "UNIT_HEAD",
"approverName": null,
"decision": "APPROVED",
"decidedAt": "2026-10-06T10:02:11.000Z",
"decidedByName": "Бакыт Осмонов",
"comment": null,
"isCurrent": false
},
{
"order": 2,
"approverRole": null,
"approverName": "Нурлан Абдыкадыров",
"decision": null,
"decidedAt": null,
"decidedByName": null,
"comment": null,
"isCurrent": true
}
]
},
"attachments": [
{
"id": "cm2att6m3r0015u6v8w1x3y5z",
"filename": "schet-118.pdf",
"size": 184320,
"mime": "application/pdf"
}
],
"createdAt": "2026-10-06T09:41:27.330Z",
"updatedAt": "2026-10-06T10:02:11.000Z"
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
status | string | Значения: PENDING, APPROVED, REJECTED, PAID, CANCELLED. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
currency | string | |
exchangeRate | string | Курс к базовой валюте организации, Decimal строкой. |
baseAmount | integer | Эквивалент в базовой валюте организации. |
description | string | |
dueDate | string (date-time) | ISO 8601. Может быть null. |
expectedPaidAt | string (date-time) | ISO 8601. Может быть null. |
paidAt | string (date-time) | ISO 8601. Может быть null. |
decisionAt | string (date-time) | ISO 8601. Может быть null. |
rejectionReason | string | Может быть null. |
requester | object | Может быть null. Поля: id, name. |
approver | object | Может быть null. Поля: id, name. |
unit | object | Может быть null. Поля: id, name. |
category | object | Может быть null. Поля: id, name. |
project | object | Может быть null. Поля: id, name. |
contractor | object | Может быть null. Поля: id, name. |
bankAccount | object | Может быть null. Поля: id, name. |
matchedOperationId | string | Операция, которой заявка оплачена. Может быть null. |
hasMatchConflict | boolean | |
approval | object | Ход согласования по маршруту; null — заявка согласуется в один шаг. Может быть null. Поля: routeId, routeName, totalSteps, currentStep, steps. |
attachments | array<object> | Поля элемента: id, filename, size, mime. |
createdAt | string (date-time) | ISO 8601. |
updatedAt | string (date-time) | ISO 8601. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 404 | not_found | Заявка не найдена |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
Справочники
Справочники отдаются целиком, без страниц: идентификаторы из них нужны фильтрам операций и телу заявки. Скоуп у всех — references:read.
get/references/units
Направления
- Скоуп:
references:read- Функция тарифа:
- «API»
Направление — направление учёта организации (филиал, магазин, лагерь); у каждого — юрлицо. Обязателен в заявке на оплату (unitId). Отдаются только действующие направления.
Пример запроса
curl "https://aynes.pro/api/v1/references/units" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис",
"legalEntity": {
"id": "cm2lgl7s4d0002q4r6t8v1w3x",
"name": "ОсОО «Ала-Тоо Сервис»"
}
}
]
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
name | string | |
legalEntity | object | Может быть null. Поля: id, name. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/references/legal-entities
Юрлица
- Скоуп:
references:read- Функция тарифа:
- «API»
Пример запроса
curl "https://aynes.pro/api/v1/references/legal-entities" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2lgl7s4d0002q4r6t8v1w3x",
"name": "ОсОО «Ала-Тоо Сервис»",
"inn": "02512201810123"
}
]
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
name | string | |
inn | string | Может быть null. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/references/categories
Категории
- Скоуп:
references:read- Функция тарифа:
- «API»
Действующие категории прихода и расхода с деревом (parentId) и разделом ПиУ. Служебные категории (isInternal: переводы в копилки, депозиты) не входят в обороты ДДС.
Пример запроса
curl "https://aynes.pro/api/v1/references/categories" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2cat6b3j0017w9x2y4z6a8b",
"name": "Выручка от услуг",
"type": "INCOME",
"parentId": null,
"isInternal": false,
"pnlSection": {
"id": "cm2sec8d5k0018x1y3z5a7b9c",
"name": "Выручка"
}
},
{
"id": "cm2cat5a2h0007u8w1x3y5z7a",
"name": "Аренда",
"type": "OUTCOME",
"parentId": null,
"isInternal": false,
"pnlSection": null
}
]
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
name | string | |
type | string | Значения: INCOME, OUTCOME. |
parentId | string | Родительская категория. Может быть null. |
isInternal | boolean | Служебная категория: переводы в копилки, депозиты. |
pnlSection | object | Раздел ПиУ. Может быть null. Поля: id, name. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/references/contractors
Контрагенты
- Скоуп:
references:read- Функция тарифа:
- «API»
Не больше 500 первых по алфавиту — ищите параметром search.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
search | string | нет | Часть названия, без учёта регистра. |
Пример запроса
curl -G "https://aynes.pro/api/v1/references/contractors" \
-H "Authorization: Bearer $AYNES_TOKEN" \
--data-urlencode "search=Орион"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2cnt3y0g0006n7p9q2r4s6t",
"name": "ОсОО «Бизнес Центр Орион»",
"inn": "01408201610045",
"kind": "LEGAL_ENTITY"
}
]
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
name | string | |
inn | string | Может быть null. |
kind | string | Юрлицо, ИП или физлицо. Значения: LEGAL_ENTITY, INDIVIDUAL_ENTREPRENEUR, INDIVIDUAL. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/references/bank-accounts
Счета и кассы
- Скоуп:
references:read- Функция тарифа:
- «API»
Действующие счета и кассы.
Пример запроса
curl "https://aynes.pro/api/v1/references/bank-accounts" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2acc9u6e0004y5z7a9b2c4d",
"name": "MBANK, расчётный KGS",
"currency": "KGS",
"kind": "BANK",
"legalEntity": {
"id": "cm2lgl7s4d0002q4r6t8v1w3x",
"name": "ОсОО «Ала-Тоо Сервис»"
}
},
{
"id": "cm2cas1w8f0005e6g8h1j3k5m",
"name": "Касса офиса",
"currency": "KGS",
"kind": "CASH",
"legalEntity": {
"id": "cm2lgl7s4d0002q4r6t8v1w3x",
"name": "ОсОО «Ала-Тоо Сервис»"
}
}
]
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
name | string | |
currency | string | |
kind | string | Банковский счёт, касса или депозит. Значения: BANK, CASH, DEPOSIT. |
legalEntity | object | Может быть null. Поля: id, name. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/references/projects
Проекты
- Скоуп:
references:read- Функция тарифа:
- «API»
Проекты не в архиве.
Пример запроса
curl "https://aynes.pro/api/v1/references/projects" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2prj7c4j0008b9d2f4g6h8k",
"name": "Открытие филиала в Оше",
"status": "ACTIVE",
"startDate": "2026-09-01T00:00:00.000Z",
"endDate": "2026-12-20T00:00:00.000Z",
"unit": {
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис"
},
"client": null
}
]
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
name | string | |
status | string | Значения: PLANNED, ACTIVE, ON_HOLD, FINISHED. |
startDate | string (date-time) | ISO 8601. Может быть null. |
endDate | string (date-time) | ISO 8601. Может быть null. |
unit | object | Может быть null. Поля: id, name. |
client | object | Клиент проекта — контрагент. Может быть null. Поля: id, name. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
Отчёты
Отчёты считаются тем же сервисом, что экраны Aynes, — числа совпадают до тыйына. Суммы — в минимальных единицах базовой валюты организации; дни и месяцы — в часовом поясе организации (tenant.timezone в GET /me).
get/reports/cashflow
ДДС за период
- Скоуп:
reports:read- Функция тарифа:
- «API»
Движение денег за период кассовым методом: остатки на начало и конец, обороты по категориям и по направлениям, юрлицам или счетам. Переводы между своими счетами и служебные категории в обороты не входят — их сумма в excludedNet, так что всегда opening + totalIncome − totalExpense + excludedNet = closing.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
dateFrom | string (date) | да | День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Начало не позже конца, период не длиннее 10 лет. Формат ГГГГ-ММ-ДД. |
dateTo | string (date) | да | День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Начало не позже конца, период не длиннее 10 лет. Формат ГГГГ-ММ-ДД. |
groupBy | string | нет | Разрез byGroup. Значения: unit, legalEntity, bankAccount. По умолчанию unit. |
unitId | string | нет | Только это направление. |
legalEntityId | string | нет | Только это юрлицо. |
bankAccountId | string | нет | Только этот счёт. |
includePlanned | string | нет | Учесть и плановые операции; без него — только факт. Значения: 1, true. |
Пример запроса
curl -G "https://aynes.pro/api/v1/reports/cashflow" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-d dateFrom=2026-09-01 -d dateTo=2026-09-30 -d groupBy=unitПример ответа · 200
{
"ok": true,
"data": {
"dateFrom": "2026-09-01T00:00:00.000Z",
"dateTo": "2026-09-30T00:00:00.000Z",
"groupBy": "unit",
"opening": 152000000,
"closing": 171850000,
"totalIncome": 98400000,
"totalExpense": 76550000,
"excludedNet": -2000000,
"byCategory": [
{
"categoryId": "cm2cat6b3j0017w9x2y4z6a8b",
"categoryName": "Выручка от услуг",
"income": 98400000,
"expense": 0
},
{
"categoryId": "cm2cat5a2h0007u8w1x3y5z7a",
"categoryName": "Аренда",
"income": 0,
"expense": 4500000
}
],
"byGroup": [
{
"id": "cm2unt5r2c0003h6j8k1m3n5p",
"name": "Бишкек, офис",
"income": 98400000,
"expense": 76550000,
"opening": null,
"closing": null
}
]
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
dateFrom | string (date-time) | Первый день периода — полночь UTC. ISO 8601. |
dateTo | string (date-time) | Последний день периода — полночь UTC. ISO 8601. |
groupBy | string | Значения: unit, legalEntity, bankAccount. |
opening | integer | Остаток счетов на начало периода. |
closing | integer | Остаток счетов на конец периода. |
totalIncome | integer | Поступления за период (без переводов между своими счетами). |
totalExpense | integer | Выплаты за период. |
excludedNet | integer | Движения вне оборотов отчёта (переводы, служебные категории): opening + totalIncome − totalExpense + excludedNet = closing. |
byCategory | array<object> | Обороты по категориям. Поля элемента: categoryId, categoryName, income, expense. |
byGroup | array<object> | Обороты и остатки по направлениям, юрлицам или счетам (groupBy). Поля элемента: id, name, income, expense, opening, closing. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/reports/pnl
ПиУ за период
- Скоуп:
reports:read- Функция тарифа:
- «API»
Прибыли и убытки по разделам и категориям, помесячно. По умолчанию — по начислению (accrual): операция попадает в месяц своей даты начисления, а без неё — даты операции; cash — строго по дате операции. Выплаты собственнику идут после прибыли и в расходы не входят.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
dateFrom | string (date) | да | День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Начало не позже конца, период не длиннее 10 лет. Формат ГГГГ-ММ-ДД. |
dateTo | string (date) | да | День ГГГГ-ММ-ДД с 2000 года и не дальше пяти лет вперёд; иначе 422 validation_error. Начало не позже конца, период не длиннее 10 лет. Формат ГГГГ-ММ-ДД. |
method | string | нет | accrual — по дате начисления (без неё — по дате операции), cash — по дате операции. Значения: cash, accrual. По умолчанию accrual. |
unitId | string | нет | Только это направление. |
legalEntityId | string | нет | Только это юрлицо. |
projectId | string | нет | Только этот проект. |
Пример запроса
curl -G "https://aynes.pro/api/v1/reports/pnl" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-d dateFrom=2026-07-01 -d dateTo=2026-09-30 -d method=accrualПример ответа · 200
{
"ok": true,
"data": {
"dateFrom": "2026-07-01T00:00:00.000Z",
"dateTo": "2026-09-30T00:00:00.000Z",
"method": "accrual",
"months": [
{
"year": 2026,
"month": 7,
"key": "2026-07"
},
{
"year": 2026,
"month": 8,
"key": "2026-08"
},
{
"year": 2026,
"month": 9,
"key": "2026-09"
}
],
"sections": [
{
"sectionId": "cm2sec8d5k0018x1y3z5a7b9c",
"name": "Выручка",
"type": "INCOME",
"order": 1,
"lines": [
{
"categoryId": "cm2cat6b3j0017w9x2y4z6a8b",
"categoryName": "Выручка от услуг",
"type": "INCOME",
"byMonth": {
"2026-07": 81000000,
"2026-08": 90500000,
"2026-09": 98400000
},
"total": 269900000,
"previousTotal": null
}
],
"totalsByMonth": {
"2026-07": 81000000,
"2026-08": 90500000,
"2026-09": 98400000
},
"total": 269900000,
"previousTotal": null
}
],
"incomeByMonth": {
"2026-07": 81000000,
"2026-08": 90500000,
"2026-09": 98400000
},
"expenseByMonth": {
"2026-07": 70200000,
"2026-08": 71900000,
"2026-09": 76550000
},
"profitByMonth": {
"2026-07": 10800000,
"2026-08": 18600000,
"2026-09": 21850000
},
"totalIncome": 269900000,
"totalExpense": 218650000,
"totalProfit": 51250000,
"withdrawalsByMonth": {
"2026-07": 0,
"2026-08": 10000000,
"2026-09": 0
},
"totalWithdrawals": 10000000,
"retainedByMonth": {
"2026-07": 10800000,
"2026-08": 8600000,
"2026-09": 21850000
},
"totalRetained": 41250000,
"comparison": null
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
dateFrom | string (date-time) | Первый день периода — полночь UTC. ISO 8601. |
dateTo | string (date-time) | Последний день периода — полночь UTC. ISO 8601. |
method | string | Значения: cash, accrual. |
months | array<object> | Месяцы периода. Поля элемента: year, month, key. |
sections | array<object> | Разделы ПиУ со строками категорий. Поля элемента: sectionId, name, type, order, lines, totalsByMonth, total, previousTotal. |
incomeByMonth | object | Сумма по месяцам: ключ — «ГГГГ-ММ». |
expenseByMonth | object | Сумма по месяцам: ключ — «ГГГГ-ММ». |
profitByMonth | object | Сумма по месяцам: ключ — «ГГГГ-ММ». |
totalIncome | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
totalExpense | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
totalProfit | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
withdrawalsByMonth | object | Сумма по месяцам: ключ — «ГГГГ-ММ». |
totalWithdrawals | integer | Выплаты собственнику — после прибыли, не в расходах. |
retainedByMonth | object | Сумма по месяцам: ключ — «ГГГГ-ММ». |
totalRetained | integer | Прибыль минус выплаты собственнику. |
comparison | object | Сравнение с прошлым периодом — во внешнем API всегда null. Может быть null. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
Брони
Методы для систем бронирования (Voyz и другие): бронь и оплаты по ней передаются в Aynes, а Aynes ведёт их учёт — выручка датой выезда, предоплата до выезда — аванс гостя, наличная оплата — сразу приход в кассу, безналичная ждёт строку банковской выписки и склеивается человеком.
- Бронь определяется парой
source+externalId: код вашей системы (латиница, цифры,_ . -, до 40 символов) и номер брони в ней (без пробелов и/, до 120 символов). Кодmanualзанят бронями, введёнными в Aynes вручную. - Скоупы —
bookings:readиbookings:write, функция тарифа — «Брони». Ключ для системы бронирования выпускается на экране «Брони → Настройки броней». - Все записи идемпотентны: повтор того же запроса ничего не задваивает (см. «Идемпотентность и версии»).
get/bookings
Брони, принятые Aynes (сверка)
- Скоуп:
bookings:read- Функция тарифа:
- «Брони»; общему токену — ещё и «API»
Что Aynes принял — для сверки с вашей системой. Порядок — по времени изменения в Aynes; updatedSince отдаёт изменённое после прошлой сверки. reconciliation у брони: no_payments — оплат нет, awaiting — есть оплаты, ждущие выписку или кассу, reconciled — все оплаты в учёте.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
source | string | нет | Код системы бронирования; manual — брони, введённые вручную. |
status | string | нет | Статус брони. Значения: pending, confirmed, checked_in, checked_out, cancelled, no_show. |
updatedSince | string (date-time) | нет | Изменённые в Aynes с этого момента (ISO 8601 с поясом). ISO 8601. |
page | integer | нет | Номер страницы. По умолчанию 1. |
pageSize | integer | нет | Записей на странице. По умолчанию 50. Не больше 200. |
Пример запроса
curl -G "https://aynes.pro/api/v1/bookings" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-d source=voyz \
--data-urlencode "updatedSince=2027-06-01T00:00:00+06:00"Пример ответа · 200
{
"ok": true,
"data": [
{
"id": "cm2bkg8p5t0019z2a4b6c8d1e",
"source": "voyz",
"externalId": "B-2027-0714",
"version": 7,
"updatedAtSource": "2027-05-30T12:00:00.000Z",
"status": "confirmed",
"unit": {
"id": "cm2unt6s3d0013j7k9m2n4p6q",
"name": "Сон-Куль, юрточный лагерь"
},
"propertyRef": "camp-son-kul",
"unitRef": "yurt-3",
"categoryRef": "yurt",
"channel": "instagram",
"checkIn": "2027-07-14",
"checkOut": "2027-07-17",
"guests": 2,
"guestName": "Айгерим",
"currency": "KGS",
"total": 1800000,
"exchangeRate": "1",
"baseAmount": 1800000,
"channelCommission": 0,
"nonRefundablePrepayment": true,
"nonRefundableAmount": null,
"note": "Конная прогулка 15.07",
"cancelledAt": null,
"paid": 900000,
"refunded": 0,
"reconciliation": "awaiting",
"payments": [
{
"id": "cm2pay9q6u0020f3g5h7j9k2m",
"externalId": "P-1",
"kind": "prepayment",
"method": "qr",
"provider": "gopay",
"amount": 900000,
"fee": 18000,
"currency": "KGS",
"exchangeRate": "1",
"baseAmount": 900000,
"paidAt": "2027-06-01T04:21:00.000Z",
"payoutRef": "gopay-payout-2027-06-02",
"status": "awaiting_statement",
"operationId": null,
"linkedAt": null
}
],
"createdAt": "2027-05-30T12:00:03.118Z",
"updatedAt": "2027-06-01T04:21:05.402Z"
}
],
"meta": {
"page": 1,
"pageSize": 50,
"total": 1,
"pages": 1
}
}Поля ответа
data — массив; поля элемента:
| Поле | Тип | Описание |
|---|---|---|
id | string | |
source | string | |
externalId | string | |
version | integer | Может быть null. |
updatedAtSource | string (date-time) | ISO 8601. Может быть null. |
status | string | Значения: pending, confirmed, checked_in, checked_out, cancelled, no_show. |
unit | object | Может быть null. Поля: id, name. |
propertyRef | string | Может быть null. |
unitRef | string | Может быть null. |
categoryRef | string | Может быть null. |
channel | string | Может быть null. |
checkIn | string (date) | Формат ГГГГ-ММ-ДД. |
checkOut | string (date) | Формат ГГГГ-ММ-ДД. |
guests | integer | Может быть null. |
guestName | string | Может быть null. |
currency | string | |
total | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
exchangeRate | string | |
baseAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
channelCommission | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
nonRefundablePrepayment | boolean | |
nonRefundableAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). Может быть null. |
note | string | Может быть null. |
cancelledAt | string (date-time) | ISO 8601. Может быть null. |
paid | integer | Принятые оплаты в валюте брони (без отменённых). |
refunded | integer | Возвраты в валюте брони. |
reconciliation | string | Значения: no_payments, awaiting, reconciled. |
payments | array<BookingPayment> | |
createdAt | string (date-time) | ISO 8601. |
updatedAt | string (date-time) | ISO 8601. |
meta.page | integer | Номер страницы, с 1. |
meta.pageSize | integer | Записей на странице. |
meta.total | integer | Всего записей под фильтры. |
meta.pages | integer | Всего страниц. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/bookings/{source}/{externalId}
Одна бронь с оплатами
- Скоуп:
bookings:read- Функция тарифа:
- «Брони»; общему токену — ещё и «API»
Чужая и несуществующая — 404.
Параметры пути
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
source | string | да | Код системы: voyz, booking_com, ostrovok… Код manual занят бронями, введёнными вручную в Aynes (D-208): запись с ним — 422. |
externalId | string | да | Номер брони в системе. |
Пример запроса
curl "https://aynes.pro/api/v1/bookings/voyz/B-2027-0714" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": {
"id": "cm2bkg8p5t0019z2a4b6c8d1e",
"source": "voyz",
"externalId": "B-2027-0714",
"version": 7,
"updatedAtSource": "2027-05-30T12:00:00.000Z",
"status": "confirmed",
"unit": {
"id": "cm2unt6s3d0013j7k9m2n4p6q",
"name": "Сон-Куль, юрточный лагерь"
},
"propertyRef": "camp-son-kul",
"unitRef": "yurt-3",
"categoryRef": "yurt",
"channel": "instagram",
"checkIn": "2027-07-14",
"checkOut": "2027-07-17",
"guests": 2,
"guestName": "Айгерим",
"currency": "KGS",
"total": 1800000,
"exchangeRate": "1",
"baseAmount": 1800000,
"channelCommission": 0,
"nonRefundablePrepayment": true,
"nonRefundableAmount": null,
"note": "Конная прогулка 15.07",
"cancelledAt": null,
"paid": 900000,
"refunded": 0,
"reconciliation": "awaiting",
"payments": [
{
"id": "cm2pay9q6u0020f3g5h7j9k2m",
"externalId": "P-1",
"kind": "prepayment",
"method": "qr",
"provider": "gopay",
"amount": 900000,
"fee": 18000,
"currency": "KGS",
"exchangeRate": "1",
"baseAmount": 900000,
"paidAt": "2027-06-01T04:21:00.000Z",
"payoutRef": "gopay-payout-2027-06-02",
"status": "awaiting_statement",
"operationId": null,
"linkedAt": null
}
],
"createdAt": "2027-05-30T12:00:03.118Z",
"updatedAt": "2027-06-01T04:21:05.402Z"
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
source | string | |
externalId | string | |
version | integer | Может быть null. |
updatedAtSource | string (date-time) | ISO 8601. Может быть null. |
status | string | Значения: pending, confirmed, checked_in, checked_out, cancelled, no_show. |
unit | object | Может быть null. Поля: id, name. |
propertyRef | string | Может быть null. |
unitRef | string | Может быть null. |
categoryRef | string | Может быть null. |
channel | string | Может быть null. |
checkIn | string (date) | Формат ГГГГ-ММ-ДД. |
checkOut | string (date) | Формат ГГГГ-ММ-ДД. |
guests | integer | Может быть null. |
guestName | string | Может быть null. |
currency | string | |
total | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
exchangeRate | string | |
baseAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
channelCommission | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
nonRefundablePrepayment | boolean | |
nonRefundableAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). Может быть null. |
note | string | Может быть null. |
cancelledAt | string (date-time) | ISO 8601. Может быть null. |
paid | integer | Принятые оплаты в валюте брони (без отменённых). |
refunded | integer | Возвраты в валюте брони. |
reconciliation | string | Значения: no_payments, awaiting, reconciled. |
payments | array<BookingPayment> | |
createdAt | string (date-time) | ISO 8601. |
updatedAt | string (date-time) | ISO 8601. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 404 | not_found | Бронь не найдена |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
put/bookings/{source}/{externalId}
Создать или обновить бронь (идемпотентно)
- Скоуп:
bookings:write- Функция тарифа:
- «Брони»; общему токену — ещё и «API»
Бронь передаётся целиком при каждом изменении: создании, подтверждении, переносе дат, заезде, выезде, отмене.
status:pending— ждёт подтверждения,confirmed— подтверждена,checked_in— гость заехал,checked_out— выехал,cancelled— отменена,no_show— гость не приехал.versionрастёт при каждом изменении брони у вас. Старее той, что в Aynes, —409 conflictсdetails.currentVersion; та же версия с другими данными — тоже409. Без версии сравниваетсяupdatedAt; без обоих — побеждает последний запрос.- Выручка признаётся всей суммой датой выезда; предоплата до выезда — аванс гостя. Смена выезда, статуса или отмены переносит дату начисления уже проведённого; проведённое по курсу не пересчитывается.
guestName— по желанию; телефон и документы гостя не передаются.propertyRef— ваш объект (лагерь, гостевой дом): в Aynes он появляется сам с первой брони, направление ему выбирают в «Настройках броней».
Параметры пути
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
source | string | да | Код системы: voyz, booking_com, ostrovok… Код manual занят бронями, введёнными вручную в Aynes (D-208): запись с ним — 422. |
externalId | string | да | Номер брони в системе. |
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
version | integer | нет | Растёт при каждом изменении брони в источнике; старая версия — 409 conflict. Может быть null. |
updatedAt | string (date-time) | нет | Время изменения в источнике — если версии нет. ISO 8601. Может быть null. |
status | string | да | Значения: pending, confirmed, checked_in, checked_out, cancelled, no_show. |
propertyRef | string | нет | Объект (лагерь, гостевой дом) — сопоставляется с направлением Aynes в настройках броней. Может быть null. |
unitRef | string | нет | Может быть null. |
categoryRef | string | нет | Может быть null. |
channel | string | нет | Может быть null. |
checkIn | string (date) | да | Формат ГГГГ-ММ-ДД. |
checkOut | string (date) | да | Формат ГГГГ-ММ-ДД. |
guests | integer | нет | Может быть null. |
guestName | string | нет | По желанию; телефон и документы не передаются. Может быть null. |
currency | string | да | |
total | integer | да | Сумма в минимальных единицах валюты (тыйыны, копейки). |
channelCommission | integer | нет | Сумма в минимальных единицах валюты (тыйыны, копейки). |
nonRefundablePrepayment | boolean | нет | |
nonRefundableAmount | integer | нет | Сумма в минимальных единицах валюты (тыйыны, копейки). Может быть null. |
note | string | нет | До 500 символов. Может быть null. |
cancelledAt | string (date-time) | нет | Когда бронь отменили; без него — момент, когда отмена пришла. ISO 8601. Может быть null. |
Пример запроса
curl -X PUT "https://aynes.pro/api/v1/bookings/voyz/B-2027-0714" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"version": 7,
"updatedAt": "2027-05-30T18:00:00+06:00",
"status": "confirmed",
"propertyRef": "camp-son-kul",
"unitRef": "yurt-3",
"categoryRef": "yurt",
"channel": "instagram",
"checkIn": "2027-07-14",
"checkOut": "2027-07-17",
"guests": 2,
"guestName": "Айгерим",
"currency": "KGS",
"total": 1800000,
"channelCommission": 0,
"nonRefundablePrepayment": true,
"note": "Конная прогулка 15.07"
}'Пример ответа · 200
{
"ok": true,
"data": {
"id": "cm2bkg8p5t0019z2a4b6c8d1e",
"source": "voyz",
"externalId": "B-2027-0714",
"version": 7,
"updatedAtSource": "2027-05-30T12:00:00.000Z",
"status": "confirmed",
"unit": {
"id": "cm2unt6s3d0013j7k9m2n4p6q",
"name": "Сон-Куль, юрточный лагерь"
},
"propertyRef": "camp-son-kul",
"unitRef": "yurt-3",
"categoryRef": "yurt",
"channel": "instagram",
"checkIn": "2027-07-14",
"checkOut": "2027-07-17",
"guests": 2,
"guestName": "Айгерим",
"currency": "KGS",
"total": 1800000,
"exchangeRate": "1",
"baseAmount": 1800000,
"channelCommission": 0,
"nonRefundablePrepayment": true,
"nonRefundableAmount": null,
"note": "Конная прогулка 15.07",
"cancelledAt": null,
"paid": 0,
"refunded": 0,
"reconciliation": "no_payments",
"payments": [],
"createdAt": "2027-05-30T12:00:03.118Z",
"updatedAt": "2027-06-01T04:21:05.402Z"
},
"meta": {
"created": true,
"changed": true
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
source | string | |
externalId | string | |
version | integer | Может быть null. |
updatedAtSource | string (date-time) | ISO 8601. Может быть null. |
status | string | Значения: pending, confirmed, checked_in, checked_out, cancelled, no_show. |
unit | object | Может быть null. Поля: id, name. |
propertyRef | string | Может быть null. |
unitRef | string | Может быть null. |
categoryRef | string | Может быть null. |
channel | string | Может быть null. |
checkIn | string (date) | Формат ГГГГ-ММ-ДД. |
checkOut | string (date) | Формат ГГГГ-ММ-ДД. |
guests | integer | Может быть null. |
guestName | string | Может быть null. |
currency | string | |
total | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
exchangeRate | string | |
baseAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
channelCommission | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
nonRefundablePrepayment | boolean | |
nonRefundableAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). Может быть null. |
note | string | Может быть null. |
cancelledAt | string (date-time) | ISO 8601. Может быть null. |
paid | integer | Принятые оплаты в валюте брони (без отменённых). |
refunded | integer | Возвраты в валюте брони. |
reconciliation | string | Значения: no_payments, awaiting, reconciled. |
payments | array<BookingPayment> | |
createdAt | string (date-time) | ISO 8601. |
updatedAt | string (date-time) | ISO 8601. |
meta.created | boolean | Запись создана этим запросом. |
meta.changed | boolean | Запрос что-то изменил; повтор того же тела — false. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden, read_only | У токена нет нужного скоупа, тариф без нужной функции или (для записи) организация в режиме чтения |
| 409 | conflict | Старая версия брони |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
get/bookings/{source}/{externalId}/payments/{paymentId}
Одна оплата брони
- Скоуп:
bookings:read- Функция тарифа:
- «Брони»; общему токену — ещё и «API»
Одна оплата и её состояние: awaiting_statement — безналичная, ждёт строку выписки; awaiting_cash_account — наличная, касса не выбрана или в другой валюте; matched — склеена с выпиской; posted — проведена в кассу; cancelled — отменена.
Параметры пути
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
source | string | да | Код системы: voyz, booking_com, ostrovok… Код manual занят бронями, введёнными вручную в Aynes (D-208): запись с ним — 422. |
externalId | string | да | Номер брони в системе. |
paymentId | string | да | Номер оплаты в системе бронирования. |
Пример запроса
curl "https://aynes.pro/api/v1/bookings/voyz/B-2027-0714/payments/P-1" \
-H "Authorization: Bearer $AYNES_TOKEN"Пример ответа · 200
{
"ok": true,
"data": {
"id": "cm2pay9q6u0020f3g5h7j9k2m",
"externalId": "P-1",
"kind": "prepayment",
"method": "qr",
"provider": "gopay",
"amount": 900000,
"fee": 18000,
"currency": "KGS",
"exchangeRate": "1",
"baseAmount": 900000,
"paidAt": "2027-06-01T04:21:00.000Z",
"payoutRef": "gopay-payout-2027-06-02",
"status": "awaiting_statement",
"operationId": null,
"linkedAt": null
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
externalId | string | Номер оплаты в системе бронирования. |
kind | string | Значения: prepayment, payment, refund. |
method | string | Значения: qr, card, transfer, cash, ota. |
provider | string | Может быть null. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
fee | integer | Комиссия, удержанная из этой оплаты: на счёт пришло amount − fee. |
currency | string | |
exchangeRate | string | |
baseAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
paidAt | string (date-time) | ISO 8601. |
payoutRef | string | Номер выплаты пачкой у провайдера. Может быть null. |
status | string | awaiting_statement — безналичная, ждёт строку выписки; awaiting_cash_account — наличная, касса не выбрана; matched — склеена с выпиской; posted — проведена в кассу; cancelled — отменена. Значения: awaiting_statement, awaiting_cash_account, matched, posted, cancelled. |
operationId | string | Операция Aynes, которой проведена оплата. Может быть null. |
linkedAt | string (date-time) | ISO 8601. Может быть null. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden | У токена нет нужного скоупа или тариф без нужной функции |
| 404 | not_found | Оплата не найдена |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
put/bookings/{source}/{externalId}/payments/{paymentId}
Оплата по брони (идемпотентно по номеру оплаты)
- Скоуп:
bookings:write- Функция тарифа:
- «Брони»; общему токену — ещё и «API»
paymentId— номер оплаты у вас: повтор с тем же номером обновляет, а не задваивает. Бронь должна быть передана раньше, иначе404.- Наличная (
method = cash) сразу становится приходом в кассу из «Настроек броней»; возврат наличными — расходом из неё же. - Безналичная (
qr,card,transfer,ota) операций не создаёт: деньги придут банковской выпиской, и человек в Aynes склеит оплату со строкой выписки — так деньги не учитываются дважды. Выплата пачкой склеивается по общемуpayoutRef. После склейки придёт вебхукbooking.reconciled. fee— комиссия эквайринга или площадки, удержанная из этой оплаты: на счёт придётamount − fee. У возврата комиссии нет.status = cancelled— оплата не состоялась или отменена у вас. Отмена проведённой наличной снимает её операции; отмена склеенной —409.- Проведённую или склеенную оплату поменять нельзя (сумма, валюта, способ, вид, комиссия, дата) —
409;providerиpayoutRefменяются всегда.
Параметры пути
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
source | string | да | Код системы: voyz, booking_com, ostrovok… Код manual занят бронями, введёнными вручную в Aynes (D-208): запись с ним — 422. |
externalId | string | да | Номер брони в системе. |
paymentId | string | да | Номер оплаты в системе бронирования. |
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
kind | string | да | Значения: prepayment, payment, refund. |
method | string | да | cash — проводится в кассу сразу; остальное ждёт выписку. Значения: qr, card, transfer, cash, ota. |
provider | string | нет | Может быть null. |
amount | integer | да | Сколько заплатил гость (возврат — сколько вернули). |
fee | integer | нет | Комиссия эквайринга или площадки, удержанная из этой оплаты. |
currency | string | да | |
paidAt | string (date-time) | да | ISO 8601. |
payoutRef | string | нет | Может быть null. |
status | string | нет | Значения: succeeded, cancelled. По умолчанию succeeded. |
Пример запроса
curl -X PUT "https://aynes.pro/api/v1/bookings/voyz/B-2027-0714/payments/P-1" \
-H "Authorization: Bearer $AYNES_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"kind": "prepayment",
"method": "qr",
"provider": "gopay",
"amount": 900000,
"fee": 18000,
"currency": "KGS",
"paidAt": "2027-06-01T10:21:00+06:00",
"payoutRef": "gopay-payout-2027-06-02"
}'Пример ответа · 200
{
"ok": true,
"data": {
"id": "cm2pay9q6u0020f3g5h7j9k2m",
"externalId": "P-1",
"kind": "prepayment",
"method": "qr",
"provider": "gopay",
"amount": 900000,
"fee": 18000,
"currency": "KGS",
"exchangeRate": "1",
"baseAmount": 900000,
"paidAt": "2027-06-01T04:21:00.000Z",
"payoutRef": "gopay-payout-2027-06-02",
"status": "awaiting_statement",
"operationId": null,
"linkedAt": null
},
"meta": {
"created": true,
"changed": true
}
}Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | string | |
externalId | string | Номер оплаты в системе бронирования. |
kind | string | Значения: prepayment, payment, refund. |
method | string | Значения: qr, card, transfer, cash, ota. |
provider | string | Может быть null. |
amount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
fee | integer | Комиссия, удержанная из этой оплаты: на счёт пришло amount − fee. |
currency | string | |
exchangeRate | string | |
baseAmount | integer | Сумма в минимальных единицах валюты (тыйыны, копейки). |
paidAt | string (date-time) | ISO 8601. |
payoutRef | string | Номер выплаты пачкой у провайдера. Может быть null. |
status | string | awaiting_statement — безналичная, ждёт строку выписки; awaiting_cash_account — наличная, касса не выбрана; matched — склеена с выпиской; posted — проведена в кассу; cancelled — отменена. Значения: awaiting_statement, awaiting_cash_account, matched, posted, cancelled. |
operationId | string | Операция Aynes, которой проведена оплата. Может быть null. |
linkedAt | string (date-time) | ISO 8601. Может быть null. |
meta.created | boolean | Запись создана этим запросом. |
meta.changed | boolean | Запрос что-то изменил; повтор того же тела — false. |
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 401 | unauthorized | Токен не передан, отозван или истёк |
| 403 | forbidden, read_only | У токена нет нужного скоупа, тариф без нужной функции или (для записи) организация в режиме чтения |
| 404 | not_found | Бронь не найдена |
| 409 | conflict | Оплата уже в учёте |
| 422 | validation_error | Ошибка валидации |
| 429 | rate_limited | Превышен лимит запросов; см. Retry-After |
Вебхуки
Подписка
- Подписку заводит владелец или администратор: Настройки → API и вебхуки → Вебхуки — адрес HTTPS, события и описание. Подписок — не больше 20 на организацию.
- Секрет подписи
whs_…показывается один раз при создании — сохраните его рядом с обработчиком. - Вебхуки — функция тарифа «API»: на тарифе без неё подписки сохраняются, но события по ним не выпускаются, пока функция не вернётся.
- Адрес — только
https://и только во внешнюю сеть: адресаlocalhostи частных сетей не сохранятся. Перенаправления не выполняются — укажите конечный адрес. - Выключенная подписка событий не получает; уже поставленные доставки по ней завершаются ошибкой «Подписка выключена».
События
| Событие | Когда приходит |
|---|---|
operation.created | Новая операция. Появилась операция: введена вручную, загружена из банковской выписки (событие на каждую строку) или записана платежом сотрудника из мини-приложения Telegram. |
payment_request.status_changed | Смена статуса заявки. Заявка на оплату сменила статус: отправлена на согласование, согласована или отклонена (решением последнего шага маршрута), оплачена, отменена. |
payment_request.updated | Изменение заявки. Изменены поля заявки, которая ждёт согласования (сумма, назначение, категория, срок…), или срок либо счёт заявки перенесены в платёжном календаре. |
sync.failed | Ошибка синхронизации банка. Загрузка банковской выписки не удалась: обмен с банком, письмо с выпиской или загрузка файла. |
booking.reconciled | Оплата брони найдена в выписке. Оплата брони нашлась в банковской выписке: человек склеил её со строкой выписки на экране «Брони». Событие на каждую оплату, в том числе в выплате пачкой. |
Тело каждой доставки — JSON одного вида: имя события, организация, момент события и данные:
{
"event": "operation.created",
"tenantId": "cm2tnt3p0b0000a1b2c3d4e5f",
"occurredAt": "2026-10-08T09:30:00.000Z",
"data": {
"id": "cm2opr9e6k0009m1n3p5q7r9s",
"type": "OUTCOME",
"status": "ACTUAL",
"amount": 4500000,
"currency": "KGS",
"baseAmount": 4500000,
"operationDate": "2026-10-03T00:00:00.000Z",
"unitId": "cm2unt5r2c0003h6j8k1m3n5p",
"bankAccountId": "cm2acc9u6e0004y5z7a9b2c4d",
"contractorId": "cm2cnt3y0g0006n7p9q2r4s6t",
"categoryId": null,
"projectId": null,
"description": "Аренда офиса за октябрь 2026",
"source": "BANK_STATEMENT"
}
}- В
data— идентификаторы и главные поля; полную запись перечитайте методом API. - Порядок доставок не гарантирован, а одно событие может прийти дважды (повтор после таймаута): отбрасывайте повторы по заголовку
X-Webhook-Delivery.
operation.created
Появилась операция: введена вручную, загружена из банковской выписки (событие на каждую строку) или записана платежом сотрудника из мини-приложения Telegram.
В теле — поля самой операции, у связей — только идентификаторы. Названия категории, счёта и контрагента — в справочниках или в GET /operations.
Поля data
| Поле | Тип | Описание |
|---|---|---|
id | string | Идентификатор операции |
type | string | INCOME, OUTCOME или TRANSFER |
status | string | ACTUAL или PLANNED |
amount | integer | Сумма в минимальных единицах валюты счёта |
currency | string | Валюта счёта, ISO 4217 |
baseAmount | integer | Эквивалент в базовой валюте организации |
operationDate | string (date-time) | Дата операции |
unitId | string | null | Направление; null — направление ещё не поставлено |
bankAccountId | string | Счёт или касса |
contractorId | string | null | Контрагент |
categoryId | string | null | Категория |
projectId | string | null | Проект |
description | string | null | Назначение |
source | string | Откуда операция: MANUAL, BANK_STATEMENT, MINIAPP и другие |
Пример тела доставки
{
"event": "operation.created",
"tenantId": "cm2tnt3p0b0000a1b2c3d4e5f",
"occurredAt": "2026-10-08T09:30:00.000Z",
"data": {
"id": "cm2opr9e6k0009m1n3p5q7r9s",
"type": "OUTCOME",
"status": "ACTUAL",
"amount": 4500000,
"currency": "KGS",
"baseAmount": 4500000,
"operationDate": "2026-10-03T00:00:00.000Z",
"unitId": "cm2unt5r2c0003h6j8k1m3n5p",
"bankAccountId": "cm2acc9u6e0004y5z7a9b2c4d",
"contractorId": "cm2cnt3y0g0006n7p9q2r4s6t",
"categoryId": null,
"projectId": null,
"description": "Аренда офиса за октябрь 2026",
"source": "BANK_STATEMENT"
}
}payment_request.status_changed
Заявка на оплату сменила статус: отправлена на согласование, согласована или отклонена (решением последнего шага маршрута), оплачена, отменена.
- Решение промежуточного шага маршрута статус не меняет — заявка остаётся
PENDING, события нет. PAIDприходит, когда заявку склеили с операцией оплаты: сам матчер или человек, подтвердивший связку.
Поля data
| Поле | Тип | Описание |
|---|---|---|
id | string | Идентификатор заявки — перечитайте её GET /payment-requests/{id} |
from | string | Прежний статус: DRAFT, PENDING, APPROVED |
to | string | Новый статус: PENDING, APPROVED, REJECTED, PAID, CANCELLED |
actorId | string | Кто сменил статус; нет у оплаты, склеенной автоматически |
operationId | string | Только у PAID: операция оплаты |
Пример тела доставки
{
"event": "payment_request.status_changed",
"tenantId": "cm2tnt3p0b0000a1b2c3d4e5f",
"occurredAt": "2026-10-08T09:30:00.000Z",
"data": {
"id": "cm2req1g8m0010t2v4w6x8y1z",
"from": "PENDING",
"to": "APPROVED",
"actorId": "cm2usr4j1p0012g4h6j8k1m3n"
}
}payment_request.updated
Изменены поля заявки, которая ждёт согласования (сумма, назначение, категория, срок…), или срок либо счёт заявки перенесены в платёжном календаре.
Событие несёт только список изменённых полей, без значений: новые значения — в GET /payment-requests/{id}.
Поля data
| Поле | Тип | Описание |
|---|---|---|
id | string | Идентификатор заявки |
changes | array<string> | Имена изменённых полей, как в ответе API: amount, dueDate, bankAccountId… |
actorId | string | Кто изменил |
via | string | calendar — перенос в платёжном календаре; нет — правка карточки заявки |
Пример тела доставки
{
"event": "payment_request.updated",
"tenantId": "cm2tnt3p0b0000a1b2c3d4e5f",
"occurredAt": "2026-10-08T09:30:00.000Z",
"data": {
"id": "cm2req1g8m0010t2v4w6x8y1z",
"changes": [
"dueDate"
],
"via": "calendar",
"actorId": "cm2usr3h9n0011a3b5c7d9e1f"
}
}sync.failed
Загрузка банковской выписки не удалась: обмен с банком, письмо с выпиской или загрузка файла.
Поля data
| Поле | Тип | Описание |
|---|---|---|
syncRunId | string | Идентификатор прогона загрузки |
integrationId | string | null | Подключение банка; null — загрузка без подключения |
connectorCode | string | Код коннектора банка, например MBANK_1C |
error | string | Текст ошибки, до 500 символов |
Пример тела доставки
{
"event": "sync.failed",
"tenantId": "cm2tnt3p0b0000a1b2c3d4e5f",
"occurredAt": "2026-10-08T09:30:00.000Z",
"data": {
"syncRunId": "cm2syn2r7v0021h4j6k8m1n3p",
"integrationId": null,
"connectorCode": "MBANK_1C",
"error": "Файл не похож на выписку 1С: нет секции СекцияРасчСчет"
}
}booking.reconciled
Оплата брони нашлась в банковской выписке: человек склеил её со строкой выписки на экране «Брони». Событие на каждую оплату, в том числе в выплате пачкой.
Поля data
| Поле | Тип | Описание |
|---|---|---|
source | string | Код системы бронирования |
bookingExternalId | string | Номер брони в системе |
paymentExternalId | string | Номер оплаты в системе |
amount | integer | Сумма оплаты в минимальных единицах |
fee | integer | Удержанная комиссия |
currency | string | Валюта оплаты |
operationId | string | Операция Aynes — строка выписки |
operationDate | string (date-time) | Дата строки выписки |
Пример тела доставки
{
"event": "booking.reconciled",
"tenantId": "cm2tnt3p0b0000a1b2c3d4e5f",
"occurredAt": "2026-10-08T09:30:00.000Z",
"data": {
"source": "voyz",
"bookingExternalId": "B-2027-0714",
"paymentExternalId": "P-1",
"amount": 900000,
"fee": 18000,
"currency": "KGS",
"operationId": "cm2opr3t8w0022k5m7n9p2q4r",
"operationDate": "2027-06-02T00:00:00.000Z"
}
}Запрос к вашему адресу
Aynes шлёт POST на адрес подписки с заголовками:
| Заголовок | Значение |
|---|---|
Content-Type | application/json |
User-Agent | finance-saas-webhooks/1 |
X-Webhook-Event | Имя события, например operation.created |
X-Webhook-Delivery | Идентификатор доставки — один у всех попыток одной доставки |
X-Webhook-Signature | sha256= и HMAC-SHA256 тела секретом подписки в hex |
Проверка подписи
- Прочитайте тело запроса как есть, байтами, — до разбора JSON. Пересобранный JSON может отличаться порядком ключей и пробелами, и подпись не сойдётся.
- Посчитайте HMAC-SHA256 тела; ключ — секрет подписки
whs_…целиком. - Запишите результат в hex строчными буквами и добавьте
sha256=в начало. - Сравните с заголовком
X-Webhook-Signatureфункцией сравнения за постоянное время. Не совпало — ответьте401и ничего не делайте.
Пример для самопроверки: секрет whs_test_secret и тело ниже дают подпись sha256=f24234cc39b57e398bf704378fb6a43f8421902c8bc4177fac84fd105dfdd421.
{"event":"sync.failed","tenantId":"t1","occurredAt":"2026-10-08T09:30:00.000Z","data":{"error":"test"}}import { createHmac, timingSafeEqual } from "node:crypto";
import express from "express";
const SECRET = process.env.AYNES_WEBHOOK_SECRET; // whs_…
const app = express();
// Подпись считается от тела как есть — читаем его байтами, до JSON.parse.
app.post("/aynes/webhook", express.raw({ type: "application/json" }), (req, res) => {
const expected = "sha256=" + createHmac("sha256", SECRET).update(req.body).digest("hex");
const received = req.get("X-Webhook-Signature") ?? "";
const valid =
received.length === expected.length &&
timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!valid) return res.status(401).end();
const delivery = req.get("X-Webhook-Delivery"); // повтор той же доставки — отбросить
const { event, data } = JSON.parse(req.body.toString("utf8"));
// Ответьте сразу, долгую обработку — после ответа.
res.status(204).end();
handle(delivery, event, data);
});<?php
$secret = getenv('AYNES_WEBHOOK_SECRET'); // whs_…
$body = file_get_contents('php://input'); // тело как есть, до json_decode
$expected = 'sha256=' . hash_hmac('sha256', $body, $secret);
$received = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
if (!hash_equals($expected, $received)) {
http_response_code(401);
exit;
}
$delivery = $_SERVER['HTTP_X_WEBHOOK_DELIVERY'] ?? ''; // повтор той же доставки — отбросить
$payload = json_decode($body, true);
// $payload['event'], $payload['data'] …
http_response_code(204);import hashlib
import hmac
import json
import os
from flask import Flask, abort, request
SECRET = os.environ["AYNES_WEBHOOK_SECRET"].encode() # whs_…
app = Flask(__name__)
@app.post("/aynes/webhook")
def aynes_webhook():
body = request.get_data() # тело как есть, до разбора JSON
expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
received = request.headers.get("X-Webhook-Signature", "")
if not hmac.compare_digest(expected, received):
abort(401)
delivery = request.headers.get("X-Webhook-Delivery") # повтор — отбросить
payload = json.loads(body)
# payload["event"], payload["data"] …
return "", 204Повторы и успешная доставка
- Доставка успешна, если ваш адрес ответил кодом
2xxв течение 10 секунд. Тело ответа не читается. - Любой другой код, перенаправление
3xx, таймаут или ошибка соединения — неудача, и доставка повторяется. - Всего до 6 попыток: первая и 5 повторов. Паузы растут вдвое со случайным разбросом: около 30–60 секунд, 1–2, 2–4, 4–8 и 8–16 минут — все попытки укладываются примерно в полчаса.
- После последней неудачной попытки доставка помечается «Не доставлено» и больше не повторяется.
- Отвечайте сразу, а долгую обработку делайте после ответа или в своей очереди.
Журнал доставок
На экране «Вебхуки» — последние 50 доставок: событие, состояние («Ждёт», «Доставлено», «Не доставлено»), число попыток, код ответа вашего сервера и текст ошибки. У каждой подписки — время и код последней доставки. По журналу удобно отлаживать обработчик: идентификатор доставки в журнале — тот же, что в заголовке X-Webhook-Delivery.
Изменения API
| Дата | Что изменилось |
|---|---|
| 2026-10-17 | Создание операций: POST /operations, скоуп operations:write, заголовок Idempotency-Key; повтор с тем же ключом — 200 и meta.repeated. |
| 2026-10-08 | Документация разработчика на этой странице. Событие booking.reconciled теперь доставляется: суммы в его теле — числа. |
| 2026-10-07 | Брони и оплаты броней: GET /bookings, GET и PUT /bookings/{source}/{externalId}, GET и PUT …/payments/{paymentId}, скоупы bookings:read и bookings:write, код ошибки conflict, событие booking.reconciled. Ключ для системы бронирования работает на тарифе с бронями без функции «API». |
| 2026-09-27 | Участок работ проекта: фильтр directionId в GET /operations и поле directionId в теле POST /payment-requests. |
| 2026-09-23 | Чтение заявок: GET /payment-requests, GET /payment-requests/{id}, скоуп payment-requests:read. |
| 2026-09-22 | Событие payment_request.updated. |
| 2026-09-17 | Версия v1: токены и скоупы, GET /me, GET /operations, POST /payment-requests, справочники, отчёты ДДС и ПиУ, вебхуки operation.created, payment_request.status_changed, sync.failed. |