Skip to content

Определение подписки Джем ​

Что такое Джем ​

Джем — это тарифная подписка Wildberries для продавцов. Разные тарифы открывают повышенные лимиты на аналитических конечных точках:

ТарифЛимит поисковых запросов
Нет подпискиАналитические конечные точки поисковых запросов недоступны
СтандартныйДо 30 поисковых запросов
ПродвинутыйДо 50 поисковых запросов

Проблема ​

WB не предоставляет прямой конечной точки API для проверки статуса подписки Джем. Продавцам необходимо знать свой тариф, чтобы корректно задавать значение limit при вызове аналитических методов.


Решение — определение через пробные запросы ​

Метод sdk.general.getJamSubscriptionStatus({ nmIds: [yourNmId] }) использует стратегию пробных запросов:

  1. Проба 1 — Запрос с limit: 31 (выше максимума Стандартного тарифа = 30)
    • 200 — Продвинутый тариф
    • 400 — Не Продвинутый, продолжаем проверку
  2. Проба 2 — Запрос с limit: 1
    • 200 — Стандартный тариф
    • 400 — Подписка Джем отсутствует

Ошибки аутентификации, превышения лимитов запросов и сетевые ошибки пробрасываются вызывающему коду.

Как это работает

Метод отправляет пробный запрос к конечной точке аналитики поисковых запросов. Если сервер принимает limit: 31, значит тариф — Продвинутый. Если отклоняет — проверяем limit: 1, чтобы отличить Стандартный от отсутствия подписки.


Сигнатура метода ​

typescript
async getJamSubscriptionStatus(
  params: GetJamSubscriptionStatusParams
): Promise<JamSubscriptionStatus>

Типы ​

typescript
type JamSubscriptionTier = 'none' | 'standard' | 'advanced';

interface JamSubscriptionStatus {
  /** Обнаруженный тариф подписки */
  tier: JamSubscriptionTier;
  /** Временная метка проверки в формате ISO 8601 */
  checkedAt: string;
  /** Количество пробных вызовов API (1 для advanced, 2 для standard/none) */
  probeCallsMade: number;
}

interface GetJamSubscriptionStatusParams {
  /** Артикулы WB (nmId) для пробного запроса */
  nmIds: number[];
}

Лимиты запросов ​

Метод использует ту же квоту, что и analytics.createProductSearchText:

ПараметрЗначение
Запросов в минуту3
Интервал20 секунд
Всплеск3

Каждый вызов getJamSubscriptionStatus выполняет 1-2 пробных запроса.


Важные замечания ​

  • nmIds должны содержать ID товаров вашего магазина — иначе API вернет 403
  • Метод расходует квоту аналитики (analytics.createProductSearchText)
  • Результат рекомендуется кешировать — тариф подписки меняется редко
  • При передаче пустого массива nmIds будет выброшена ValidationError

Внимание

Каждый вызов этого метода потребляет 1-2 запроса из квоты аналитики. Кешируйте результат на стороне приложения.


Примеры ​

Базовое использование ​

typescript
import { WildberriesSDK } from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({ apiKey: process.env.WB_API_KEY! });

// Определяем тариф подписки Джем
const status = await sdk.general.getJamSubscriptionStatus({
  nmIds: [12345678] // Артикул вашего товара
});

console.log(`Тариф: ${status.tier}`);
console.log(`Проверено: ${status.checkedAt}`);
console.log(`Пробных запросов: ${status.probeCallsMade}`);

switch (status.tier) {
  case 'advanced':
    console.log('Продвинутый Джем — лимит до 50 запросов');
    break;
  case 'standard':
    console.log('Стандартный Джем — лимит до 30 запросов');
    break;
  case 'none':
    console.log('Нет подписки Джем');
    break;
}

Выбор лимита для createProductSearchText ​

typescript
import { WildberriesSDK } from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({ apiKey: process.env.WB_API_KEY! });

// Определяем доступный лимит по тарифу
const status = await sdk.general.getJamSubscriptionStatus({
  nmIds: [12345678]
});

const limitMap: Record<string, number> = {
  advanced: 50,
  standard: 30,
  none: 0
};

const maxLimit = limitMap[status.tier];

if (maxLimit === 0) {
  console.log('Аналитика поисковых запросов недоступна без подписки Джем');
} else {
  // Используем определенный лимит для запроса аналитики
  const searchTexts = await sdk.analytics.createProductSearchText({
    nmIds: [12345678],
    limit: maxLimit
  });
  console.log(`Получено поисковых запросов: ${searchTexts.data?.length ?? 0}`);
}

Кеширование результата ​

typescript
import { WildberriesSDK, JamSubscriptionStatus } from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({ apiKey: process.env.WB_API_KEY! });

// Простой кеш с TTL
let cachedStatus: JamSubscriptionStatus | null = null;
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 часа

async function getJamTier(): Promise<JamSubscriptionStatus> {
  // Проверяем кеш
  if (cachedStatus) {
    const elapsed = Date.now() - new Date(cachedStatus.checkedAt).getTime();
    if (elapsed < CACHE_TTL_MS) {
      return cachedStatus;
    }
  }

  // Обновляем кеш
  cachedStatus = await sdk.general.getJamSubscriptionStatus({
    nmIds: [12345678]
  });

  return cachedStatus;
}

// Использование
const tier = await getJamTier();
console.log(`Текущий тариф Джем: ${tier.tier}`);

// Повторный вызов — из кеша (без запроса к API)
const tierAgain = await getJamTier();
console.log(`Из кеша: ${tierAgain.tier}`);

Обработка ошибок ​

typescript
import {
  WildberriesSDK,
  AuthenticationError,
  RateLimitError,
  ValidationError,
  NetworkError
} from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({ apiKey: process.env.WB_API_KEY! });

try {
  const status = await sdk.general.getJamSubscriptionStatus({
    nmIds: [12345678]
  });
  console.log(`Тариф: ${status.tier}`);
} catch (error) {
  if (error instanceof ValidationError) {
    // Пустой массив nmIds или некорректные данные
    console.error('Ошибка валидации:', error.message);

  } else if (error instanceof AuthenticationError) {
    // Неверный API ключ или недостаточно прав
    console.error('Ошибка аутентификации:', error.message);

  } else if (error instanceof RateLimitError) {
    // Превышен лимит запросов — подождите и повторите
    console.error('Превышен лимит запросов. Повтор через:', error.retryAfter, 'мс');

  } else if (error instanceof NetworkError) {
    // Сетевая ошибка — проверьте соединение
    console.error('Ошибка сети:', error.message);

  } else {
    console.error('Неизвестная ошибка:', error);
  }
}

Связанные разделы ​

Made with ❤️ for the Wildberries developer community