Для разработчиков
API и вебхуки iPlanner
Ваша CRM, сайт, Albato, n8n или своя программа читают из кабинета услуги, мастеров и свободное время, записывают клиентов и получают события о записях. Версия API — 1.0.0; адрес — https://iplanner.pro/api/v1.
Как получить ключ
Ключ выпускает владелец кабинета (или сотрудник с правом «API: выпускать и отзывать ключи») в разделе «Настройки → API и доступы». Внешний API работает на оплаченном тарифе, в который он входит. Модуль «API и доступы» должен быть в тарифе и не выключен, кабинет и сотрудник, выпустивший ключ, — не заблокированы. Пробный период не считается оплатой.
Секретный ключ начинается с ipk_live_ и показывается один раз. Он действует от имени выпустившего: при выпуске отмечаются права, и ключ получает пересечение отмеченного с текущими правами этого человека. Сняли право — ключ потерял его сразу. Перестали платить или кабинет заблокирован — запросы получают 403, но ключи не удаляются и заработают снова без перевыпуска.
Права ключа
Без отмеченных прав ключ читает то, что и так видно на витрине: компанию, услуги, мастеров, свободное время и условия записи.
journal.view.all— Записи кабинета: читатьСписок записей и запись по номеру (GET /bookings, /bookings/{id}), кто работает в день и рабочие места (GET /shifts, /places), проведённые приходы склада (GET /stock-receipts).
clients.view— Имя и телефон клиентаВ записях появляются имя и телефон клиента. Без этого права — только номер клиента.
appointments.manage— Записи: создавать, переносить, отменятьУдержание времени и запись клиента (POST /reservations, POST /bookings), перенос и отмена записи (PUT и DELETE /bookings/{id}).
tasks.view— Задачи: ставитьНовая задача в разделе «Задачи» кабинета (POST /tasks): название, описание, исполнитель и срок.
Вход и лимиты
Ключ передаётся в каждом запросе заголовком Authorization: Bearer …. Нет ключа, ключ отозван или неверный — 401.
curl https://iplanner.pro/api/v1/companies \
-H "Authorization: Bearer ipk_live_…"Лимит частоты — 120 запросов за 60 с на ключ и 300 на кабинет целиком (все его ключи вместе). Превышение — 429 с заголовком Retry-After: через сколько секунд повторить.
Все даты-время — ISO 8601 в UTC; дни (ГГГГ-ММ-ДД) и подписи времени — в поясе компании (timezone в ответе /companies). Деньги — целые копейки в полях …Minor.
В версии 1 API только дополняется: новые поля, ручки, значения перечислений и события. Незнакомые поля и значения принимайте молча.
Ручки
- /companies— Компания ключа
- /services— Услуги с онлайн-записью
- /resources— Мастера, принимающие онлайн-запись
- /available-dates— Дни со свободным временем
- /available-slots— Свободное время на день
- /booking-conditions— Условия записи
- /shifts— Кто работает в день
- /places— Рабочие места
- /bookings— Записи компании
- POST/bookings— Записать клиента
- /bookings/{id}— Запись по id
- PUT/bookings/{id}— Перенести запись
- DELETE/bookings/{id}— Отменить запись
- POST/reservations— Удержать время
- DELETE/reservations/{id}— Снять удержание
- /reviews— Новые отзывы
- /stock-receipts— Приход материалов
- POST/tasks— Поставить задачу
- /events— Каталог событий
/companies
Компания ключа
Кабинет с адресом. У сети кабинетов список пуст: сеть компанией не бывает.
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
curl -X GET "https://iplanner.pro/api/v1/companies" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (CompanyList)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"name": "Анна",
"type": "individual",
"address": "ул. Ленина, 1",
"city": "Пермь",
"location": {
"lat": 58.01,
"lng": 56.25
},
"timezone": "Europe/Moscow",
"currency": "RUB",
"storefront": {
"url": "текст",
"qrUrl": "текст",
"accentColor": "текст",
"logoUrl": "текст"
}
}
]
}Отказы: 400, 401, 403, 429 — коды в разделе «Ошибки и коды».
/services
Услуги с онлайн-записью
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
curl -X GET "https://iplanner.pro/api/v1/services" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (ServiceList)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"companyId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"title": "Маникюр с покрытием",
"category": "Ногти",
"description": "текст",
"durationMinutes": 60,
"price": {
"amountMinor": 250000,
"currency": "RUB",
"isFrom": true
},
"resourceIds": [
"c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704"
]
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/resources
Мастера, принимающие онлайн-запись
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
serviceIdstring, uuid, в строке запроса- Только те, кто оказывает эту услугу.
curl -X GET "https://iplanner.pro/api/v1/resources" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (ResourceList)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"companyId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"name": "Анна",
"headline": "Мастер маникюра",
"avatarUrl": "текст",
"services": [
{
"serviceId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"durationMinutes": 60,
"price": {}
}
]
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/available-dates
Дни со свободным временем
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
resourceIdstring, uuid, в строке запроса, обязательный- Мастер (id из /resources).
serviceIdsstring, в строке запроса, обязательный- Услуги визита через запятую, в порядке исполнения (id из /services).
curl -X GET "https://iplanner.pro/api/v1/available-dates" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (AvailableDates)
{
"resourceId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"serviceIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"timezone": "Europe/Moscow",
"dates": [
"2026-10-01"
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/available-slots
Свободное время на день
Считается той же функцией, что витрина: порог записи, горизонт, перерывы и прилипание — как у клиента на сайте.
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
resourceIdstring, uuid, в строке запроса, обязательный- Мастер (id из /resources).
serviceIdsstring, в строке запроса, обязательный- Услуги визита через запятую, в порядке исполнения (id из /services).
datestring, date, в строке запроса, обязательный- День в поясе компании, ГГГГ-ММ-ДД.
curl -X GET "https://iplanner.pro/api/v1/available-slots" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (AvailableSlots)
{
"resourceId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"serviceIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"date": "2026-10-01",
"timezone": "Europe/Moscow",
"durationMinutes": 60,
"slots": [
{
"start": "2026-10-01T07:30:00.000Z",
"label": "10:30"
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/booking-conditions
Условия записи
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
curl -X GET "https://iplanner.pro/api/v1/booking-conditions" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (BookingConditions)
{
"companyId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"personalDataConsentRequired": true,
"prepayment": {
"mode": "percent",
"percent": 1,
"amountMinor": 250000,
"currency": "RUB",
"forAllClients": true,
"forNewClients": true,
"forFlaggedServices": true,
"minPriceMinor": 250000,
"terms": "текст",
"offerConsentRequired": true
},
"resources": [
{
"resourceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"onlineBooking": true,
"audience": "everyone",
"horizonDays": 30,
"minNoticeMinutes": 60,
"sameDayBooking": true,
"slotStepMinutes": 60
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/shifts
Кто работает в день
Все сотрудники компании, не только с онлайн-записью, и их рабочее время в этот день: график с учётом отгулов и доп. смен. Пустые spans — в этот день не работает. Отрезков может быть несколько (смена с перерывом).
Право ключа: `journal.view.all` (Записи кабинета: читать).
Право ключа: journal.view.all — Записи кабинета: читать.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
datestring, date, в строке запроса- День в поясе компании, ГГГГ-ММ-ДД. По умолчанию — сегодня.
curl -X GET "https://iplanner.pro/api/v1/shifts" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (ShiftDay)
{
"companyId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"date": "2026-10-01",
"timezone": "Europe/Moscow",
"items": [
{
"resourceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"name": "Анна",
"avatarUrl": "текст",
"role": "owner",
"spans": [
{
"start": "2026-10-01T07:30:00.000Z",
"end": "2026-10-01T07:30:00.000Z"
}
]
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/places
Рабочие места
Кресла, кабинеты и аппараты компании. Место записи — placeId в записи.
Право ключа: `journal.view.all` (Записи кабинета: читать).
Право ключа: journal.view.all — Записи кабинета: читать.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
curl -X GET "https://iplanner.pro/api/v1/places" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (PlaceList)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"companyId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"name": "Анна",
"kind": "chair"
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/bookings
Записи компании
По времени начала, курсором. Перенесённая запись приходит один раз — действующей версией. Имя и телефон клиента — только с правом clients.view.
Право ключа: `journal.view.all` (Записи кабинета: читать).
Право ключа: journal.view.all — Записи кабинета: читать.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
fromstring, date, в строке запроса- Первый день, ГГГГ-ММ-ДД в поясе компании. По умолчанию — сегодня.
tostring, date, в строке запроса- Последний день включительно. По умолчанию — 30 дней от from, не больше 93.
cursorstring, в строке запроса- nextCursor из предыдущей страницы.
limitinteger, 1–200, в строке запроса- Записей на странице: 1–200, по умолчанию 50.
curl -X GET "https://iplanner.pro/api/v1/bookings" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (BookingPage)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"previousIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"companyId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"resourceId": "5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53",
"placeId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"status": "pending",
"cancelledBy": "client",
"cancelledAt": "2026-10-01T07:30:00.000Z",
"start": "2026-10-01T07:30:00.000Z",
"end": "2026-10-01T07:30:00.000Z",
"services": [
{
"serviceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"title": "Маникюр с покрытием",
"durationMinutes": 60,
"price": {}
}
],
"price": {
"totalMinor": 250000,
"discountMinor": 0,
"paidMinor": 0,
"currency": "RUB"
},
"prepayment": {
"status": "none",
"requiredMinor": 250000
},
"channel": "online",
"tag": "instagram",
"client": {
"id": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"birthdayToday": true,
"name": "Анна",
"phone": "+79001234567"
},
"productsCount": 1,
"createdAt": "2026-10-01T07:30:00.000Z",
"updatedAt": "2026-10-01T07:30:00.000Z"
}
],
"nextCursor": "текст"
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
POST/bookings
Записать клиента
Из удержания (reservationId — запись получит его id) или сразу на время из /available-slots. Правила — те же, что у записи с сайта: согласие, доступ «только клиенты», лимит записей, предоплата. Запись ждёт подтверждения мастера (status pending). Имя и телефон клиента в ответе — только с правом clients.view.
Право ключа: `appointments.manage` (Записи: создавать, переносить, отменять).
Право ключа: appointments.manage — Записи: создавать, переносить, отменять.
Параметры
Idempotency-Keystring, заголовок, обязательный- Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
Тело запроса (BookingCreate)
reservationIdstring, uuid, в теле- Удержание из POST /reservations. С ним resourceId, serviceIds и start не нужны.
resourceIdstring, uuid, в телеserviceIdsarray, в телеstartstring, date-time, в телеclientobject, в теле, обязательныйconsentobject, в теле, обязательныйpromoCodestring, в телеtagstring, в теле- Метка вашей системы; по умолчанию api (у записи из удержания — метка удержания).
curl -X POST "https://iplanner.pro/api/v1/bookings" \
-H "Authorization: Bearer ipk_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ … }'Пример тела
{
"reservationId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"resourceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"serviceIds": [
"c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704"
],
"start": "2026-10-01T07:30:00.000Z",
"client": {
"name": "Анна",
"phone": "+79001234567"
},
"consent": {
"personalData": true,
"offer": true
},
"promoCode": "AUTUMN10",
"tag": "instagram"
}Ответ 201 (Booking)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"previousIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"companyId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"resourceId": "5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53",
"placeId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"status": "pending",
"cancelledBy": "client",
"cancelledAt": "2026-10-01T07:30:00.000Z",
"start": "2026-10-01T07:30:00.000Z",
"end": "2026-10-01T07:30:00.000Z",
"services": [
{
"serviceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"title": "Маникюр с покрытием",
"durationMinutes": 60,
"price": {
"amountMinor": 250000,
"currency": "RUB"
}
}
],
"price": {
"totalMinor": 250000,
"discountMinor": 0,
"paidMinor": 0,
"currency": "RUB"
},
"prepayment": {
"status": "none",
"requiredMinor": 250000
},
"channel": "online",
"tag": "instagram",
"client": {
"id": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"birthdayToday": true,
"name": "Анна",
"phone": "+79001234567"
},
"productsCount": 1,
"createdAt": "2026-10-01T07:30:00.000Z",
"updatedAt": "2026-10-01T07:30:00.000Z"
}Отказы: 400, 401, 403, 404, 409, 422, 429 — коды в разделе «Ошибки и коды».
/bookings/{id}
Запись по id
Прежний id после переноса ведёт к действующей версии: в ответе её id и previousIds.
Право ключа: `journal.view.all` (Записи кабинета: читать).
Право ключа: journal.view.all — Записи кабинета: читать.
Параметры
idstring, uuid, в пути, обязательный- id записи, в том числе прежний.
curl -X GET "https://iplanner.pro/api/v1/bookings/:id" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (Booking)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"previousIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"companyId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"resourceId": "5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53",
"placeId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"status": "pending",
"cancelledBy": "client",
"cancelledAt": "2026-10-01T07:30:00.000Z",
"start": "2026-10-01T07:30:00.000Z",
"end": "2026-10-01T07:30:00.000Z",
"services": [
{
"serviceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"title": "Маникюр с покрытием",
"durationMinutes": 60,
"price": {
"amountMinor": 250000,
"currency": "RUB"
}
}
],
"price": {
"totalMinor": 250000,
"discountMinor": 0,
"paidMinor": 0,
"currency": "RUB"
},
"prepayment": {
"status": "none",
"requiredMinor": 250000
},
"channel": "online",
"tag": "instagram",
"client": {
"id": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"birthdayToday": true,
"name": "Анна",
"phone": "+79001234567"
},
"productsCount": 1,
"createdAt": "2026-10-01T07:30:00.000Z",
"updatedAt": "2026-10-01T07:30:00.000Z"
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
PUT/bookings/{id}
Перенести запись
Новое начало и/или другой мастер. Те же правила, что у клиента по ссылке из напоминания: окно правки до визита, запас до визита, закрытый визит не переносится. В ответе — новая версия записи, прежний id — в previousIds.
Право ключа: `appointments.manage` (Записи: создавать, переносить, отменять).
Право ключа: appointments.manage — Записи: создавать, переносить, отменять.
Параметры
idstring, uuid, в пути, обязательный- id записи, в том числе прежний: ведём к действующей версии.
Idempotency-Keystring, заголовок, обязательный- Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
Тело запроса (BookingUpdate)
startstring, date-time, в телеresourceIdstring, uuid, в теле- Другой мастер компании, оказывающий все услуги записи.
curl -X PUT "https://iplanner.pro/api/v1/bookings/:id" \
-H "Authorization: Bearer ipk_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ … }'Пример тела
{
"start": "2026-10-01T07:30:00.000Z",
"resourceId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90"
}Ответ 200 (Booking)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"previousIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"companyId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"resourceId": "5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53",
"placeId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"status": "pending",
"cancelledBy": "client",
"cancelledAt": "2026-10-01T07:30:00.000Z",
"start": "2026-10-01T07:30:00.000Z",
"end": "2026-10-01T07:30:00.000Z",
"services": [
{
"serviceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"title": "Маникюр с покрытием",
"durationMinutes": 60,
"price": {
"amountMinor": 250000,
"currency": "RUB"
}
}
],
"price": {
"totalMinor": 250000,
"discountMinor": 0,
"paidMinor": 0,
"currency": "RUB"
},
"prepayment": {
"status": "none",
"requiredMinor": 250000
},
"channel": "online",
"tag": "instagram",
"client": {
"id": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"birthdayToday": true,
"name": "Анна",
"phone": "+79001234567"
},
"productsCount": 1,
"createdAt": "2026-10-01T07:30:00.000Z",
"updatedAt": "2026-10-01T07:30:00.000Z"
}Отказы: 400, 401, 403, 404, 409, 422, 429 — коды в разделе «Ошибки и коды».
DELETE/bookings/{id}
Отменить запись
Отмена от имени клиента (cancelledBy: client) по тем же правилам, что по ссылке из напоминания. Отменённая уже — не ошибка.
Право ключа: `appointments.manage` (Записи: создавать, переносить, отменять).
Право ключа: appointments.manage — Записи: создавать, переносить, отменять.
Параметры
idstring, uuid, в пути, обязательный- id записи, в том числе прежний: ведём к действующей версии.
Idempotency-Keystring, заголовок, обязательный- Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
curl -X DELETE "https://iplanner.pro/api/v1/bookings/:id" \
-H "Authorization: Bearer ipk_live_…" \
-H "Idempotency-Key: $(uuidgen)"Ответ 200 (Booking)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"previousIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"companyId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"resourceId": "5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53",
"placeId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"status": "pending",
"cancelledBy": "client",
"cancelledAt": "2026-10-01T07:30:00.000Z",
"start": "2026-10-01T07:30:00.000Z",
"end": "2026-10-01T07:30:00.000Z",
"services": [
{
"serviceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"title": "Маникюр с покрытием",
"durationMinutes": 60,
"price": {
"amountMinor": 250000,
"currency": "RUB"
}
}
],
"price": {
"totalMinor": 250000,
"discountMinor": 0,
"paidMinor": 0,
"currency": "RUB"
},
"prepayment": {
"status": "none",
"requiredMinor": 250000
},
"channel": "online",
"tag": "instagram",
"client": {
"id": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"birthdayToday": true,
"name": "Анна",
"phone": "+79001234567"
},
"productsCount": 1,
"createdAt": "2026-10-01T07:30:00.000Z",
"updatedAt": "2026-10-01T07:30:00.000Z"
}Отказы: 400, 401, 403, 404, 409, 422, 429 — коды в разделе «Ошибки и коды».
POST/reservations
Удержать время
Держит слот, пока клиент заполняет вашу форму: запись с сайта или из кабинета на это время получит отказ базы. Правила те же, что у записи с сайта (онлайн-запись, запас до визита, места). Снимается само по expiresAt.
Право ключа: `appointments.manage` (Записи: создавать, переносить, отменять).
Право ключа: appointments.manage — Записи: создавать, переносить, отменять.
Параметры
Idempotency-Keystring, заголовок, обязательный- Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
Тело запроса (ReservationCreate)
resourceIdstring, uuid, в теле, обязательныйserviceIdsarray, в теле, обязательный- Услуги визита в порядке исполнения, от 1 до 20.
startstring, date-time, в теле, обязательныйholdMinutesinteger, 1–30, в теле- Срок удержания; по умолчанию 10 минут, не больше 30.
tagstring, в теле- Метка вашей системы (a–z, 0–9, _ и -, до 32 знаков) — видна в «Хронологии» и отчётах. По умолчанию api.
curl -X POST "https://iplanner.pro/api/v1/reservations" \
-H "Authorization: Bearer ipk_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ … }'Пример тела
{
"resourceId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"serviceIds": [
"9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15"
],
"start": "2026-10-01T07:30:00.000Z",
"holdMinutes": 60,
"tag": "instagram"
}Ответ 201 (Reservation)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"companyId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"resourceId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"serviceIds": [
"5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53"
],
"start": "2026-10-01T07:30:00.000Z",
"expiresAt": "2026-10-01T07:30:00.000Z"
}Отказы: 400, 401, 403, 404, 409, 422, 429 — коды в разделе «Ошибки и коды».
DELETE/reservations/{id}
Снять удержание
Время освобождается сразу. Снятое уже — не ошибка. Удержание, ставшее записью, отменяйте как запись.
Право ключа: `appointments.manage` (Записи: создавать, переносить, отменять).
Право ключа: appointments.manage — Записи: создавать, переносить, отменять.
Параметры
idstring, uuid, в пути, обязательный- id удержания.
Idempotency-Keystring, заголовок, обязательный- Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
curl -X DELETE "https://iplanner.pro/api/v1/reservations/:id" \
-H "Authorization: Bearer ipk_live_…" \
-H "Idempotency-Key: $(uuidgen)"Ответ 200 (ReservationRelease)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"released": true
}Отказы: 400, 401, 403, 404, 409, 422, 429 — коды в разделе «Ошибки и коды».
/reviews
Новые отзывы
Опубликованные отзывы компании с начала дня from, свежие первыми, не больше 200. Только то, что видно на витрине: скрытых нет, а если витрина студии прячет блок отзывов — список пуст. Текста и автора нет — оценка, мастер и время.
Хватает действующего ключа допущенного кабинета.
Хватает действующего ключа.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
fromstring, date, в строке запроса- С какого дня, ГГГГ-ММ-ДД в поясе компании. По умолчанию — сегодня.
curl -X GET "https://iplanner.pro/api/v1/reviews" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (ReviewList)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"resourceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"rating": 1,
"createdAt": "2026-10-01T07:30:00.000Z"
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
/stock-receipts
Приход материалов
Проведённые приходы склада с начала дня from, свежие первыми, не больше 200: время проведения и число строк. Отменённые не отдаются. Названий и денег нет. Нет модуля «Склад» в тарифе — пустой список.
Право ключа: `journal.view.all` (Записи кабинета: читать).
Право ключа: journal.view.all — Записи кабинета: читать.
Параметры
companyIdstring, uuid, в строке запроса- Компания ключа. Можно не передавать: ключ принадлежит одной компании; чужой id — 404.
fromstring, date, в строке запроса- С какого дня, ГГГГ-ММ-ДД в поясе компании. По умолчанию — сегодня.
curl -X GET "https://iplanner.pro/api/v1/stock-receipts" \
-H "Authorization: Bearer ipk_live_…"Ответ 200 (StockReceiptList)
{
"items": [
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"postedAt": "2026-10-01T07:30:00.000Z",
"lines": 1
}
]
}Отказы: 400, 401, 403, 404, 429 — коды в разделе «Ошибки и коды».
POST/tasks
Поставить задачу
Задача появляется в разделе «Задачи» кабинета от имени сотрудника, выпустившего ключ. Правила — те же, что у формы: исполнитель только из состава компании и получает уведомление. Модуля «Задачи» нет в тарифе — 403 not_in_plan.
Право ключа: `tasks.view` (Задачи: ставить).
Право ключа: tasks.view — Задачи: ставить.
Параметры
Idempotency-Keystring, заголовок, обязательный- Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
Тело запроса (TaskCreate)
titlestring, в теле, обязательный- Что нужно сделать: от 2 до 200 знаков.
descriptionstring, в теле- Комментарий, до 2000 знаков.
assigneeResourceIdstring, uuid, в теле- Исполнитель — действующий сотрудник компании (resourceId из /shifts). У мастера-одиночки не ставится.
dueDatestring, date, в теле- Срок, ГГГГ-ММ-ДД.
curl -X POST "https://iplanner.pro/api/v1/tasks" \
-H "Authorization: Bearer ipk_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ … }'Пример тела
{
"title": "Маникюр с покрытием",
"description": "текст",
"assigneeResourceId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"dueDate": "2026-10-01"
}Ответ 201 (Task)
{
"id": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"title": "Маникюр с покрытием",
"assigneeResourceId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"dueDate": "2026-10-01",
"createdAt": "2026-10-01T07:30:00.000Z"
}Отказы: 400, 401, 403, 404, 409, 422, 429 — коды в разделе «Ошибки и коды».
/events
Каталог событий
Типы событий, которые уходят вебхуком. Формы данных — в разделе webhooks этого описания.
Ключ не нужен.
Ключ не нужен.
curl -X GET "https://iplanner.pro/api/v1/events"Ответ 200 (EventList)
{
"items": [
{
"type": "текст",
"event": "текст",
"label": "10:30",
"description": "текст",
"dataVersion": "текст"
}
]
}Повтор запроса: Idempotency-Key
Ручки, которые меняют данные (POST /bookings, PUT /bookings/{id}, DELETE /bookings/{id}, POST /reservations, DELETE /reservations/{id}, POST /tasks), требуют заголовок Idempotency-Key. Сеть оборвалась, ответ не дошёл — повторите запрос с тем же ключом: вторая запись не появится.
Уникальная строка на каждую попытку (например, UUID), до 255 знаков ASCII. Повтор с тем же ключом и тем же телом отдаёт сохранённый ответ и второй раз ничего не делает; с другим телом — 409 idempotency_conflict. Ключ живёт сутки.
409 idempotency_conflict— Этот ключ идемпотентности уже использован с другим запросом409 idempotency_in_progress— Такой же запрос уже выполняется. Повторите чуть позже.
Ошибки и коды
Отказ приходит телом { code, message, details? }. Различайте причины по code, а не по тексту: текст — для человека и может меняться. Незнакомый код обрабатывайте по HTTP-статусу. Непредвиденная ошибка сервера — 500 с тем же форматом тела; повторите позже.
{
"code": "slot_taken",
"message": "Это время только что заняли. Выберите другое окно."
}400 — ошибка в запросе
consent_required— Отметьте согласие на обработку персональных данныхinvalid_input— Проверьте заполнение формыoffer_consent_required— Отметьте согласие с условиями предоплаты и возврата
401 — ключ не принят
api_key_invalid— Ключ API не принят: нет, отозван или неверный
403 — нет доступа или права
actor_blocked— Доступ этого сотрудника закрытcabinet_blocked— Кабинет заблокированdenied— Недостаточно правnot_for_node— В этом кабинете раздел недоступенnot_in_plan— Не входит в ваш тарифpast_locked— Записи прошлых дней правит только владелец или тот, кому он дал право «Записи прошлых дней: править»plan_not_paid— Работает только на оплаченном тарифе
404 — не найдено
not_found— Не найденоnot_offered— Такого раздела нет
409 — конфликт: время заняли, удержание истекло, ключ идемпотентности
failed— Не удалось выполнить. Попробуйте ещё раз.hold_expired— Время удержания слота вышло. Выберите время заново.idempotency_conflict— Этот ключ идемпотентности уже использован с другим запросомidempotency_in_progress— Такой же запрос уже выполняется. Повторите чуть позже.place_taken— Это место уже занято в это время. Выберите другое кресло или время.slot_taken— Это время только что заняли. Выберите другое окно.slot_unavailable— На это время записаться нельзя — выберите одно из свободных окон.
422 — правило записи не пускает
bot— Не удалось записаться, попробуйте ещё раз.change_closed— Изменить запись уже нельзя — свяжитесь с мастеромclient_blocked— Клиент заблокирован в этом кабинетеclient_online_closed— Онлайн-запись сейчас недоступна — позвоните, пожалуйста, в студиюdiscount_rejected— Скидка не применимаlimit_exceeded— На этот номер уже есть несколько предстоящих записей. Свяжитесь с мастером напрямую.online_closed— Мастер сейчас не принимает онлайн-записьstranger— Онлайн-запись — только для клиентовtoo_soon— Пока рано для записи — выберите время позже
429 — слишком часто
rate_limited— Слишком много запросов. Повторите позже.
Вебхуки
События кабинета уходят POST-запросом на ваш адрес. Подключение — в «Настройки → Интеграции», карточка «Свой вебхук»: адрес (только https), галочки нужных событий. Секрет подписи (whsec_…) показывается один раз при подключении. Вебхуки работают на оплаченном тарифе с модулем «Интеграции»; пока кабинет не допущен, события не уходят и потом не досылаются.
Формат — CloudEvents 1.0
Тело — конверт CloudEvents (application/cloudevents+json), его без переводчика понимают Albato, n8n, Make и большинство приёмников событий. type — тип события из каталога ниже, subject — id записи, id уникален навсегда: по нему отбивайте повторы. Версия формы данных — dataversion (1).
{
"specversion": "1.0",
"id": "7d0b3e6a-2c51-4f8e-9a14-6b3d2e8c0f71",
"type": "ru.iplanner.appointment.created",
"source": "/workspaces/9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"subject": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"time": "2026-10-01T07:31:12.000Z",
"datacontenttype": "application/json",
"dataversion": "1",
"data": {
"appointmentId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"previousId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"status": "confirmed",
"startsAt": "2026-10-01T07:30:00.000Z",
"endsAt": "2026-10-01T07:30:00.000Z",
"professionalId": "c41d8e03-7b6a-4e29-8f15-a3d2c6b9e704",
"previousProfessionalId": "5e8a2f71-0c4d-4b96-a1e3-7f2b9d6c8a53",
"previousStartsAt": "2026-10-01T07:30:00.000Z",
"resourceId": "3f6c1a52-8d1e-4c3b-9a0f-2b7e5d4c1a90",
"clientId": "9b2e7d14-5a3c-4f81-b6d2-0c9e8a7f3b15",
"priceTotalMinor": 250000,
"discountMinor": 0,
"paidMinor": 0,
"prepayStatus": "none",
"source": "online",
"srcTag": "instagram",
"cancelledBy": "client",
"changed": [
"priceTotalMinor"
]
}
}Подпись — Standard Webhooks
Каждый запрос подписан по стандарту Standard Webhooks: заголовки webhook-id, webhook-timestamp, webhook-signature (HMAC-SHA256). Проверяйте готовой библиотекой standardwebhooks — она есть для JS, Python, Go, PHP и других языков — по сырому телу запроса, до разбора JSON. Запрос старше 5 минут библиотека отвергнет.
JavaScript (Node.js, Express)
// npm install standardwebhooks express
import express from 'express';
import { Webhook } from 'standardwebhooks';
const wh = new Webhook(process.env.IPLANNER_WEBHOOK_SECRET); // whsec_…
const app = express();
// сырое тело: подпись считается по байтам, а не по разобранному JSON
app.post('/hooks/iplanner', express.raw({ type: '*/*' }), (req, res) => {
let event;
try {
event = wh.verify(req.body.toString('utf8'), req.headers);
} catch {
return res.sendStatus(400); // подпись не сошлась или запрос устарел
}
// event.id — отбивайте повторы; event.type — ru.iplanner.appointment.…
res.sendStatus(204);
handle(event); // тяжёлую работу — после ответа
});Python (Flask)
# pip install standardwebhooks flask
import os
from flask import Flask, request
from standardwebhooks.webhooks import Webhook
wh = Webhook(os.environ["IPLANNER_WEBHOOK_SECRET"]) # whsec_…
app = Flask(__name__)
@app.post("/hooks/iplanner")
def iplanner():
try:
event = wh.verify(request.get_data(), dict(request.headers))
except Exception:
return "", 400 # подпись не сошлась или запрос устарел
# event["id"] — отбивайте повторы; event["type"] — ru.iplanner.appointment.…
handle(event)
return "", 204Повторы
Успех — любой ответ 2xx. Любой другой ответ, таймаут или обрыв — повтор по расписанию (пауза перед каждой попыткой): сразу → 5 с → 5 мин → 30 мин → 2 ч → 5 ч → 10 ч → 10 ч. Всего около 27 ч 35 мин; после этого событие считается недоставленным. Приёмник, который долго не отвечает, помечается сломанным — владелец кабинета увидит это в карточке подключения.
Порядок доставки не гарантирован, повтор возможен и после успеха: сверяйте id и время события. Отвечайте быстро, тяжёлую работу делайте после ответа. Проверить связь — кнопкой в карточке подключения: придёт событие ru.iplanner.ping с той же подписью.
Каталог событий
Тот же список отдаёт без ключа /api/v1/events. Список только растёт: новое событие не придёт, пока вы не отметите его в подключении.
Новая запись
ru.iplanner.appointment.createdЗапись создана — с витрины, из кабинета, через API или виджет. Перенос сюда не относится.
Запись перенесена
ru.iplanner.appointment.rescheduledВремя записи изменилось. У перенесённой записи новый id, прежний — в previousId.
Запись передана другому мастеру
ru.iplanner.appointment.reassignedСменился мастер (и, возможно, время). Прежний мастер — в previousProfessionalId.
Запись подтверждена
ru.iplanner.appointment.confirmedМастер или администратор подтвердил запись.
Клиент пришёл
ru.iplanner.appointment.startedВизит начался — клиент на месте.
Визит завершён
ru.iplanner.appointment.completedВизит закрыт — вручную или автоматически по окончании времени.
Запись отменена
ru.iplanner.appointment.cancelledЗапись отменена клиентом, мастером или системой (например, не внесена предоплата). Кто отменил — в cancelledBy.
Клиент не пришёл
ru.iplanner.appointment.no_showВизит отмечен неявкой.
Запись удалена
ru.iplanner.appointment.deletedЗапись убрана из раздела «Записи». Время освобождено.
Запись возвращена в работу
ru.iplanner.appointment.reopenedОтменённая, удалённая или отмеченная неявкой запись снова действует.
Предоплата получена
ru.iplanner.appointment.prepaidПо записи отмечена полученная предоплата.
Запись изменена
ru.iplanner.appointment.updatedИзменились состав, сумма, скидка, оплата, место или клиент записи. Какие поля — в changed.
Персональные данные
В событиях имени и телефона клиента нет. Снимок записи в событии. Имени и телефона клиента нет — только clientId. По clientId и id записи вы запрашиваете подробности через API.
В API имя и телефон клиента есть только у ключа с правом clients.view («Имя и телефон клиента»). В записях появляются имя и телефон клиента. Без этого права — только номер клиента. Отмечайте это право, только если ваша система действительно должна знать клиента, и храните полученное по правилам 152-ФЗ.
OpenAPI
Машиночитаемое описание — OpenAPI 3.1, открыто без ключа: /api/v1/openapi.json. Его можно загрузить в Postman, Insomnia или генератор клиента. Эта страница и описание собираются из одного источника и не расходятся.