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

Отримати · Пошукові запити — Аналітика й правила пошуку

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

GET/api/v1/search/queries/{query_hash}

Автентифікація
Bearer
Доступно починаючи з
STANDARD
Потрібні дозволи
search.analytics: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/search/queries/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?limit=20'

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/search/queries/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?limit=20');
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/search/queries/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?limit=20', 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": [
    {
      "category_id": "example",
      "category_result_count": 1,
      "currency_code": "PLN",
      "is_zero_results": false,
      "locale_code": "en",
      "market_id": "example",
      "max_price": "0.00",
      "min_price": "0.00",
      "occurred_at": "2026-01-01T12:00:00Z",
      "page": 1,
      "product_result_count": 1,
      "query_display": "example",
      "request_id": "example",
      "results": [
        {
          "clicked": false,
          "entity_id": "example",
          "entity_type": "product",
          "image_url": "https://example.invalid/product.jpg",
          "number": "example",
          "placement_source": "organic",
          "position": 1,
          "sku": "example",
          "slug": "example",
          "title": "example"
        }
      ],
      "sort_key": "example",
      "source": "results"
    }
  ],
  "meta": {
    "pagination": {
      "has_more": false,
      "limit": 20,
      "next_cursor": null
    },
    "period": {
      "as_of": "2026-01-02T00:00:00Z",
      "days": 1,
      "started_at": "2026-01-01T00:00:00Z"
    },
    "request_id": "example"
  }
}

Як це працює

  • GET /api/v1/search/overview і /api/v1/search/queries надають зведену статистику та згруповані запити.
  • Отримуйте окремі появи запиту за його query_hash.
  • Звітні періоди становлять 7, 30 або 90 днів; кожна кінцева точка вказує доступні фільтри.
  • Правила пошуку пов’язують фрази з вибраними товарами й категоріями; їх можна створювати, читати, оновлювати й видаляти.
  • Правила й аналітика мають окремі дозволи: читання статистики пошуку не надає доступу до налаштувань.

Параметри

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

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

Стабільний ідентифікатор згрупованої пошукової фрази.

Обмеження
pattern
"^[a-f0-9]{64}$"
Приклад: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

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

limitЦіле числоНеобов’язкове

Максимальна кількість записів на цій сторінці.

minimum: 1maximum: 100
За замовчуванням: 50Приклад: 20
cursorРядок nullНеобов’язкове

Непрозоре значення для продовження, повернуте попередньою сторінкою.

Рядок:minLength: 1maxLength: 1024
daysЦіле числоНеобов’язкове

Звітний період у днях.

Обмеження
enum
[7, 30, 90]
За замовчуванням: 30
localeРядок nullНеобов’язкове

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

Рядок:minLength: 2maxLength: 20
Обмеження · Рядок 1
pattern
"^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
sourceРядок nullНеобов’язкове

Джерело записаної активності.

Обмеження · Рядок 1
enum
["results", "autocomplete"]
market_idРядок nullНеобов’язкове

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

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

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

Відповіді

Відповідь 200

dataМасив <OccurrenceData > Обов’язкове

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

Поля · data

OccurrenceData

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

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

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

Кількість результатів категорій.

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

Код валюти.

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

Чи не повернув пошук жодного результату.

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

Код мови.

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

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

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

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

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

Мінімальна ціна в наведеному діапазоні.

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

Дата й час події.

format: "date-time"
pageЦіле числоОбов’язкове

Відомості про сторінку CMS.

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

Кількість товарів у результатах пошуку.

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

Пошукова фраза, показана адміністратору.

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

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

resultsМасив <ResultSnapshotData > nullОбов’язкове

Записані результати пошуку.

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

Ключ сортування.

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

Джерело записаної активності.

Обмеження
enum
["results", "autocomplete"]
metaAnalyticsPageMeta AnalyticsMeta Обов’язкове

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

Поля · meta

AnalyticsPageMeta

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

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

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

Звітний період і його межі.

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

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

minLength: 1maxLength: 100

AnalyticsMeta

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

Звітний період і його межі.

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