Get a normalized catalog aggregate
curl --request GET \
--url https://salespilot.crossup.ai/v1/catalog/items/{item_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://salespilot.crossup.ai/v1/catalog/items/{item_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://salespilot.crossup.ai/v1/catalog/items/{item_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://salespilot.crossup.ai/v1/catalog/items/{item_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://salespilot.crossup.ai/v1/catalog/items/{item_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://salespilot.crossup.ai/v1/catalog/items/{item_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://salespilot.crossup.ai/v1/catalog/items/{item_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"item": {
"item_id": "<string>",
"store_id": "<string>",
"connection_id": "<string>",
"external_id": "<string>",
"title": {},
"status": "<string>",
"source_version": "<string>",
"primary_media": {
"url": "<string>",
"alt": {}
},
"description": {},
"handles": {},
"urls": {},
"media": [
{
"url": "<string>",
"alt": {}
}
],
"brand": "<string>",
"tags": [
"<string>"
],
"free_shipping": true,
"taxonomy": [
{
"taxonomy_id": "<string>",
"external_id": "<string>",
"name": {},
"handles": {},
"parent_id": "<string>"
}
]
},
"variants": [
{
"variant_id": "<string>",
"item_id": "<string>",
"external_id": "<string>",
"status": "<string>",
"sku": "<string>",
"title": {},
"price": {
"amount": "<string>",
"currency": "<string>"
},
"promotional_price": {
"amount": "<string>",
"currency": "<string>"
},
"attributes": [
{
"name": {},
"value": {}
}
]
}
],
"availability": [
{
"variant_id": "<string>",
"sellable": "<string>",
"as_of": "2023-11-07T05:31:56Z",
"quantity": 123
}
],
"refresh_revision": 2
}{
"type": "https://api.crossup.ai/salespilot/errors/unauthorized",
"title": "Authentication required",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/forbidden-scope",
"title": "Key is missing the required scope",
"status": 403,
"detail": "<string>",
"code": "forbidden_scope",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/not-found",
"title": "Resource not found",
"status": 404,
"detail": "<string>",
"code": "not_found",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "<string>",
"code": "rate_limited",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/internal-error",
"title": "Internal server error",
"status": 500,
"detail": "<string>",
"code": "internal_error",
"request_id": "<string>"
}Operaciones
Leer un ítem del catálogo
Devuelve el agregado canónico: ítem, variantes y disponibilidad.
GET
/
v1
/
catalog
/
items
/
{item_id}
Get a normalized catalog aggregate
curl --request GET \
--url https://salespilot.crossup.ai/v1/catalog/items/{item_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://salespilot.crossup.ai/v1/catalog/items/{item_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://salespilot.crossup.ai/v1/catalog/items/{item_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://salespilot.crossup.ai/v1/catalog/items/{item_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://salespilot.crossup.ai/v1/catalog/items/{item_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://salespilot.crossup.ai/v1/catalog/items/{item_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://salespilot.crossup.ai/v1/catalog/items/{item_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"item": {
"item_id": "<string>",
"store_id": "<string>",
"connection_id": "<string>",
"external_id": "<string>",
"title": {},
"status": "<string>",
"source_version": "<string>",
"primary_media": {
"url": "<string>",
"alt": {}
},
"description": {},
"handles": {},
"urls": {},
"media": [
{
"url": "<string>",
"alt": {}
}
],
"brand": "<string>",
"tags": [
"<string>"
],
"free_shipping": true,
"taxonomy": [
{
"taxonomy_id": "<string>",
"external_id": "<string>",
"name": {},
"handles": {},
"parent_id": "<string>"
}
]
},
"variants": [
{
"variant_id": "<string>",
"item_id": "<string>",
"external_id": "<string>",
"status": "<string>",
"sku": "<string>",
"title": {},
"price": {
"amount": "<string>",
"currency": "<string>"
},
"promotional_price": {
"amount": "<string>",
"currency": "<string>"
},
"attributes": [
{
"name": {},
"value": {}
}
]
}
],
"availability": [
{
"variant_id": "<string>",
"sellable": "<string>",
"as_of": "2023-11-07T05:31:56Z",
"quantity": 123
}
],
"refresh_revision": 2
}{
"type": "https://api.crossup.ai/salespilot/errors/unauthorized",
"title": "Authentication required",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/forbidden-scope",
"title": "Key is missing the required scope",
"status": 403,
"detail": "<string>",
"code": "forbidden_scope",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/not-found",
"title": "Resource not found",
"status": 404,
"detail": "<string>",
"code": "not_found",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "<string>",
"code": "rate_limited",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/internal-error",
"title": "Internal server error",
"status": 500,
"detail": "<string>",
"code": "internal_error",
"request_id": "<string>"
}Devuelve un
No hay idioma garantizado: elegí uno y tené un fallback.
CatalogAggregate: el ítem, sus variantes y su disponibilidad, tal
como quedaron después de las señales ingeridas.
Tres formas que sorprenden la primera vez
title no es un string, es un LocalizedText
title no es un string, es un LocalizedText
item.title y variant.title son objetos { [lang]: string } con al
menos una clave:{ "es": "Remera Demo" }
primary_media.alt
tiene la misma forma.sellable es un string, no un booleano
sellable es un string, no un booleano
availability[].sellable es un string abierto (el fixture usa
"in_stock"). Un booleano no puede decir «no sé», y CrossUp no adivina lo
que el proveedor no dijo: lo desconocido queda unknown. Tratalo como
opaco y mostralo tal cual.quantity ausente no es cero
quantity ausente no es cero
Si el proveedor no informó inventario,
quantity no viene: es
desconocido. quantity ?? 0 convierte «no sé» en «no hay stock», una
decisión de negocio que la API no tomó.Un ítem de otra tienda da 404, no 403
Unitem_id inexistente y uno de otra tienda son indistinguibles: los dos
dan not_found. Un 404 inesperado con un
token válido casi siempre es el token de otra tienda.Autorizaciones
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Parámetros de ruta
CrossUp catalog item identifier.
Minimum string length:
1Respuesta
Catalog aggregate found
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Which look at the store this aggregate came from. A client that caches can tell a newer read from a stale one without comparing every field, and a bug report that quotes it says exactly what the caller saw.
Rango requerido:
x >= 1