Разделы справки
Для разработчиков
Внешний API, identity контакта, витрина, покупки и платежи, вебхуки и проверка подписи, повторы.
Этот раздел для того, кто подключает сайт, бот или другую систему к Истоку. Здесь главное, чтобы начать; полный список полей смотрите в ответах API.
Подключение сайта
Интеграция в Истоке создаётся владельцем или администратором проекта в «Настройках» на вкладке «Интеграции». Вам передадут API-ключ вида istk_… и, если вы принимаете события, секрет вебхука whsec_….
Все запросы идут на https://<адрес Истока>/api/v1/… с заголовком:
Authorization: Bearer istk_…
Проект в запросах не указывается: он определяется ключом. Проверить ключ проще всего так:
GET /api/v1/me
В ответе интеграция с её подписками и проект. Выключенная или удалённая интеграция, как и перевыпущенный ключ, получает 401.
Ключ и секрет
Ключ даёт доступ к данным проекта, секрет нужен только для проверки подписи вебхуков. Ключ и секрет меняются независимо: «Перевыпустить» в карточке интеграции сразу отзывает старый ключ, «Перегенерировать» меняет секрет. Храните оба на сервере; в браузерный код они попадать не должны.
Identity контакта
Внешняя система не знает внутренних номеров контактов. Вместо этого контакт определяется значениями полей идентификации, заданных в проекте: обычно это почта или телефон. Ключи полей видны в «Настройках» на вкладке «Поля контактов» в столбце «Ключ».
Создать или обновить контакт:
PUT /api/v1/contacts
{"values": {"pochta": "anna.sokolova@example.com", "imya": "Анна Соколова", "status": "Новый"}}
Если контакт с такой почтой уже есть, значения дописываются к нему, и в ответе created: false. Все поля идентификации в values обязательны, остальные по желанию. Значения должны соответствовать типам полей: число для числового поля, true/false для булева, дата в формате YYYY-MM-DD, значения списков ровно как в настройках.
В остальных запросах контакт передаётся полем identity с теми же ключами:
{"identity": {"pochta": "anna.sokolova@example.com"}}
Каталог и витрина
| Запрос | Что возвращает |
|---|---|
POST /api/v1/products/search |
Активные продукты с поиском, фильтрами по характеристикам и сортировкой; в каждом количество предложений и минимальная цена |
GET /api/v1/products/{id} |
Продукт с активными предложениями |
POST /api/v1/showcase с identity |
Витрина конкретного контакта: только то, что ему доступно по условиям продукта и предложения |
Цены везде в копейках: 24000_00 это 24 000 ₽. Картинки приходят в пяти размерах: thumb, small, medium, large и original, это готовые адреса.
Покупки и платежи
Покупка без оплаты через Исток:
POST /api/v1/purchases
Idempotency-Key: order-1287
{"identity": {"pochta": "…"}, "offer_id": 8, "price": 350000}
Покупка создаётся в статусе «Ожидает оплаты»; price необязателен, по умолчанию берётся цена предложения. Дальше POST /api/v1/purchases/{id}/confirm отмечает её оплаченной, POST /api/v1/purchases/{id}/cancel отменяет. Есть также GET /api/v1/purchases/{id} и POST /api/v1/purchases/search по identity.
Покупка с оплатой через Робокассу:
POST /api/v1/payments
Idempotency-Key: order-1288
{"identity": {"pochta": "…"}, "offer_id": 9, "customer_email": "…"}
В ответе payment_url для покупателя и expires_at: ссылка действует 24 часа. customer_email попадёт в чек. Предложение должно быть доступно этому контакту, иначе 409. Состояние платежа можно проверить через GET /api/v1/payments/{id}, но надёжнее подписаться на события «Оплата прошла» и «Оплата не прошла».
Заголовок Idempotency-Key защищает от дублей при повторе запроса: с тем же ключом вернётся уже созданная покупка или платёж.
Вебхуки и проверка подписи
Событие приходит на Webhook URL интеграции POST-запросом с JSON:

Конверт события:
{
"id": 39,
"type": "purchase.status_changed",
"occurred_at": "2026-09-17T16:15:14.945001+00:00",
"origin": {"kind": "integration", "integration_id": 1},
"data": {…}
}
origin говорит, кто вызвал событие: сотрудник в админке (user) или интеграция. Так вы отличите свои же действия от чужих. Состав data зависит от типа: у событий контакта это values, у покупки — purchase_id, offer_id, product_id, price, status, old_status, new_status и contact, у платежа — данные платежа вместе с покупкой и контактом.
Подпись в заголовке X-Istok-Signature: t=<unix time>,v1=<hex>. Это HMAC-SHA256 от строки "<t>." + тело запроса с секретом вебхука. Проверка на Python:
import hmac, hashlib
def verify(secret: str, header: str, body: bytes) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
signed = f"{parts['t']}.".encode() + body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
Считайте подпись от байтов тела как они пришли, до разбора JSON. Отвечайте 2xx в течение 10 секунд; редиректы Исток не выполняет и считает ошибкой.
Типы событий:
| Группа | Код | Когда |
|---|---|---|
| Контакты | contact.created, contact.updated, contact.deleted |
Контакт создан, изменены поля, удалён |
| Покупки | purchase.created, purchase.status_changed |
Покупка создана; сменился статус |
| Оплата | payment.succeeded, payment.failed |
Платёж прошёл; платёж отклонён, просрочен или отменён |
| Каталог | product.created, product.updated, product.deleted, offer.created, offer.updated, offer.deleted |
Изменения продуктов и предложений |
Повторы и лог
Если ваш сервер не ответил 2xx, Исток повторяет доставку: паузы 1, 3, 9, 27 и 81 минута, затем около 4 часов и дважды по 12 часов, всего 8 попыток. После восьмой событие получает статус «Не доставлено» и больше не отправляется. Порядок доставки при повторах не гарантируется: ориентируйтесь на occurred_at.
Пока интеграция выключена, события копятся и уйдут после включения. Записи о доставках хранятся 30 дней и видны в карточке интеграции на вкладке «Лог доставок»: там же код ответа вашего сервера и текст ошибки.