Saltar al contenido
ShopentlyLearn

Listar — Productos

Consulta los datos de «Productos». El resultado depende de los parámetros de esta operación.

GET/api/v1/products

Autenticación
Bearer
Disponible desde
STANDARD
Permisos necesarios
catalog.product:read

Ejemplos de código

Ejemplo de solicitud

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?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/products?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/products?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))

Ejemplo de respuesta 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",
      "id": "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",
    "pagination": {
      "has_more": false,
      "limit": 20,
      "next_cursor": null
    },
    "request_id": "example"
  }
}

Cómo funciona

La integración puede leer productos no eliminados, incluidos los borradores, excepto los bloqueados por un límite del plan. Los productos bloqueados se excluyen de las listas; el acceso directo devuelve entitlements.resource_blocked. Por tanto, la visibilidad en la API difiere de la publicación en la tienda.

Parámetros

Parámetros de consulta

limitNúmero enteroOpcional

Número máximo de registros en esta página.

minimum: 1maximum: 100
Valor predeterminado: 50Ejemplo: 20
cursorCadena de texto nullOpcional

Valor de continuación opaco devuelto por la página anterior.

Cadena de texto:minLength: 1maxLength: 1024
localeCadena de texto nullOpcional

Idioma seleccionado para esta solicitud.

Cadena de texto:minLength: 2maxLength: 20
market_idCadena de texto nullOpcional

Identificador del mercado devuelto por el endpoint de contexto.

Restricciones · Cadena de texto 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
market_codeCadena de texto nullOpcional

Código del mercado devuelto por el endpoint de contexto.

Cadena de texto:minLength: 1maxLength: 16
skuCadena de texto nullOpcional

Código de referencia de inventario.

Cadena de texto:minLength: 1maxLength: 100
Restricciones · Cadena de texto 1
pattern
"^\\S+$"
publishedBooleano nullOpcional

Indica si el recurso está publicado.

brand_idCadena de texto nullOpcional

Identificador de la marca.

Restricciones · Cadena de texto 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
category_idCadena de texto nullOpcional

Identificador de la categoría.

Restricciones · Cadena de texto 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"

Esta operación no acepta un cuerpo JSON.

Respuestas

Respuesta 200

dataLista <ProductSummaryData > Obligatorio

Contenido de una respuesta correcta.

Campos · data

ProductSummaryData

availabilityAvailabilityData Obligatorio

Información de disponibilidad en el contexto seleccionado.

brand_idCadena de texto nullObligatorio

Identificador de la marca.

conditionCadena de textoObligatorio

Estado del producto.

Restricciones
enum
["new", "refurbished", "used", "returned", "display", "damaged"]
created_atCadena de textoObligatorio

Momento de creación.

format: "date-time"
idCadena de textoObligatorio

Identificador del recurso; consérvalo tal como se devuelve.

nameCadena de texto nullObligatorio

Nombre del recurso en el contexto correspondiente.

numberCadena de textoObligatorio

Número de pedido o solicitud mostrado al usuario.

pricePriceData nullObligatorio

Información del precio en el contexto seleccionado.

price_versionNúmero enteroObligatorio

Versión actual del precio para controlar cambios simultáneos.

primary_category_idCadena de texto nullObligatorio

Identificador de la categoría principal.

primary_media_idCadena de texto nullObligatorio

Identificador del archivo multimedia principal.

publishedBooleanoObligatorio

Indica si el recurso está publicado.

skuCadena de textoObligatorio

Código de referencia de inventario.

slugCadena de texto nullObligatorio

Segmento de la ruta URL en el idioma seleccionado.

tax_category_idCadena de textoObligatorio

Identificador de la categoría fiscal.

updated_atCadena de textoObligatorio

Momento de la última actualización.

format: "date-time"
variants_enabledBooleanoObligatorio

Indica si el producto utiliza variantes.

versionNúmero enteroObligatorio

Versión del recurso utilizada para controlar cambios simultáneos.

metaContextPageMeta ContextMeta PageMeta RequestMeta Obligatorio

Metadatos de la respuesta.

Campos · meta

ContextPageMeta

localeCadena de textoObligatorio

Idioma seleccionado para esta solicitud.

market_codeCadena de textoObligatorio

Código del mercado devuelto por el endpoint de contexto.

market_idCadena de textoObligatorio

Identificador del mercado devuelto por el endpoint de contexto.

paginationPagination Obligatorio

Metadatos de la paginación por cursor.

request_idCadena de textoObligatorio

Identificador de la solicitud; en los metadatos de respuesta identifica la solicitud HTTP.

minLength: 1maxLength: 100

ContextMeta

localeCadena de textoObligatorio

Idioma seleccionado para esta solicitud.

market_codeCadena de textoObligatorio

Código del mercado devuelto por el endpoint de contexto.

market_idCadena de textoObligatorio

Identificador del mercado devuelto por el endpoint de contexto.

request_idCadena de textoObligatorio

Identificador de la solicitud; en los metadatos de respuesta identifica la solicitud HTTP.

minLength: 1maxLength: 100

PageMeta

paginationPagination Obligatorio

Metadatos de la paginación por cursor.

request_idCadena de textoObligatorio

Identificador de la solicitud; en los metadatos de respuesta identifica la solicitud HTTP.

minLength: 1maxLength: 100

RequestMeta

request_idCadena de textoObligatorio

Identificador de la solicitud; en los metadatos de respuesta identifica la solicitud HTTP.

minLength: 1maxLength: 100
Ejemplo de respuesta

Estado HTTP

200
Respuesta correcta Esquema
400
Solicitud no válida
401
Autenticación necesaria
403
Permiso denegado
404
Recurso no encontrado
409
Conflicto de versión
422
Error de validación
429
Límite de solicitudes excedido
Otros estados HTTP (7)
405
Método no permitido
413
Solicitud demasiado grande
415
Formato no compatible
500
Error del servidor
502
Error de la puerta de enlace API
503
Servicio no disponible
504
Tiempo de espera agotado

Catálogo de errores: ErrorResponse

Cabeceras

401

WWW-AuthenticateCadena de textoOpcional

Esquema de autenticación exigido por el servidor.

405

AllowCadena de textoOpcional

Métodos HTTP admitidos por este recurso.

429, 503

Retry-AfterNúmero enteroOpcional

Espera mínima antes de reintentar, en segundos.

minimum: 0