Перейти до вмісту
ShopentlyLearn

Отримати — Товари

Отримайте дані з «Товари». Результат залежить від параметрів цієї операції.

GET/api/v1/products/{product_id}

Автентифікація
Bearer
Доступно починаючи з
STANDARD
Потрібні дозволи
catalog.product:read

Приклади коду

Приклад запиту

cURL

: "${SHOPENTLY_SHOP_URL:?}"

curl --disable --globoff --fail-with-body --silent --show-error \
  --proto '=https' --connect-timeout 5 --max-time 30 \
  --request GET \
  --header "Authorization: Bearer ${SHOPENTLY_ACCESS_TOKEN:?}" \
  --url "${SHOPENTLY_SHOP_URL%/}"/api/v1/products/example

PHP

<?php
declare(strict_types=1);

$baseUrl = rtrim(getenv('SHOPENTLY_SHOP_URL') ?: '', '/');
$origin = parse_url($baseUrl);
if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) ||
    isset($origin['user'], $origin['pass']) || isset($origin['user']) || isset($origin['path']) ||
    isset($origin['query']) || isset($origin['fragment'])) {
    throw new RuntimeException('SHOPENTLY_SHOP_URL must be an HTTPS origin');
}
$credential = getenv('SHOPENTLY_ACCESS_TOKEN') ?: '';
if ($credential === '' || strpbrk($credential, "\r\n") !== false) {
    throw new RuntimeException('Invalid credential');
}
$headers = [];
$headers[] = 'Authorization: Bearer ' . $credential;
$responseHeaders = [];
$handle = curl_init($baseUrl . '/api/v1/products/example');
curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HEADERFUNCTION => static function ($handle, string $line) use (&$responseHeaders): int {
        if (str_contains($line, ':')) {
            [$name, $value] = explode(':', $line, 2);
            $responseHeaders[strtolower(trim($name))] = trim($value);
        }
        return strlen($line);
    },
]);
$raw = curl_exec($handle);
$status = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
$error = curl_error($handle);
curl_close($handle);
if ($raw === false) {
    throw new RuntimeException('Transport error: ' . $error);
}
if ($status < 200 || $status >= 300) {
    throw new RuntimeException('HTTP ' . $status . '; request_id=' .
        ($responseHeaders['x-request-id'] ?? '') . '; retry_after=' . ($responseHeaders['retry-after'] ?? ''));
}
$result = $raw === '' ? null : json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
echo json_encode($result, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;

Python

from contextlib import ExitStack
import json
import os
from urllib.parse import urlsplit

import requests  # python -m pip install requests

base_url = os.environ["SHOPENTLY_SHOP_URL"].rstrip("/")
origin = urlsplit(base_url)
if origin.scheme != "https" or not origin.hostname or origin.username or origin.password or origin.path or origin.query or origin.fragment:
    raise ValueError("SHOPENTLY_SHOP_URL must be an HTTPS origin")
credential = os.environ['SHOPENTLY_ACCESS_TOKEN']
if not credential or "\r" in credential or "\n" in credential:
    raise ValueError("Invalid credential")
headers = {}
headers["Authorization"] = 'Bearer' + " " + credential
body = None
if body is not None:
    headers["Content-Type"] = "application/json"

with ExitStack() as stack:
    session = stack.enter_context(requests.Session())
    files = None
    if False:
        image = stack.enter_context(open(os.environ["SHOPENTLY_IMAGE_FILE"], "rb"))
        if os.fstat(image.fileno()).st_size > 5242880:
            raise ValueError("Image exceeds 5 MiB")
        files = {"file": ("article.png", image, "image/png")}
    response = session.request(
        'GET', base_url + '/api/v1/products/example', headers=headers,
        data=body.encode("utf-8") if body is not None else None, files=files,
        timeout=(5, 30), allow_redirects=False,
    )
    if not 200 <= response.status_code < 300:
        raise RuntimeError(f"HTTP {response.status_code}; request_id={response.headers.get('X-Request-ID', '')}; retry_after={response.headers.get('Retry-After', '')}")
    if False:
        if response.headers.get("Content-Type") != "image/webp" or len(response.content) > 5242880:
            raise ValueError("Unexpected image response")
        with open(os.environ["SHOPENTLY_OUTPUT_FILE"], "xb") as output:
            output.write(response.content)
    else:
        result = response.json() if response.content else None
        print(json.dumps(result, ensure_ascii=False, indent=2))

Приклад відповіді 200

JSON
{
  "data": {
    "availability": {
      "available_from": null,
      "available_until": null,
      "is_available": true
    },
    "brand_id": null,
    "condition": "new",
    "created_at": "2026-01-01T12:00:00Z",
    "description": "example",
    "features": [
      {
        "feature_id": "example",
        "feature_name": "example",
        "value": "example",
        "value_id": "example"
      }
    ],
    "id": "example",
    "identifiers": {},
    "media": [
      {
        "alt_text": "example",
        "id": "example",
        "is_primary": true,
        "kind": "image",
        "mime_type": "image/jpeg",
        "position": 1,
        "url": "https://example.invalid/product.jpg"
      }
    ],
    "meta_description": "example",
    "meta_keywords": [
      "example"
    ],
    "meta_title": "example",
    "name": "Example",
    "number": "example",
    "price": {
      "amount": "0.00",
      "currency": "PLN",
      "minor_units": 2,
      "tax_included": true
    },
    "price_version": 1,
    "primary_category_id": "example",
    "primary_media_id": "example",
    "published": false,
    "sku": "example",
    "slug": "example",
    "tax_category_id": "example",
    "updated_at": "2026-01-01T12:00:00Z",
    "variants_enabled": false,
    "version": 1
  },
  "meta": {
    "locale": "en",
    "market_code": "PL",
    "market_id": "example",
    "request_id": "example"
  }
}

Як це працює

  • Інтеграція може читати всі невидалені товари, зокрема чернетки, крім заблокованих лімітом тарифу.
  • Заблоковані товари не потрапляють до списків; прямий доступ повертає entitlements.resource_blocked.
  • Тому доступність товару через API відрізняється від його публікації на вітрині.
  • Використовуйте наявні ідентифікатори брендів, категорій, характеристик і медіафайлів.
  • Для цін явно вказуються валюта, прайс-лист, податковий режим і версії контролю одночасних змін.
  • Ціни товару й варіантів відокремлені; використовуйте підтримувану структуру ціни та точні десяткові рядки.

Параметри

Параметри шляху

product_idРядокОбов’язкове

Ідентифікатор товару.

Обмеження
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
Приклад: "example"

Параметри запиту

localeРядок nullНеобов’язкове

Мова, вибрана для цього запиту.

Рядок:minLength: 2maxLength: 20
market_idРядок nullНеобов’язкове

Ідентифікатор ринку, повернутий кінцевою точкою контексту.

Обмеження · Рядок 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
market_codeРядок nullНеобов’язкове

Код ринку, повернутий кінцевою точкою контексту.

Рядок:minLength: 1maxLength: 16

Ця операція не приймає тіло JSON.

Відповіді

Відповідь 200

dataProductDetailData Обов’язкове

Дані успішної відповіді.

Поля · data
availabilityAvailabilityData Обов’язкове

Відомості про доступність у вибраному контексті.

Поля · availability
available_fromРядок nullОбов’язкове

Початок доступності.

Рядок:format: "date-time"
available_untilРядок nullОбов’язкове

Кінець доступності.

Рядок:format: "date-time"
is_availableЛогічне значенняОбов’язкове

Чи доступна позиція в цьому контексті.

brand_idРядок nullОбов’язкове

Ідентифікатор бренду.

conditionРядокОбов’язкове

Стан товару.

Обмеження
enum
["new", "refurbished", "used", "returned", "display", "damaged"]
created_atРядокОбов’язкове

Час створення.

format: "date-time"
descriptionРядок nullОбов’язкове

Опис вибраною мовою.

featuresМасив <FeatureSelectionData > Обов’язкове

Характеристики товару.

Поля · features
idРядокОбов’язкове

Ідентифікатор ресурсу; зберігайте його в отриманому вигляді.

identifiersОб’єктДодаткові поля: РядокОбов’язкове

Ідентифікаційні коди товару.

mediaМасив <ProductMediaData > Обов’язкове

Відомості про додані медіафайли.

Поля · media
meta_descriptionРядок nullОбов’язкове

Опис для пошукових систем вибраною мовою.

meta_keywordsМасив <Рядок> nullОбов’язкове

Ключові слова для пошукових систем вибраною мовою.

meta_titleРядок nullОбов’язкове

Заголовок для пошукових систем вибраною мовою.

nameРядок nullОбов’язкове

Назва ресурсу у відповідному контексті.

numberРядокОбов’язкове

Зрозумілий користувачу номер замовлення або звернення.

pricePriceData nullОбов’язкове

Відомості про ціну у вибраному контексті.

Поля · price
price_versionЦіле числоОбов’язкове

Поточна версія ціни для контролю одночасних змін.

primary_category_idРядок nullОбов’язкове

Ідентифікатор основної категорії.

primary_media_idРядок nullОбов’язкове

Ідентифікатор основного медіафайлу.

publishedЛогічне значенняОбов’язкове

Чи опубліковано ресурс.

skuРядокОбов’язкове

Код складської облікової одиниці.

slugРядок nullОбов’язкове

Сегмент шляху URL вибраною мовою.

tax_category_idРядокОбов’язкове

Ідентифікатор податкової категорії.

updated_atРядокОбов’язкове

Час останнього оновлення.

format: "date-time"
variants_enabledЛогічне значенняОбов’язкове

Чи використовує товар варіанти.

versionЦіле числоОбов’язкове

Версія ресурсу для контролю одночасних змін.

metaContextPageMeta ContextMeta PageMeta RequestMeta Обов’язкове

Метадані відповіді.

Поля · meta

ContextPageMeta

localeРядокОбов’язкове

Мова, вибрана для цього запиту.

market_codeРядокОбов’язкове

Код ринку, повернутий кінцевою точкою контексту.

market_idРядокОбов’язкове

Ідентифікатор ринку, повернутий кінцевою точкою контексту.

paginationPagination Обов’язкове

Метадані пагінації за курсором.

request_idРядокОбов’язкове

Ідентифікатор звернення; у метаданих відповіді ідентифікує запит HTTP.

minLength: 1maxLength: 100

ContextMeta

localeРядокОбов’язкове

Мова, вибрана для цього запиту.

market_codeРядокОбов’язкове

Код ринку, повернутий кінцевою точкою контексту.

market_idРядокОбов’язкове

Ідентифікатор ринку, повернутий кінцевою точкою контексту.

request_idРядокОбов’язкове

Ідентифікатор звернення; у метаданих відповіді ідентифікує запит HTTP.

minLength: 1maxLength: 100

PageMeta

paginationPagination Обов’язкове

Метадані пагінації за курсором.

request_idРядокОбов’язкове

Ідентифікатор звернення; у метаданих відповіді ідентифікує запит HTTP.

minLength: 1maxLength: 100

RequestMeta

request_idРядокОбов’язкове

Ідентифікатор звернення; у метаданих відповіді ідентифікує запит HTTP.

minLength: 1maxLength: 100
Приклад відповіді

Статус HTTP

200
Успішна відповідь Схема
400
Некоректний запит
401
Потрібна автентифікація
403
Доступ заборонено
404
Ресурс не знайдено
409
Конфлікт версій
422
Помилка валідації
429
Перевищено ліміт запитів
Інші статуси HTTP (7)
405
Метод не дозволено
413
Завеликий запит
415
Непідтримуваний формат
500
Помилка сервера
502
Помилка шлюзу API
503
Сервіс недоступний
504
Перевищено час очікування

Каталог помилок: ErrorResponse

Заголовки

401

WWW-AuthenticateРядокНеобов’язкове

Схема автентифікації, потрібна серверу.

405

AllowРядокНеобов’язкове

Методи HTTP, підтримувані цим ресурсом.

429, 503

Retry-AfterЦіле числоНеобов’язкове

Мінімальна затримка перед повтором у секундах.

minimum: 0