Endpoint
POST /api/workspace/{workspaceId}/catalogs/{catalogId}/batch/gold
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string | Yes | Your workspace ID |
catalogId | string | Yes | The catalog to analyze |
Request body
{
"productIds": ["prod_abc", "prod_def"],
"scope": "selection"
}
| Field | Type | Required | Description |
|---|---|---|---|
productIds | string[] | No | Product IDs to analyze. Required when scope is "selection" |
scope | string | Yes | "selection" or "all". When "all", productIds is ignored |
Response
{
"results": [
{
"productId": "prod_abc",
"status": "success",
"score": 82,
"gaps": ["secondaryImages", "gtin"],
"missingFields": ["gtin"]
},
{
"productId": "prod_def",
"status": "success",
"score": 41,
"gaps": ["description", "gtin", "brand", "images"],
"missingFields": ["description", "gtin"]
},
{
"productId": "prod_zzz",
"status": "error",
"error": "Product not in Silver stage — run Silver first"
}
],
"catalogSummary": {
"avgScore": 61.5,
"scoreDistribution": {
"excellent": 12,
"good": 34,
"warning": 28,
"poor": 8
},
"topGaps": ["gtin", "description", "secondaryImages"]
}
}
GoldResult fields
| Field | Type | Description |
|---|---|---|
productId | string | The product that was analyzed |
status | string | "success" or "error" |
score | number | Optimization score 0–100 |
gaps | string[] | Fields ordered by score impact (highest impact first) |
missingFields | string[] | Fields completely absent (subset of gaps) |
error | string | Present only when status is "error" |
catalogSummary fields
| Field | Type | Description |
|---|---|---|
avgScore | number | Mean optimization score across all processed products |
scoreDistribution | object | Count per threshold: excellent (85–100), good (65–84), warning (40–64), poor (0–39) |
topGaps | string[] | Most common gaps across the catalog, ordered by frequency |
Examples
# Analyze a selection
curl -X POST "https://app.alana.shopping/api/workspace/ws_123/catalogs/cat_456/batch/gold" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"productIds": ["prod_abc", "prod_def"],
"scope": "selection"
}'
const workspaceId = 'ws_123';
const catalogId = 'cat_456';
const response = await fetch(
`https://app.alana.shopping/api/workspace/${workspaceId}/catalogs/${catalogId}/batch/gold`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ALANA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
productIds: ['prod_abc', 'prod_def'],
scope: 'selection',
}),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.message);
}
const { results, catalogSummary } = await response.json();
console.log(`Average score: ${catalogSummary.avgScore}`);
console.log(`Top gaps to address: ${catalogSummary.topGaps.join(', ')}`);
// Find products needing immediate attention
const poorProducts = results.filter(r => r.score < 40);
console.log(`${poorProducts.length} products need urgent attention`);
import requests
import os
workspace_id = "ws_123"
catalog_id = "cat_456"
response = requests.post(
f"https://app.alana.shopping/api/workspace/{workspace_id}/catalogs/{catalog_id}/batch/gold",
headers={
"Authorization": f"Bearer {os.environ['ALANA_API_KEY']}",
"Content-Type": "application/json",
},
json={
"productIds": ["prod_abc", "prod_def"],
"scope": "selection",
}
)
response.raise_for_status()
data = response.json()
summary = data["catalogSummary"]
print(f"Average score: {summary['avgScore']}")
print(f"Score distribution: {summary['scoreDistribution']}")
print(f"Top gaps: {', '.join(summary['topGaps'])}")
# Products below warning threshold
needs_work = [r for r in data["results"] if r.get("score", 100) < 65]
print(f"\n{len(needs_work)} products below 'Good' threshold:")
for p in needs_work:
print(f" {p['productId']}: {p['score']} — fix {p['gaps'][:2]}")
Analyze entire catalog
curl -X POST "https://app.alana.shopping/api/workspace/ws_123/catalogs/cat_456/batch/gold" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"scope": "all"}'
const response = await fetch(
`https://app.alana.shopping/api/workspace/${workspaceId}/catalogs/${catalogId}/batch/gold`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ALANA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ scope: 'all' }),
}
);
const { results, catalogSummary } = await response.json();
import requests, os
response = requests.post(
f"https://app.alana.shopping/api/workspace/{workspace_id}/catalogs/{catalog_id}/batch/gold",
headers={"Authorization": f"Bearer {os.environ['ALANA_API_KEY']}"},
json={"scope": "all"}
)
data = response.json()
print(f"Catalog average score: {data['catalogSummary']['avgScore']}")
Score thresholds
| Range | Label | Meaning |
|---|---|---|
| 85–100 | Excellent | Ready for all channels |
| 65–84 | Good | Minor improvements recommended |
| 40–64 | Warning | Important fields missing |
| 0–39 | Poor | Critical gaps — not feed-ready |
Error responses
| HTTP status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | scope is missing or invalid |
| 403 | INSUFFICIENT_PERMISSIONS | API key lacks catalogs:write |
| 404 | CATALOG_NOT_FOUND | Catalog does not exist in workspace |
| 409 | JOB_ALREADY_RUNNING | A batch job is already in progress |
| 429 | RATE_LIMIT_EXCEEDED | Back off and retry after Retry-After header value |
Products that have not been through Silver will return
status: "error" with the message "Product not in Silver stage — run Silver first". Run Batch Silver before Gold for best results.