List products
curl --request GET \
--url https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products', 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://app.alana.shopping/api/workspace/{workspaceId}/catalog/products",
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://app.alana.shopping/api/workspace/{workspaceId}/catalog/products"
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://app.alana.shopping/api/workspace/{workspaceId}/catalog/products")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products")
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{
"products": [
{
"id": "<string>",
"workspaceId": "<string>",
"title": "<string>",
"price": 123,
"currency": "<string>",
"availability": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"catalogId": "<string>",
"description": "<string>",
"brand": "<string>",
"categoryPath": [
"<string>"
],
"originalPrice": 123,
"primaryImageUrl": "<string>",
"sku": "<string>",
"gtin": "<string>",
"attributes": {},
"optimizationScore": 50,
"feedReady": true,
"createdBy": "<string>"
}
],
"total": 123,
"limit": 123,
"offset": 123
}{
"error": "UNAUTHORIZED",
"details": {
"message": "Missing or invalid authentication token"
}
}{
"error": "FORBIDDEN",
"details": {
"message": "User does not have permission to access this resource"
}
}{
"error": "INTERNAL_SERVER_ERROR",
"details": {
"message": "An unexpected error occurred"
}
}List Products
Retrieve the workspace’s own catalog products with optimization scores and feed readiness status. Without query parameters the full workspace catalog is returned (products only). When any of limit, offset, search, brand_id or catalog_id is present the result is a database-level page scoped to the workspace repo, and total, limit and offset are included.
GET
/
api
/
workspace
/
{workspaceId}
/
catalog
/
products
List products
curl --request GET \
--url https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products', 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://app.alana.shopping/api/workspace/{workspaceId}/catalog/products",
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://app.alana.shopping/api/workspace/{workspaceId}/catalog/products"
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://app.alana.shopping/api/workspace/{workspaceId}/catalog/products")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.alana.shopping/api/workspace/{workspaceId}/catalog/products")
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{
"products": [
{
"id": "<string>",
"workspaceId": "<string>",
"title": "<string>",
"price": 123,
"currency": "<string>",
"availability": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"catalogId": "<string>",
"description": "<string>",
"brand": "<string>",
"categoryPath": [
"<string>"
],
"originalPrice": 123,
"primaryImageUrl": "<string>",
"sku": "<string>",
"gtin": "<string>",
"attributes": {},
"optimizationScore": 50,
"feedReady": true,
"createdBy": "<string>"
}
],
"total": 123,
"limit": 123,
"offset": 123
}{
"error": "UNAUTHORIZED",
"details": {
"message": "Missing or invalid authentication token"
}
}{
"error": "FORBIDDEN",
"details": {
"message": "User does not have permission to access this resource"
}
}{
"error": "INTERNAL_SERVER_ERROR",
"details": {
"message": "An unexpected error occurred"
}
}Authorizations
Bearer token authentication via Auth0. Users authenticate through Auth0 Universal Login. Include the access token in the Authorization header: Authorization: Bearer <token>
Path Parameters
The workspace ID
Pattern:
^ws_[a-z0-9]+$Query Parameters
Filter by catalog ID
Filter by brand ID (brand scoping, ADR 028)
Case-insensitive substring match on title, brand, sku or merchant_item_id
Page size (paged mode only)
Required range:
1 <= x <= 200Page offset (paged mode only)
Required range:
x >= 0Last modified on February 16, 2026