Prism API Reference
Personalized product search service that wraps Shopkeep with user-aware reranking and filtering. Use Prism for user-specific product discovery tailored to individual taste profiles.
When to Use Prism
- • User-specific product recommendations
- • Personalized discovery feeds
- • Multi-modal searches with user history
- • Brand/domain scoped personalized search
API Configuration
Base URL: https://api-prism.bestomer.io/
Authentication: HTTP Bearer token
Authorization: Bearer $PRISM_TOKEN Core Endpoint: Unified Search
POST /search/unified is the primary endpoint for Prism. It accepts a flexible mix of capture references, text queries, product handles, and image URLs in a single request.
Request Parameters
{
// REQUIRED
"queries": [
{ "query": "text search" },
{ "image_url": "https://..." },
{ "product_variant_handle": "https://..." },
{ "user_id": "uuid", "capture_id": "uuid" }
],
"n_products": 30,
"n_pool": 300,
"noise": 0.0,
// PERSONALIZATION (optional)
"user_id": "user-uuid",
"search_weight": 0.5,
"personalization_weight": 0.5,
// ADVANCED (optional)
"domains": ["cb2.com", "westelm.com"],
"window_id": "window-uuid",
"include_visualization": false
} Response Structure
{
"results": [
{
"maxsim_sim": 0.87,
"product_handle": "https://...",
"product": {
"name": "Product Name",
"brand": "Brand",
"images": ["https://..."],
"offers": [{
"price": 49.99,
"currency": "USD",
"availability": "in_stock"
}],
"_prism_metadata": {
"personalization_applied": true,
"search_score": 0.85,
"personalization_score": 0.94,
"final_score": 0.895
}
}
}
],
"personalization_applied": true,
"total_signals_count": 57,
"impactful_signals_count": 23,
"processing_time_ms": 156.3
} TypeScript Example
async function searchUnified(params: {
queries: Array<
| { query: string }
| { image_url: string }
| { product_variant_handle: string }
| { user_id: string; capture_id: string }
>;
n_products: number;
n_pool: number;
noise: number;
user_id?: string;
search_weight?: number;
personalization_weight?: number;
}) {
const response = await fetch('https://api-prism.bestomer.io/search/unified', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PRISM_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});
return await response.json();
}
// Example: Multi-modal search
const results = await searchUnified({
queries: [
{ query: "coastal grandmother aesthetic" },
{ product_variant_handle: "https://cb2.com/products/linen-pillow" },
{ user_id: "user-123", capture_id: "cap-456" }
],
n_products: 30,
n_pool: 300,
noise: 0.0,
user_id: "user-123",
search_weight: 0.5,
personalization_weight: 0.5
}); Common Patterns
Pattern 1: Multi-Modal Search
Combine text, images, and products in one search:
const results = await searchUnified({
queries: [
{ query: "scandinavian dining room" },
{ user_id: userId, capture_id: inspoCapture1 },
{ user_id: userId, capture_id: inspoCapture2 },
{ product_variant_handle: "https://cb2.com/products/dining-table" }
],
n_products: 50,
n_pool: 500,
noise: 0.05,
user_id: userId,
search_weight: 0.4,
personalization_weight: 0.6
}); Pattern 2: Domain-Specific Exploration
Explore products within favorite stores:
const results = await searchUnified({
queries: [{ query: "throw pillows" }],
n_products: 30,
n_pool: 300,
noise: 0.0,
user_id: userId,
domains: ["cb2.com", "westelm.com", "anthropologie.com"],
search_weight: 0.5,
personalization_weight: 0.5
}); Other Endpoints
Brand Search: POST /search/brand
Search within specific brand catalogs with personalization:
{
"queries": [{ "query": "minimal leather bags" }],
"n_products": 30,
"n_pool": 300,
"noise": 0.0,
"user_id": "user-123",
"brands": ["Everlane", "Patagonia", "Allbirds"]
} Domain Search: POST /search/domain
Search within specific retailer domains:
{
"queries": [{ "query": "dining chairs" }],
"n_products": 30,
"n_pool": 300,
"noise": 0.0,
"user_id": "user-123",
"domains": ["cb2.com", "westelm.com"]
} Troubleshooting
Issue: No Personalization Applied
Cause: User has insufficient sentiment history
if (!response.personalization_applied) {
console.log("User needs more sentiment signals");
console.log("Total signals:", response.total_signals_count);
console.log("Impactful signals:", response.impactful_signals_count);
} Solution: Prompt user to like/dislike products or upload captures
Issue: Over-Personalization (Filter Bubble)
Solution: Reduce personalization weight and add noise
const results = await searchUnified({
queries: [{ query: query }],
n_products: 50,
n_pool: 500,
noise: 0.15, // Add diversity
user_id: userId,
search_weight: 0.7, // Increase search weight
personalization_weight: 0.3 // Decrease personalization
}); Related Resources
- Shopkeep API - Non-personalized search
- Code Examples - Ready-to-use snippets
- Level 2: Persona Services - Windows, Sentiments