Мок-API
Заголовки ответа
Боевые заголовки каждого сервиса плюс собственные X-APIStend-* — что приходит, у кого чего нет и почему набор разный.
На этой странице · 6
Заголовки ответа делятся на две части, и это не формальность, а правило, по которому здесь всё устроено.
Боевые заголовки сервиса — те, что отдал бы настоящий Wildberries, Ozon или Битрикс24. Их набор у каждого свой, и APIStend повторяет его буквально: ничего не добавляет и ничего не убирает. Именно поэтому подмена базового адреса не ломает клиентскую библиотеку — она читает то же, что читала в бою.
Заголовки APIStend — всё, что начинается с X-APIStend-. Их в бою нет
и быть не может; они отвечают на вопрос «откуда взялось это тело и насколько
ему верить». Ни одна боевая библиотека их не читает, поэтому они ничего
не ломают, а вам позволяют пользоваться моком осознанно.
Боевые заголовки: у каждого сервиса свои
Разница в Content-Type не косметическая: Битрикс24 и Apify приходят с charset,
Ozon и Wildberries — без него. Строгие клиенты это сравнивают.
Колонка Apify показывает третий вариант поведения с лимитом, которого до неё
в стенде не было: сервис сообщает потолок, но не остаток. Клиент, написанный
на чтении X-Ratelimit-Remaining, в бою получит undefined — и в моке получит
его же. Вдобавок у Apify лимит зависит от эндпоинта, а не от сервиса:
подробности в Лимитах.
Списковые ответы Apify дублируют конверт data в заголовки
X-Apify-Pagination-Total, -Offset, -Count, -Limit, -Desc. Значения мок
берёт из того самого тела, которое отдаёт, поэтому заголовок разойтись с телом
не может — иначе листающий клиент ушёл бы в бесконечный цикл.
Идентификатор запроса у Wildberries продублирован в теле ошибки — поле
requestId спецификация прямо называет копией заголовка X-Request-Id.
У APIStend это одно и то же значение, и оно же лежит в журнале кабинета:
разработчик приносит в поддержку то число, которое увидела его библиотека.
Живой ответ Wildberries:
HTTP/1.1 200 OK
content-type: application/json
x-request-id: fd92ca05545b4fe9edcf61a7c1189c58
x-ratelimit-limit: 300
x-ratelimit-remaining: 299
x-ratelimit-reset: 1
x-apistend-request-id: fd92ca05545b4fe9edcf61a7c1189c58
x-apistend-source: schema
x-apistend-readiness: updating
x-apistend-scenario: success
x-apistend-upstream: https://marketplace-api.wildberries.ru
x-apistend-snapshot: 2026-09-07
x-apistend-cors: added-by-sandbox
Тот же вызов у Ozon — ни одного заголовка лимита, вместо x-request-id
сквозной идентификатор платформы:
HTTP/1.1 200 OK
content-type: application/json
x-o3-trace-id: f0c9ea91aae8abf9
x-apistend-request-id: f0c9ea91aae8abf9
x-apistend-source: example
x-apistend-readiness: ready
А у Битрикс24 нет и его: портал не отдаёт идентификатора запроса вовсе, зато
к каждому ответу прикладывает конверт time — с длительностью вызова
и с operating_reset_at, по которому клиент судит об остатке ресурса.
Конверт time приходит всегда
Даже там, где в документации Битрикс24 его в примере нет. Библиотеки вроде
bitrix24-php-sdk разбирают time как обязательное поле, и ответ без него
уронил бы рабочую интеграцию на разборе. Значения в нём — настоящие: сколько
шёл именно ваш вызов, а не переписанные из примера документации.
Заголовки APIStend
X-APIStend-Request-Id есть всегда — в том числе у Битрикс24, где боевого
заголовка не существует. У Wildberries и Ozon он повторяет боевой.
Три яруса ответа
X-APIStend-Source — это ярус, на котором собрали тело.
Ярус связан с готовностью: example — ready, schema — updating,
generic — planned. Так метод и помечен в каталоге.
Ответ метода без примера и без схемы у Bitrix24 выглядит буквально так
(плюс конверт time, который портал добавляет всегда):
{"result":[],"total":0}
У Ozon в этом случае {"result":{}}, у Wildberries {}, у Apify {"data":{}}
(он заворачивает в data каждый ответ, и голый {} уронил бы клиента не там,
где тот ошибся). Метод с успешным кодом 204 отвечает пустым телом.
Зачем это в тестах
Тест, который проверяет разбор ответа, имеет право работать с любым ярусом.
Тест, который проверяет бизнес-логику по значениям полей, на schema
и generic проверяет выдуманные данные. Прочитайте X-APIStend-Source
в тесте и пометьте такой случай явно, вместо того чтобы удивляться
расхождению с боем.
Особые источники
Кроме трёх ярусов каталога, X-APIStend-Source принимает два значения,
у которых другое происхождение:
custom-mock— ответ отдал ваш собственный мок по префиксу/custom/;app-context— ответ про состояние портала Bitrix24 для локального приложения (app.info,placement.*,event.*). Такие ответы зависят от того, что приложение установило и зарегистрировало, а не от каталога. Рядом приходитX-APIStend-Appсclient_idприложения.
Заголовки на ошибках
Тело ошибки всегда остаётся родным конвертом сервиса, а причина отказа уходит
в X-APIStend-Error: в бою такого поля нет, и подмешивать его в тело нельзя.
На ответе с ошибкой авторизации заголовков X-APIStend-Source, Readiness
и Snapshot нет: метод до каталога не дошёл. Заголовков лимита там тоже нет —
считать его не на чем, ключ не опознан.
Подводные камни
Браузер видит не все заголовки
Из кода страницы читаются только заголовки, перечисленные в
Access-Control-Expose-Headers. Шлюз перечисляет там весь свой набор — боевые
боевые заголовки всех сервисов и все x-apistend-*, — но это касается только
запросов из браузера к песочнице. Боевые Ozon и Wildberries из браузера
вызывать нельзя вовсе, так что код, который так делает, в бою не поедет.
- Имена заголовков приходят в нижнем регистре; сравнивайте без учёта регистра.
- Не пишите обработку лимита по заголовкам Wildberries для всех сервисов: у Ozon и Битрикс24 их нет вовсе, у Apify есть только потолок без остатка — см. Лимиты.
X-APIStend-Snapshot— дата снимка спецификации, а не дата ответа. У методов одного сервиса она общая.X-APIStend-Upstreamпоказывает реальный хост метода. У Wildberries это не один адрес:marketplace-api,content-api,advert-apiи другие.