Quickstart, триал-как-sandbox и партнёрские sub-проекты
TL;DR: первая интеграция BOTIX в реальном агентстве заняла у разработчика 38 минут — мы рассчитывали на 5. За квартал время «регистрация → первый успешный запрос» упало до 4-7 минут. Три решения, которые это дали: quickstart как отдельный артефакт с ключом на первом экране, триал на той же production-инфраструктуре вместо отдельного sandbox, и один partner-key, который превращает пять минут агентства в десятки клиентских проектов.
Коротко
- Quickstart — не короткая документация, а отдельный артефакт. Ключ выдаётся на той же странице, первый блок кода виден без скролла, snippet с реальными значениями (curl + PHP/Python/Node). Между копированием кода и ответом — ноль промежуточных шагов.
- Отдельный sandbox не нужен — его роль играет триал на проде. Тот же контур, те же миграции, те же валидаторы и заголовки; отличия только в лимитах (
api_rate_per_minute30 против 2000), флагеapi_write_enabledи сроке 14 дней. Класс ошибок «в sandbox работало, в проде нет» исчезает. - Партнёрский слой закладывается заранее. Один partner-key + sub-проекты через API: агентство создаёт клиента одним POST за секунды, а не регистрирует 47 аккаунтов вручную. Изоляция —
Auth::assertProjectAccess()+WHERE project_id = ?в каждом запросе.
BOTIX — российская SaaS-платформа AI-ассистентов. Public API v1.1.0, база — https://api.botix.pro, эндпоинты под префиксом /public/v1/*, документация на developers.botix.pro, репозитории — github.com/BOTIX-pro. Ниже — не про «купите рекламу, чтобы привести разработчика», а про то, как убрать трение в первые две минуты, чтобы разработчик вернулся сам и рассказал коллегам. Три связанных решения — по одному на каждый узел developer experience: первый запрос, тестовая среда, масштабирование интегратора.
Узкое горлышко: первая встреча с API
Любой публичный API проходит через одно узкое горлышко — первую встречу с разработчиком. У неё нет второго шанса. Если человек тратит больше пяти-десяти минут на первый осмысленный запрос и не видит ответа — он закрывает вкладку. Это не лень, а фокус: он пришёл проверить гипотезу «подходит ли этот API под мою задачу», и каждая лишняя минута увеличивает шанс, что гипотеза не проверится вовсе.
Что дала первая итерация онбординга — та самая, на которой агентство мучилось 38 минут:
- Регистрация по email + подтверждение через ссылку. 1-3 минуты, иногда 10 (письмо в спаме).
- Логин, мастер настройки бота: выбор ниши, профиль бизнеса, подключение Telegram через token, импорт каталога. 15-25 минут.
- Поиск раздела API — он назывался «Интеграции» и был спрятан в третьем уровне меню. 1-2 минуты.
- Генерация ключа, копирование, переключение в IDE, первый запрос с подсматриванием в документацию. 5-15 минут.
- Первый запрос. Часто
INVALID_API_KEY/ 401 (не тот формат заголовка). Дополнительные минуты на отладку.
Итого около 38 минут на медиану. Для владельца барбершопа, пришедшего «сделать бота», — нормально: мастер и есть его продукт. Для разработчика, пришедшего проверить «подходит ли API», — катастрофа. Дальше — три раздела, каждый снимает одну из этих точек трения.
Решение 1. Quickstart как отдельный артефакт (тезис 06)
Документация отвечает на вопрос «как устроена система». Quickstart — на «как мне получить первый ответ прямо сейчас». Разные жанры, разная структура. Документацию читают последовательно и возвращаются к ней; quickstart читают один раз, по диагонали. Не увидел блок кода при пролистывании — ушёл.
Признаки правильного quickstart, которые легко проверить визуально:
- Первый блок кода виден без скролла, на первом экране после заголовка.
- API-ключ выдаётся прямо на этой же странице. Не «зарегистрируйтесь, подтвердите email, дождитесь письма, создайте проект, найдите вкладку API».
- Snippet содержит реальные значения, а не плейсхолдеры
YOUR_API_KEYилиhttps://api.example.com. - Есть переключатель языка: curl и два-три популярных языка с SDK.
- Между копированием кода и видимым результатом нет промежуточных шагов.
В обычном онбординге BOTIX триал начинается с мастера: ниша, профиль бизнеса, Telegram, каталог, приветственный сценарий. Владельцу бизнеса это нужно — его задача увидеть работающего бота под свою нишу. Разработчику это препятствие: он хочет понять форматы запросов и ответов, а не настраивать ассистента. Поэтому после регистрации с пометкой «я разработчик» (флаг is_developer_trial в проекте) система обходит мастер и открывает /developers/quickstart: выданный API-ключ (показанный один раз), четыре snippet-таба для curl, PHP, Python, Node; ссылки на полную документацию и Swagger UI на developers.botix.pro/try-it.
Первый snippet — curl, работает в любом терминале без установки SDK:
curl -X POST https://api.botix.pro/public/v1/contacts \
-H "Authorization: Bearer XXXXXXXX" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"phone":"+79991234567","name":"Test"}'Тот же запрос в Python через SDK:
from botix import Client
client = Client(api_key="XXXXXXXX")
contact = client.contacts.create(phone="+79991234567", name="Test")Никаких предварительных шагов, никакого выбора ниши. Триал должен решать вопрос «совместим ли API с моими нуждами», а не «умеете ли вы пользоваться платформой». То, что оба snippet генерируются из одной спецификации и не расходятся с curl, — отдельная тема: почему SDK лучше генерировать из OpenAPI, а не писать руками.
Одноразовый показ ключа — компромисс. Стандартный паттерн: показать ключ один раз, дальше хранить только хеш. Если база утечёт, восстановить рабочие ключи невозможно (по дизайну — потерянный ключ мы не восстанавливаем, только перевыпускаем). Но для quickstart это трение: скопировал, получил 401, переключил окна, потерял ключ. Компромисс BOTIX: ключ показывается один раз, но рядом кнопка «Перевыпустить» (аннулирует старый и сразу показывает новый). Правило «не хранить ключ в открытом виде в БД» сохранено, трение убрано.
Что должно быть в первом ответе. Первый запрос почти всегда заканчивается одним из четырёх исходов, и каждый требует подсказки:
- 200 — возвращённый объект с полями (id, время создания, статус), а не голый
{"id":123}. - 401 — явный код, что не так с ключом:
MISSING_API_KEY,INVALID_API_KEY,KEY_REVOKED. Без этого разработчик гадает. - 422 — список ошибок валидации по полям с указанием конкретного поля.
- 5xx — уникальный идентификатор запроса, который можно приложить к обращению в поддержку.
Что отрезали осознанно. В жанре quickstart допустимо не рассказывать про все коды ошибок (отдельная страница developers.botix.pro/error-codes), webhook-подписи (гайд на best-practices), OAuth (developers.botix.pro/oauth), идемпотентность в деталях (на quickstart одна строка: «обязательный заголовок Idempotency-Key, генерируйте UUIDv4; ключ действует 24 часа»), версионирование (developers.botix.pro/versioning). Каждая тема критична для production, но не для первого запроса — иначе страница раздувается и теряет жанр.
Решение 2. Триал на production-инфраструктуре (тезис 08)
Когда у платформы появляется публичный API, почти автоматически принимается решение: «нужен sandbox» — отдельный домен sandbox.api.example.com, база, ключи, панель, CI-пайплайн. Проблема в том, что любой второй контур — не половина прода, а отдельный продукт со своей жизнью, расходящейся с продом. Расходы больше, чем кажется на старте:
- Дублирование инфраструктуры. Свои серверы БД, очередей, кеша, воркеров. Стоят денег. Экономишь — sandbox отдаёт другие тайминги, тесты становятся ненадёжными.
- Дублирование миграций и фич. Любая новая фича — в оба контура. Команда забывает. Через полгода в sandbox устаревшие поля, неработающие endpoint'ы, отдельный тикет «синхронизировать sandbox с prod».
- Дублирование тестовых данных. Тоже устаревают: формат меняется, ссылочная целостность ломается из-за наполовину применённых миграций.
- Расхождение поведения. Самый болезненный пункт. Sandbox считается «безопасным» — в нём отключают часть проверок: rate-limit послабее, fraud-фильтры выключены, валидация мягче. Интеграция работает в sandbox, переключается на prod — падает на первом запросе. Это не лень разработчика, а архитектурное расхождение, заложенное командой платформы.
Подход BOTIX иной. Отдельного sandbox нет. Триальный кабинет физически живёт на том же production-контуре, но с жёсткими лимитами и флагами, ограничивающими побочные эффекты:
- Триальный проект пишет в ту же базу, что и платный.
- Запросы идут через те же FPM-воркеры, FastAPI-сервисы, Redis-очередь.
- Те же миграции, фичи, логика обработки ошибок.
- Те же rate-limit-лимиты (просто значения ниже), те же коды ошибок, те же заголовки в ответе.
Различия только в трёх местах:
- Лимиты тарифа.
api_rate_per_minuteдля триала — 30/мин, для бизнеса — 2000/мин;api_rate_per_day— от 1000 до 1000000. Логика одна: тот же механизм rate-limit, что увидят пользователи на проде, просто с более жёстким порогом. Лимиты хранятся в JSONlimitsкаждого тарифа (config/plans.php+btx_plans.limits), читаются черезPlanService::getLimit(). - Toggle on-write операций. У триала
api_write_enabled = false— все POST/PUT/DELETE возвращают 403TRIAL_READ_ONLY. Удобно для смоук-тестов: прогнать чтение без риска что-то изменить. Тот же тогл доступен и платным клиентам. - Срок жизни. Триал — 14 дней. После — read-only до оплаты. Не успел протестировать — заводишь второй триал или оплачиваешь минимальный тариф.
Разработчик тестирует ту же систему, которую увидит на проде — не её модель, не урезанную копию, не сборку трёхмесячной давности. Это убирает целый класс ошибок:
- «Поле было в sandbox, в проде нет» — невозможно, контур один.
- «В sandbox 200, в проде 422» — невозможно, валидаторы те же.
- «Webhook в sandbox отправляется, в проде нет» — невозможно, код обработчика тот же.
- «Заголовок rate-limit другого формата» — невозможно, middleware один.
Граница между триалом и продом — не в инфраструктуре, а в данных и правах. Триальный проект — просто запись в btx_projects с флагом is_developer_trial = true и тарифом «триал» со своими значениями в JSON limits. API-ключ триала видит только данные своего проекта. Чужие данные защищены той же логикой Auth::assertProjectAccess(), что и у платных клиентов. Идея «безопасной среды» реализуется не через изоляцию инфраструктуры, а через изоляцию проекта — и это правильный уровень. Где ещё встают решения этого класса (хранение ключей, polling или webhook), разбирается отдельно: архитектура интеграции без второго контура.
Сравнение по затратам команды:
| Затрата | dev/staging/prod | Триал-как-sandbox |
|---|---|---|
| Серверы | х2-х3 | х1 |
| Миграции | Каждую применить дважды | Один раз |
| Тестовые данные | Поддерживать отдельно | Не нужны |
| Документация | «Различия между sandbox и prod» | Не нужна |
| Тикеты «в sandbox работает, в prod нет» | Регулярно | Не возникают |
Где подход неприменим. Отдельный sandbox оправдан для: финансовых операций с реальным движением денег (тестовые карты или test_mode флаг на уровне ключа), действий с побочными эффектами на третьих лиц (SMS, push, email на боевые номера), тяжёлых операций с физическим миром (промышленное оборудование, доставка грузов). У нас все три обходятся флагами в модулях: у bot-preview есть $context['preview']=true — пишет в лог, но не отправляет реальное сообщение в Telegram. Это снимает риск побочных эффектов без второго контура.
Решение 3. Партнёрские sub-проекты — масштабирование интегратора (тезис 19)
Третий уровень DX, который мало кто делает заранее. Сценарий: агентство пробует API в триале, делает первый запрос за пять минут, видит, что работает. Дальше задача — масштабировать на 47 клиентов. Если нужно зарегистрировать 47 отдельных аккаунтов — это 5 минут × 47 ≈ 4 часа скучной работы, и половина агентств в этой точке отваливается.
У прямого клиента контур простой: один аккаунт, один проект, несколько ключей, один webhook. У партнёра — многоуровневый: сам партнёр имеет аккаунт у поставщика, внутри него десятки или сотни конечных клиентов, у каждого свой логический проект со своими данными, биллингом, webhook'ом. Пытаться удовлетворить это тем же API, что и обычных клиентов, — путь к ошибкам: обычный ключ работает в контексте одного проекта, партнёрский должен работать в контексте партнёрского аккаунта и переключаться между конечными.
Альтернатива вместо четырёх часов ручной регистрации — партнёрский аккаунт + sub-проекты. У агентства один аккаунт BOTIX, в нём отдельный тип ключа (partner-key) с правом создавать sub-проекты через API. Для каждого нового клиента — один POST:
curl -X POST https://api.botix.pro/public/v1/partner/projects \
-H "Authorization: Bearer XXXXXXXX" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"Барбершоп на Тверской","plan":"start"}'В ответе — новый project_id, новый API-ключ, готовый webhook-секрет. 5 секунд вместо 5 минут на каждого клиента.
Минимальный набор возможностей, без которого партнёрская модель не собирается:
- Партнёрский уровень аутентификации. Отдельный тип ключа (partner-key) с более высокими привилегиями, чем у обычного project-key: создавать проекты, перечислять существующие, получать ключи. Обращение к партнёрским эндпоинтам обычным ключом возвращает 403
INSUFFICIENT_SCOPE. - Sub-проекты под одним аккаунтом. Иерархия: партнёр сверху, набор конечных проектов снизу, у каждого свои данные, webhook, биллинг.
- Сырые usage-данные через API. Партнёр биллит конечных клиентов по своей модели: ему нужны количество запросов, сообщений, активных контактов по каждому sub-проекту за период — отдельным эндпоинтом или webhook-событием в конце расчётного периода.
- Audit-логи на партнёрском уровне. Когда конечный клиент пишет «не работает», партнёр диагностирует сам, не привлекая поставщика; доступ к журналу по sub-проектам регулируется тем же partner-ключом.
Изоляция данных — критическая граница. Внутри одного партнёрского аккаунта могут быть sub-проекты конкурирующих компаний. Защита на трёх уровнях: на уровне БД — WHERE project_id = ? в каждом запросе; на уровне API — явный project_id в каждом запросе и проверка, что он принадлежит партнёрскому аккаунту, выпустившему ключ; на уровне ключей — нельзя получить ответ по одному sub-проекту, передав ключ другого. В BOTIX Auth::assertProjectAccess($projectId) вызывается в начале каждого эндпоинта, работающего с проектом; партнёрский слой добавляет проверку, что sub-проект принадлежит выпустившему ключ аккаунту.
Чего не делать. Не навешивать партнёрские возможности на обычные эндпоинты через флаги «если ты партнёр, можешь передать ещё этот параметр» — запутанная семантика; лучше отдельный префикс. Не делать партнёрский API «по запросу» только избранным по NDA — работает, пока партнёров три; на двадцати начинаются разные SLA и теневая документация. Не ставить высокий минимальный объём для входа — из маленьких команд вырастают крупные.
Метрика, которая отвечает «работает ли quickstart»
Единственный полезный показатель — медианное время от просмотра quickstart до первого успешного API-запроса с того же ключа. У нас это поле time_to_first_api_call в таблице btx_developer_funnel. Текущая медиана — 4-7 минут (было 38). Меньше пяти — quickstart работает. Больше — трение, ищется через сессионные логи. Другие метрики (просмотры, время на странице, прокрутка) вторичны: quickstart нужен не для того, чтобы его читали, а для того, чтобы после него был работающий запрос.
Что отвергли по дороге
- Sandbox-окружение с отдельной БД — отказались в пользу триала на проде.
- Регистрация через подтверждение email до выдачи ключа. Для триала с
is_developer_trialподтверждение отложено: ключ выдаётся сразу, email подтверждается фоном до конца триала. Не подтверждён за 14 дней — триал замораживается. - API-ключ только через настройки кабинета. На quickstart ключ выдан сразу; разделы «Настройки → API» доступны позже для управления списком ключей.
- Один уровень тарифа в триале с урезанными фичами — создаёт расхождение «работает в триале, не в проде». В триале доступны все фичи (bulk-endpoints, OAuth, webhook), просто с жёсткими лимитами. Флаги
is_trial/write_enabled— не специальные исключения, а часть общей механики тарифов, работающей у всех клиентов одинаково.
Тенденция в индустрии
Stripe в 2010-х задал стандарт quickstart за 60 секунд. Триал на production-инфраструктуре — следующая волна: Vercel, Render, Supabase делают именно так. Партнёрская модель с sub-проектами через API — стандарт Stripe Connect, GitHub Apps, Shopify Partners; на российском рынке пока редкость. Открытые SDK как канал доверия и снижения интеграционного трения — та же логика: зачем компании open-source-ить SDK.
Попробуйте API BOTIX
Получите ключ, отправьте первый запрос и поймайте webhook — прямо в браузере, без боевого канала.
Попробовать API бесплатноЧитайте также
Онбординг разработчика: quickstart, sandbox и API-ключи
SDK BOTIX 1.1: zero-deps, генерация из OpenAPI и триал
Первый запрос к API за 5 минут: SDK из OpenAPI и триал
Quickstart, триал-sandbox и polling vs webhook
Почему в SDK ноль зависимостей и генерация из OpenAPI
