Начало
Совместимость и ограничения
Что мок повторяет за боевым сервисом точно, а в чём отличается от него заведомо и намеренно.
На этой странице · 4
Мок полезен ровно настолько, насколько понятно, где он совпадает с боем, а где нет. Ниже — обе половины, без округления в свою пользу.
Что повторяется точно
Адресация и глаголы. Путь после префикса стенда — тот же, что у боевого
сервиса. У Ozon и Wildberries значим HTTP-метод: GET там, где в спецификации
только POST, даст 404. У Bitrix24 глагол не значит ничего, имя метода лежит
в пути — и это повторено намеренно: боевой портал разрешает звать один и тот же
crm.deal.add и через GET с query, и через POST с JSON или form-urlencoded.
Место ключа. Authorization у Wildberries, Client-Id с Api-Key у Ozon,
путь /rest/{user_id}/{code}/… или параметр auth= у Bitrix24 — включая ключ
внутри JSON-тела. Суффикс .json / .xml и сегмент с секретом вебхука
отрезаются до маршрутизации, как это делает портал.
Схемы ответов. Тело собирается из официальной спецификации: сначала готовый пример, если он в ней есть, иначе — генерация по схеме метода. Форма ответа, имена полей и вложенность совпадают со спецификацией на дату снимка.
Конверты ошибок. У каждого сервиса свой, дословно. Wildberries:
{"title":"Too Many Requests","detail":"rate limit exceeded","code":"TooManyRequests",
"requestId":"36170ddaa809e86093bdbecb84fd2482","origin":"ag-api","status":429,
"statusText":"too_many_requests","timestamp":"2026-09-09T10:14:24.992Z"}
Bitrix24 на то же превышение отвечает не 429, а 503:
{"error":"QUERY_LIMIT_EXCEEDED","error_description":"Too many requests"}
Лимиты. У каждого сервиса свой профиль: окно, ёмкость всплеска, код ответа
и наличие Retry-After.
Профили лимитов
У Apify лимит принадлежит методу, а не сервису: 400 запросов в секунду на запуски и датасеты, 200 на записи key-value store, 90 на профиль пользователя, 60 на всё остальное. Разбор — в Лимитах.
Политика доставки событий. Тоже свойство сервиса, а не транспорта: у Bitrix24
события уходят x-www-form-urlencoded и повторов нет вообще, у Ozon успехом
считается 200 и тело {"result": true}, у Wildberries — строго 200 за 10 секунд,
с подписью HMAC-SHA256 в X-Hub-Signature и пачками до 100 событий в запросе,
а у Apify — любой 2xx за две минуты и одиннадцать повторов с удваивающимся
интервалом, от минуты до примерно тридцати двух часов.
Единая сетка повторов на всех сервисах давала бы ложную картину ровно в том
сценарии, ради которого инструмент и нужен: «что будет, если мой обработчик упал».
В чём мок заведомо отличается
Данных сервисов внутри нет
Ни одного боевого заказа, товара, контакта или ключа. Всё, что отдаёт стенд, — пример из спецификации или значение, вычисленное детерминированным генератором. Проверять на APIStend бизнес-логику, завязанную на реальные остатки или суммы, бессмысленно: числа правдоподобны по форме и выдуманы по существу.
Ответ не зависит от параметров запроса. Успешное тело — чистая функция от
метода, сценария и объёма демо-данных. Фильтры, пагинация и идентификаторы
в запросе на него не влияют: crm.deal.get?ID=777 вернёт ту же карточку, что
и без параметра, а ?limit=1 и ?limit=999 дадут байт в байт одинаковый ответ.
Именно этот детерминизм позволяет кешировать ответы и закреплён тестом; но это
и главное расхождение с боем.
Запись ничего не меняет. POST-методы отвечают штатным успехом и не создают
состояния: созданная сделка не появится в следующем списке. Подробнее —
в разделе Основные понятия.
CORS разрешён всем. Боевые Ozon и Wildberries запросов из браузера не
разрешают. Шлюз APIStend отдаёт Access-Control-Allow-Origin: * на всех адресах
песочницы — и честно помечает это заголовком X-APIStend-CORS: added-by-sandbox.
Код, который работает в браузере против стенда, в бою упрётся в CORS: это
удобство отладки, а не совместимость.
Ответ несёт лишние заголовки — но только свои. Боевые заголовки сервиса
приходят ровно те же, что в бою: у Wildberries X-Request-Id и счётчики
X-Ratelimit-*, у Ozon x-o3-trace-id, у Битрикс24 ни того ни другого,
зато конверт time в теле. Сверх этого шлюз добавляет свои —
X-APIStend-Source, -Readiness, -Scenario, -Upstream, -Snapshot,
-Request-Id, а на 404 подсказку X-APIStend-Did-You-Mean с похожими путями
каталога. В бою их нет; ни одна клиентская библиотека их не читает, поэтому
они ничего не ломают. Так и задумано: мок обязан быть неотличим по телу,
коду и заголовкам ответа — и отличим по метаданным.
Задержка и ошибки — настройка, а не реальность. Искусственная задержка (по умолчанию 250 мс) и доля случайных ошибок (по умолчанию выключена) не измеряют ничего: это регуляторы, которыми вы проверяете свой код. К скорости и надёжности боевых сервисов они отношения не имеют.
Лимит считается на ключ. Боевой сервис считает на аккаунт продавца или на портал. У ключа, у сессии кабинета и у локального приложения Bitrix24 счётчики здесь свои.
Ответ всегда JSON. Суффикс .xml у метода Bitrix24 принимается и отрезается,
но тело приходит в application/json; charset=utf-8. XML-ответа портала стенд
не воспроизводит.
Доставка на localhost устроена иначе. Боевой сервис требует публичный адрес.
Здесь событие забирает агент из npm-пакета apistend по WebSocket-туннелю,
который инициирует ваша машина, — поэтому работает из-за NAT и корпоративного
файрвола. На публичном стенде доставка на приватные адреса (localhost, 10/8,
192.168/16, ::1) может быть запрещена настройкой WEBHOOK_ALLOW_PRIVATE_TARGETS:
адрес из чужой песочницы иначе стал бы каналом во внутреннюю сеть.
Журнал не хранит тела успешных ответов. Они детерминированы и
восстанавливаются движком при открытии карточки запроса. Тела ошибок хранятся.
Выше 300 запросов в секунду журнал прореживается, и доля выборки видна
и в /health, и в интерфейсе; срок хранения записей — 30 дней.
Счётчики ключа отстают. «Последнее использование» и число запросов за сутки записываются пачкой примерно раз в десять секунд, а не на каждом вызове.
Чего в продукте нет
Чтобы не искать: подтверждения почты, восстановления пароля, входа через сторонние провайдеры и SSO; ролей и совместной работы в одной песочнице; второй песочницы из кабинета; тарифов и лимитов на количество ключей или запросов; страницы статуса и обязательств по доступности. Это не «пока не описано» — этого нет в коде.
Если совпадения не хватает
Ответ нужной формы можно задать руками — свои моки живут на отдельном адресе
/custom/… с любым телом, кодом ответа, задержкой и заголовками; такой ответ
помечается X-APIStend-Source: custom-mock. Заменить этим путь боевого сервиса
нельзя: /custom/ — самостоятельный префикс рядом с /b24, /oz и /wb,
а не подмена метода в каталоге. Метод, которого в каталоге нет, отвечает родным
404 сервиса с подсказкой по похожим путям в X-APIStend-Did-You-Mean.