Public API Quickstart
Public API подходит для собственного интерфейса поверх данных ShopStory, доступных только для чтения. Для готовых web-компонентов используйте Web SDK, для видео в нативном приложении — Mobile SDK.
Проверить пример локально
Скачайте API starter. Нужен Node.js 22+. В архиве есть скрипт запроса и непустой синтетический fixture со связанными ID эфира и товара.
node request-streams.mjs --fixture streams.fixture.json
Ожидаемый результат: запись stream-vod-1, статус finished, строковый товарный ID 0001001. Это проверка API-клиента без сетевого запроса; fixture не запускает SDK и не подтверждает воспроизведение. Для реальных данных задайте SHOPSTORY_APPLICATION_ID и выполните node request-streams.mjs.
Следующий шаг — схема ответа API, карточки каталога и плеера: в том же ZIP есть browser-пример с товарами и вызовом основного Web SDK на реальных данных.
До запроса
Получите у команды ShopStory:
applicationIdпроекта.- Подтверждение нужного окружения.
- Регистрацию точного origin, если запрос будет выполняться из браузера.
- Тестовый эфир или подтверждение, что пустая выборка сейчас ожидаема.
applicationId выбирает конфигурацию проекта. Он виден в браузерных запросах и не является паролем. Не используйте его как доказательство полномочий для операций с корзиной, заказом или персональными данными.
Первый запрос
Для cURL-примера нужны curl с поддержкой --fail-with-body и jq. Для Node.js — версия 22+.
Первый запрос выполните из терминала или с сервера клиента: ограничения браузерного CORS там не действуют.
- cURL
- Node.js
export SHOPSTORY_APPLICATION_ID="assigned-application-id"
set -o pipefail
curl --silent --show-error --fail-with-body --max-time 8 --get \
"https://app.shopstory.live/v3/streams" \
--data-urlencode "applicationId=${SHOPSTORY_APPLICATION_ID}" \
--data-urlencode "limit=3" \
--data-urlencode "offset=0" \
| jq -e '
if .status != 200 then
error(.body.message // "ShopStory request failed")
elif ([.body.availableStreams, .body.plannedStreams,
.body.products, .body.streamers, .body.categories]
| all(type == "array") | not) then
error("Expected catalog collection arrays")
else
{
status,
total: .body.total,
available: (.body.availableStreams | length),
planned: (.body.plannedStreams | length)
}
end
'
const applicationId = process.env.SHOPSTORY_APPLICATION_ID;
if (!applicationId) {
throw new Error('SHOPSTORY_APPLICATION_ID is required');
}
const url = new URL('https://app.shopstory.live/v3/streams');
url.search = new URLSearchParams({
applicationId,
limit: '3',
offset: '0',
}).toString();
const response = await fetch(url, {
signal: AbortSignal.timeout(8_000),
});
if (!response.ok) {
throw new Error(`ShopStory HTTP ${response.status}`);
}
const payload = await response.json();
if (!payload || !Number.isInteger(payload.status)) {
throw new Error('Invalid ShopStory response envelope');
}
if (payload.status !== 200) {
throw new Error(payload.body?.message || `ShopStory status ${payload.status}`);
}
const collections = ['availableStreams', 'plannedStreams', 'products', 'streamers', 'categories'];
if (!payload.body || collections.some(name => !Array.isArray(payload.body[name]))) {
throw new Error('Expected catalog collection arrays');
}
console.log({
total: payload.body.total,
available: payload.body.availableStreams.length,
planned: payload.body.plannedStreams.length,
});
Количество элементов зависит от проекта и текущих публикаций. Smoke-тест прошёл, если получены HTTP 200, верхнеуровневый status: 200 и массивы в body.
Пример успешного ответа:
{
"status": 200,
"body": {
"availableStreams": [],
"plannedStreams": [],
"products": [],
"streamers": [],
"categories": [],
"total": 0
},
"serverTime": "2025-01-15T10:15:30.000Z"
}
Пустые массивы могут быть корректным результатом. Они не доказывают проблему доступа.
Ошибка параметров
Некоторые /v3/* возвращают валидационную ошибку внутри JSON-конверта при транспортном HTTP 200:
{
"status": 400,
"body": {
"error": "invalid",
"message": "invalid applicationId"
},
"serverTime": "2025-01-15T10:15:30.000Z"
}
Всегда проверяйте оба уровня. Схема проверок ответа и общая функция обработки приведены в разделе «Формат запросов и ответов».
Фильтры и пагинация
GET /v3/streams поддерживает:
| Параметр | Назначение |
|---|---|
limit | Размер страницы. Значения выше 100 обрабатываются как 100. |
offset | Смещение от начала выборки |
feedProductId | Точный ID товара из согласованного фида |
categoryId | Категория ShopStory |
status | planned, online или finished |
Фильтры объединяются. Не преобразуйте товарные ID в числа:
export SHOPSTORY_APPLICATION_ID="assigned-application-id"
export SHOPSTORY_PRODUCT_ID="product-id-from-feed"
curl --silent --show-error --fail-with-body --max-time 8 --get \
"https://app.shopstory.live/v3/streams" \
--data-urlencode "applicationId=${SHOPSTORY_APPLICATION_ID}" \
--data-urlencode "feedProductId=${SHOPSTORY_PRODUCT_ID}" \
--data-urlencode "limit=10"
Полная схема: Каталог эфиров.
Используйте одно строковое значение feedProductId в товарном фиде, на web-PDP, в native-PDP и в product action. Не вводите отдельный mobile-ID. Если commerce API ритейлера принимает другой ключ, преобразуйте его на границе commerce-системы.
Запуск в браузере
Браузерный запрос разрешён только с origins, зарегистрированных ShopStory для проекта. Если запрос из терминала или с сервера работает, а браузер показывает ошибку CORS:
- Сверьте точный scheme, hostname и port текущей страницы.
- Убедитесь, что запрос направлен в нужное окружение.
- Передайте origin менеджеру интеграции ShopStory.
Не обходите CORS открытым relay и не добавляйте учётные данные в URL. Сервер клиента может применять собственные правила доступа, кеширования и наблюдаемости. applicationId остаётся видимым идентификатором.
Production-чеклист
- HTTP-запрос имеет ограниченный тайм-аут на стороне клиента.
- Проверяются HTTP-код, JSON-конверт и состояние ресурса.
- Интерфейс различает загрузку, пустую выдачу и ошибку.
- Новые необязательные поля не ломают парсер.
- Идентификаторы остаются строками.
- Повторные запросы ограничены и выполняются с backoff.
- Сбой ShopStory не блокирует основной каталог или checkout клиента.
- Реальные пароли, cookies и токены не вставляются в публичные онлайн-инструменты.