Mini-player API
API возвращает состояние контента для собственного интерфейса. Для готового виджета используйте mini-player Web SDK; для нативного приложения — Mobile SDK.
Схема режимов Web PiP показывает превью записи, live, Continuous Video и постер в готовом виджете. Их отображением управляет Web SDK.
Запрос stock-check к API магазина выполняет код клиента; mini-player API этого не делает.
Состояние по товару
GET https://app.shopstory.live/v2/mini-player/stream-state?application=<application-id>&feedProductId=<feed-product-id>
Accept: application/json
| Параметр | Обязательно | Описание |
|---|---|---|
application | Да | Выданный ShopStory идентификатор приложения. Он не является секретом или способом авторизации. |
feedProductId | Да для новых интеграций | Канонический строковый идентификатор товара из согласованного фида. |
productCode | Только по legacy-контракту | Строковый артикул продавца для ранее согласованных интеграций с поиском по vendorCode. |
feedProductGroupId | Только по legacy-контракту | Дополнительная группа товара. Используется только вместе с productCode, если такой маппинг уже согласован. |
В новой интеграции используйте один feedProductId во всех поверхностях. Не чередуйте его с productCode и не передавайте оба параметра одновременно. Идентификаторы должны оставаться строками, включая ведущие нули.
Найден live или VOD
{
"serverTime": "2025-01-15T10:00:00.000Z",
"status": 200,
"body": {
"status": "active",
"stream": {
"streamId": "stream-123",
"streamStatus": "completed",
"productId": "product-456",
"feedProductId": "0001001",
"playbackLink": "https://media.example.net/stream.m3u8",
"previewUrl": "https://media.example.net/preview.webm",
"posterUrl": "https://media.example.net/poster.jpg",
"startTime": 120,
"mediaOrientation": "portrait",
"playerUrl": "https://app.shopstory.live/sdk/"
}
}
}
Поле body.stream | Обязательно | Описание |
|---|---|---|
streamId | Да | Строковый идентификатор эфира. |
streamStatus | Да | online или completed. |
productId | Да | Внутренний идентификатор товара ShopStory. |
feedProductId | Нет | Идентификатор из фида. Может отсутствовать у ранее загруженных товаров или при поиске по productCode. |
playerUrl | Да | Готовый HTTPS URL WebView-плеера. Считайте его непрозрачным и передавайте без изменения. |
mediaOrientation | Да | portrait, landscape, square или unknown. |
playbackLink | Да | Совместимое поле медиапотока. Не определяйте по нему видеопровайдера и не собирайте из него playerUrl. |
previewUrl, posterUrl | Нет | Готовые HTTPS URL превью и статического постера. Превью может быть видео или анимированным изображением в зависимости от профиля. Используйте URL без изменения; не подменяйте расширение файла. |
startTime | Нет | Неотрицательное смещение релевантного эпизода VOD в секундах. |
В ручной web-интеграции открывайте playerUrl без изменения. В нативном приложении Mobile SDK выполняет lookup и возвращает типизированный entrypoint, а приложение отдельно передаёт его в SDK coordinator для открытия плеера. Не конструируйте URL плеера из streamId, playbackLink или других полей.
Ответ может содержать дополнительные диагностические поля. Игнорируйте неизвестные поля и не используйте их для бизнес-логики.
Связанного эфира нет
Когда связанный live или VOD не найден, API возвращает HTTP 200 с no_active_stream:
{
"serverTime": "2025-01-15T10:00:00.000Z",
"status": 200,
"body": {
"status": "no_active_stream",
"stream": null
}
}
Это штатное отсутствие готового контента: с товаром может не быть связанного эфира либо его запись ещё не готова к показу. В Web SDK товарный PiP в этом состоянии не загружает превью или HLS. В ручной интеграции также скрывайте точку входа и не запрашивайте медиа.
Сейчас API возвращает no_active_stream. Неизвестное значение status обрабатывайте как отсутствие контента: скрывайте точку входа и не открывайте stream.
Ошибки запроса
Этот эндпоинт выставляет HTTP-код ошибки и повторяет его в JSON-конверте:
{
"serverTime": "2025-01-15T10:00:00.000Z",
"status": 400,
"body": {
"error": "invalid",
"message": "Bad request: either 'productCode' or 'feedProductId' must be provided"
}
}
- HTTP
400— отсутствуетapplicationлибо оба идентификатора товара. - HTTP
500— серверная часть не смогла сформировать воспроизводимый источник.
Скрывайте контейнер при no_active_stream, транспортной ошибке, невалидном ответе или если playerUrl отсутствует либо не является HTTPS URL.
Текущий live
GET https://app.shopstory.live/v2/mini-player/online?application=<application-id>
Accept: application/json
При наличии эфира body.online содержит streamId, streamStatus: "online" и playbackLink. Игнорируйте неизвестные дополнительные поля.
Если live сейчас нет, эндпоинт возвращает успешный ответ с пустым объектом body:
{
"serverTime": "2025-01-15T10:00:00.000Z",
"status": 200,
"body": {}
}
Отсутствующий application возвращает HTTP 400 и такой же status в конверте.
Краткое состояние эфира
GET https://app.shopstory.live/v3/translation/quick-state?translationId=<stream-id>
Accept: application/json
{
"status": 200,
"serverTime": "2025-01-15T10:00:00.000Z",
"body": {
"translationState": "completed",
"translationId": "stream-123",
"expires": "2025-01-15T10:01:00.000Z"
}
}
translationState принимает draft, confirmed, online, completed или пустую строку, если состояние неизвестно. Отсутствующий translationId возвращается как HTTP 200 с status: 400 внутри конверта.
Если вызываете эндпоинт периодически, обрабатывайте HTTP 429 и 5xx с увеличивающейся задержкой и случайным разбросом. Не используйте его для проверки товарного остатка.
Мобильные приложения
В нативном приложении lookup и открытие выполняются через Mobile SDK. Lookup возвращает active, unavailable или техническую ошибку. Для active приложение передаёт entrypoint в SDK coordinator, после чего host app открывает плеер.
WebView bridge из web-примеров в mobile contract не входит. Открывайте плеер через SDK coordinator. Маршрутизация товара и добавление в корзину остаются в приложении продавца. Оно получает текущий остаток, цену, авторизацию и результат операции из своих commerce-систем. Точная версия пакета и host contract передаются в integration handoff.
Диагностика
| Наблюдение | Значение | Проверка |
|---|---|---|
body.status: "no_active_stream" | Для идентификатора нет готового live/VOD. | Сверьте feedProductId или согласованный productCode с фидом и привязкой эфира. |
body.status: "active", виджета на странице нет | Серверная часть нашла эфир, но web-компонент не отрисован. | Проверьте домен, CSP и настройку шаблона карточки товара. |
| Вместо движущегося превью виден постер | Браузер не поддерживает кодек либо медиа не загрузилось. | Проверьте поддержку VP9, запрос к previewUrl и ошибки media/CSP в браузере. |
| Во время эфира в PiP нет live | Режим Live в PiP не включён в конфигурации проекта либо эфир не связан с товаром. | Проверьте streamStatus: "online" в ответе stream-state и согласуйте включение режима с ShopStory. |
| После перехода из плеера началось короткое превью | Условия Continuous Video не выполнены. | Проверьте включение режима, общий origin, ту же вкладку, доступность sessionStorage и совпадение товара/эфира. |
| Continuous Video воспроизводится без звука | Браузер мог отклонить autoplay со звуком. | Включите звук кнопкой PiP; проверьте сценарий на целевых устройствах. |
body.online отсутствует | Текущего live нет. | Проверяйте VOD через stream-state для известного товара. |
translationState: "completed" | Эфир завершён. | Используйте playerUrl из stream-state для связанного товара. |