Aller au contenu
ShopentlyLearn

Obtenir · Requêtes — Analyse des recherches et règles

Consultez les données de « Analyse des recherches et règles ». Le résultat dépend des paramètres de cette opération.

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

Authentification
Bearer
Disponible à partir de
STANDARD
Autorisations requises
search.analytics:read

Exemples de code

Exemple de requête

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))

Exemple de réponse 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"
  }
}

Fonctionnement

  • GET /api/v1/search/overview et /api/v1/search/queries exposent des statistiques et des requêtes regroupées.
  • Consultez les occurrences d'une requête avec query_hash.
  • Les périodes prises en charge sont de 7, 30 ou 90 jours, avec les filtres indiqués par chaque point d'accès.
  • Les règles associent des expressions à des produits et catégories sélectionnés et peuvent être créées, lues, modifiées ou supprimées.
  • Les règles et les analyses ont des autorisations distinctes ; lire les statistiques n'accorde pas l'accès à la configuration.

Paramètres

Paramètres de chemin

query_hashChaîneObligatoire

Identifiant stable de l'expression recherchée regroupée.

Contraintes
pattern
"^[a-f0-9]{64}$"
Exemple: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

Paramètres de requête

limitEntierFacultatif

Nombre maximal d'enregistrements sur cette page.

minimum: 1maximum: 100
Valeur par défaut: 50Exemple: 20
cursorChaîne nullFacultatif

Valeur opaque de continuation renvoyée par la page précédente.

Chaîne:minLength: 1maxLength: 1024
daysEntierFacultatif

Période du rapport en jours.

Contraintes
enum
[7, 30, 90]
Valeur par défaut: 30
localeChaîne nullFacultatif

Langue sélectionnée pour cette requête.

Chaîne:minLength: 2maxLength: 20
Contraintes · Chaîne 1
pattern
"^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
sourceChaîne nullFacultatif

Source de l'activité enregistrée.

Contraintes · Chaîne 1
enum
["results", "autocomplete"]
market_idChaîne nullFacultatif

Identifiant de marché renvoyé par le point d'accès au contexte.

Contraintes · Chaîne 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"

Cette opération n'accepte pas de corps JSON.

Réponses

Réponse 200

dataTableau <OccurrenceData > Obligatoire

Données d'une réponse réussie.

Champs · data

OccurrenceData

category_idChaîne nullObligatoire

Identifiant de la catégorie.

category_result_countEntierObligatoire

Nombre de résultats de catégorie.

currency_codeChaîneObligatoire

Code de la devise.

is_zero_resultsBooléenObligatoire

Indique si la recherche n'a renvoyé aucun résultat.

locale_codeChaîneObligatoire

Code de langue.

market_idChaîneObligatoire

Identifiant de marché renvoyé par le point d'accès au contexte.

max_priceChaîne nullObligatoire

Prix maximal dans la plage indiquée.

min_priceChaîne nullObligatoire

Prix minimal dans la plage indiquée.

occurred_atChaîneObligatoire

Date et heure de l'événement.

format: "date-time"
pageEntierObligatoire

Informations sur la page CMS.

product_result_countEntierObligatoire

Nombre de produits dans les résultats de recherche.

query_displayChaîneObligatoire

Expression recherchée affichée à l'administrateur.

request_idChaîneObligatoire

Identifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.

resultsTableau <ResultSnapshotData > nullObligatoire

Résultats de recherche enregistrés.

sort_keyChaîneObligatoire

Clé de tri.

sourceChaîneObligatoire

Source de l'activité enregistrée.

Contraintes
enum
["results", "autocomplete"]
metaAnalyticsPageMeta AnalyticsMeta Obligatoire

Métadonnées de la réponse.

Champs · meta

AnalyticsPageMeta

paginationPagination Obligatoire

Métadonnées de pagination par curseur.

periodAnalyticsPeriodData Obligatoire

Période du rapport et ses bornes.

request_idChaîneObligatoire

Identifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.

minLength: 1maxLength: 100

AnalyticsMeta

periodAnalyticsPeriodData Obligatoire

Période du rapport et ses bornes.

request_idChaîneObligatoire

Identifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.

minLength: 1maxLength: 100
Exemple de réponse

Statut HTTP

200
Réponse réussie Schéma
400
Requête invalide
401
Authentification requise
403
Accès refusé
404
Ressource introuvable
409
Conflit de version
422
Échec de validation
429
Limite de requêtes dépassée
Autres statuts HTTP (7)
405
Méthode non autorisée
413
Requête trop volumineuse
415
Format non pris en charge
500
Erreur du serveur
502
Erreur de passerelle API
503
Service indisponible
504
Délai de passerelle dépassé

Catalogue des erreurs: ErrorResponse

En-têtes

401

WWW-AuthenticateChaîneFacultatif

Schéma d'authentification exigé par le serveur.

405

AllowChaîneFacultatif

Méthodes HTTP prises en charge par cette ressource.

429, 503

Retry-AfterEntierFacultatif

Délai minimal avant une nouvelle tentative, en secondes.

minimum: 0