Obtenir — Produits
Consultez les données de « Produits ». Le résultat dépend des paramètres de cette opération.
GET/api/v1/products/{product_id}
- Authentification
Bearer- Disponible à partir de
- STANDARD
- Autorisations requises
catalog.product: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/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))
Exemple de réponse 200
{
"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"
}
}
Fonctionnement
- L'intégration peut lire les produits non supprimés, y compris les brouillons, sauf ceux bloqués par une limite du forfait.
- Ils sont exclus des listes et un accès direct renvoie entitlements.resource_blocked.
- La visibilité API diffère donc de la publication dans la boutique.
- Utilisez des identifiants existants pour les marques, catégories, caractéristiques et médias.
- Les prix précisent devise, liste de prix, traitement fiscal et versions de concurrence.
- Les prix des produits et variantes sont distincts ; utilisez la structure prévue et des chaînes décimales exactes.
Paramètres
Paramètres de chemin
product_idChaîneObligatoireIdentifiant du produit.
Contraintes
pattern"^[a-z0-9][a-z0-9_-]{0,62}$"
Paramètres de requête
localeChaîne nullFacultatifLangue sélectionnée pour cette requête.
Chaîne:minLength:2maxLength:20market_idChaîne nullFacultatifIdentifiant de marché renvoyé par le point d'accès au contexte.
Contraintes · Chaîne 1
pattern"^[a-z0-9][a-z0-9_-]{0,62}$"
market_codeChaîne nullFacultatifCode de marché renvoyé par le point d'accès au contexte.
Chaîne:minLength:1maxLength:16
Cette opération n'accepte pas de corps JSON.
Réponses
Réponse 200
Modèle complet: ApiResponse_ProductDetailData_
dataProductDetailDataObligatoireDonnées d'une réponse réussie.
Champs ·
dataModèle complet:
ProductDetailDataavailabilityAvailabilityDataObligatoireInformations de disponibilité dans le contexte sélectionné.
Champs ·
availabilityModèle complet:
AvailabilityDataavailable_fromChaîne nullObligatoireDébut de la disponibilité.
Chaîne:format:"date-time"available_untilChaîne nullObligatoireFin de la disponibilité.
Chaîne:format:"date-time"is_availableBooléenObligatoireIndique si l'article est disponible dans ce contexte.
brand_idChaîne nullObligatoireIdentifiant de la marque.
conditionChaîneObligatoireÉtat du produit.
Contraintes
enum["new", "refurbished", "used", "returned", "display", "damaged"]
created_atChaîneObligatoireDate et heure de création.
format:"date-time"descriptionChaîne nullObligatoireDescription dans la langue sélectionnée.
featuresTableau <FeatureSelectionData> ObligatoireCaractéristiques du produit.
Champs ·
featuresidChaîneObligatoireIdentifiant de ressource ; conserver la valeur renvoyée.
identifiersObjetChamps supplémentaires: ChaîneObligatoireCodes d'identification du produit.
mediaTableau <ProductMediaData> ObligatoireInformations sur les médias associés.
Champs ·
mediameta_descriptionChaîne nullObligatoireDescription pour les moteurs de recherche dans la langue sélectionnée.
meta_keywordsTableau <Chaîne> nullObligatoireMots-clés pour les moteurs de recherche dans la langue sélectionnée.
meta_titleChaîne nullObligatoireTitre pour les moteurs de recherche dans la langue sélectionnée.
nameChaîne nullObligatoireNom de la ressource dans le contexte concerné.
numberChaîneObligatoireNuméro de commande ou de demande visible par l'utilisateur.
pricePriceDatanullObligatoireInformations de prix dans le contexte sélectionné.
Champs ·
priceprice_versionEntierObligatoireVersion actuelle du prix pour le contrôle de concurrence.
primary_category_idChaîne nullObligatoireIdentifiant de la catégorie principale.
primary_media_idChaîne nullObligatoireIdentifiant du média principal.
publishedBooléenObligatoireIndique si la ressource est publiée.
skuChaîneObligatoireCode de l'unité de gestion des stocks.
slugChaîne nullObligatoireSegment du chemin URL dans la langue sélectionnée.
tax_category_idChaîneObligatoireIdentifiant de la catégorie fiscale.
updated_atChaîneObligatoireDate et heure de la dernière modification.
format:"date-time"variants_enabledBooléenObligatoireIndique si le produit utilise des variantes.
versionEntierObligatoireVersion de ressource utilisée pour le contrôle de concurrence.
metaContextPageMetaContextMetaPageMetaRequestMetaObligatoireMétadonnées de la réponse.
Champs ·
metaModèle complet:
ContextPageMetalocaleChaîneObligatoireLangue sélectionnée pour cette requête.
market_codeChaîneObligatoireCode de marché renvoyé par le point d'accès au contexte.
market_idChaîneObligatoireIdentifiant de marché renvoyé par le point d'accès au contexte.
paginationPaginationObligatoireMétadonnées de pagination par curseur.
request_idChaîneObligatoireIdentifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.
minLength:1maxLength:100
localeChaîneObligatoireLangue sélectionnée pour cette requête.
market_codeChaîneObligatoireCode de marché renvoyé par le point d'accès au contexte.
market_idChaîneObligatoireIdentifiant de marché renvoyé par le point d'accès au contexte.
request_idChaîneObligatoireIdentifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.
minLength:1maxLength:100
paginationPaginationObligatoireMétadonnées de pagination par curseur.
request_idChaîneObligatoireIdentifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.
minLength:1maxLength:100
request_idChaîneObligatoireIdentifiant de demande ; dans les métadonnées, identifiant de la requête HTTP.
minLength:1maxLength:100
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îneFacultatifSchéma d'authentification exigé par le serveur.
405
AllowChaîneFacultatifMéthodes HTTP prises en charge par cette ressource.
429, 503
Retry-AfterEntierFacultatifDélai minimal avant une nouvelle tentative, en secondes.
minimum:0