API Reference
Complete REST API documentation for the RecomNext engine. All endpoints require the X-Tenant-Id header unless noted.
# Authentication — every request needs the tenant header curl -H "X-Tenant-Id: my-tenant" http://localhost:3000/...
Unified Recommendation Endpoint
The primary way to fetch recommendations. Dispatches to the appropriate algorithm based on scenario or explicit logicType.
| Method | Path | Description |
|---|---|---|
POST | /recommendations | Unified recommendation endpoint |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| scenario | string | No | Scenario slug — resolves logicType, filters, boosters, constraints |
| logicType | string | No | Explicit logic type — required when no scenario is provided. One of: user-to-item, item-to-item, recently-viewed, items-to-items, similar-products |
| userId | string | No | User or session ID — required for user-to-item and recently-viewed |
| itemId | string | No | Seed item ID — required for item-to-item and similar-products |
| itemIds | string[] | No | Seed item IDs (e.g. cart items) — required for items-to-items |
| count | number | No | Number of results to return (default: 10) |
| returnProperties | boolean | No | Projection toggle. Default true. false returns lean identity payload (itemId + score when computed). |
| includedProperties | string[] | No | Optional exact raw document paths to include (for example attributes.name, attributes.price). |
Example
curl -X POST http://localhost:3000/recommendations \
-H "Content-Type: application/json" \
-H "X-Tenant-Id: demo-ecommerce" \
-d '{
"scenario": "homepage-for-you",
"userId": "user-123",
"count": 8,
"returnProperties": true,
"includedProperties": ["attributes.name", "attributes.price", "attributes.image", "category"]
}'Ingestion
Ingest your item catalog, user data, and interaction events. Items are automatically indexed for vector search if a matching embedding template exists.
| Method | Path | Description |
|---|---|---|
POST | /ingestion/items | Bulk upsert items (triggers async embedding indexing) |
POST | /ingestion/users | Bulk upsert users |
POST | /ingestion/interactions | Log interaction events (async via Kafka) |
POST | /ingestion/impressions | Log impression events — which recommended items were shown |
Interactions Payload
{
"userId": "user-123", // optional if sessionId is provided
"itemId": "prod-001",
"sessionId": "sess-456", // optional if userId is provided
"type": "view", // view, cart, purchase, click
"weight": 1, // optional, default is 1
"scenarioSlug": "homepage-for-you", // optional, for attribution
"timestamp": "2024-03-07T12:00:00Z" // optional, default is now
}Recommendations (Legacy Endpoints)
Specific endpoints for each recommendation logic type. While the unified endpoint is preferred, these individual endpoints provide clear parameter separation.
| Method | Path | Description |
|---|---|---|
GET | /recommendations/user-to-item/:userId | Personalized "For You" — Params: scenario, count, returnProperties, includedProperties |
GET | /recommendations/item-to-item/:itemId | Related items (co-occurrence) — Params: scenario, count, userId, returnProperties, includedProperties |
GET | /recommendations/recently-viewed/:userId | Recently viewed items — Params: scenario, count, returnProperties, includedProperties |
POST | /recommendations/items-to-items | Multi-item recommendations — Body: { itemIds, count, returnProperties, includedProperties }, Params: scenario, userId |
GET | /recommendations/similar-products/:itemId | Vector-similar products via Qdrant — Params: scenario, count, userId, returnProperties, includedProperties |
GET | /recommendations/algorithms | List all registered algorithms |
GET | /recommendations/algorithms/:logicType | List algorithms for a specific logic type |
* Passing `userId` to Item-to-Item, Items-to-Items, or Similar-Products endpoints enables the "Purchase Cap" constraint.
Projection Behavior and Security Rules
Projection runs on raw item document paths and is deterministic across unified and legacy endpoints. Identity fields are preserved for response stability.
| Mode | Request Shape | Response Contract |
|---|---|---|
| Default full payload | Omit returnProperties/includedProperties | Backward-compatible full payload |
| Lean payload | returnProperties=false | Identity-only payload (itemId; score only when computed by algorithm) |
| Selective projection | returnProperties=true + includedProperties[] | Only exact requested raw paths + required identity keys |
- Path strictness is exact: requesting
namedoes not resolveattributes.name. - Safe but missing paths are omitted from the item payload (no error).
- Unsafe segments (
__proto__,constructor,prototype,toString,valueOf) are rejected with HTTP 400. - When
returnProperties=false,includedPropertiesis ignored and identity-only payload is returned. scoreis passive algorithm metadata and may be absent in lean responses.
Legacy GET Query and HMAC Notes
For signed browser traffic, request placement must match signing scope exactly.
# Signed GET endpoints: projection fields are query params (part of signed URL)
/recommendations/item-to-item/prod-001?scenario=pdp-related&count=8&returnProperties=true&includedProperties=attributes.name,attributes.price
# Signed POST items-to-items: projection fields are body keys (not query keys)
POST /recommendations/items-to-items?scenario=cart-upsell
{
"itemIds": ["prod-1", "prod-2"],
"count": 8,
"returnProperties": true,
"includedProperties": ["attributes.name", "attributes.price", "attributes.image"]
}- GET: projection keys must be in query before signing; mismatch causes signature verification failure.
- GET serialization format is CSV in a single query key:
includedProperties=a,b,c(not repeated params or bracket notation). - POST items-to-items: projection keys belong in the JSON body and are signed with the body payload.
returnPropertieson GET should be explicit: usetrueorfalse; missing defaults to full payload.- GET guardrails: at most
20included paths and total URL length up to2048characters; overflow returns HTTP 400.
Projection Path Discovery
Discover valid include paths from raw catalog items, then reuse those exact paths inincludedProperties.
# 1) Fetch a sample item and inspect raw fields curl "http://localhost:3000/catalog/items?page=1&limit=1" \ -H "X-Tenant-Id: demo-ecommerce" # 2) Use literal raw paths from the item JSON # Valid example: attributes.name # Invalid alias example: name (unless top-level name actually exists)
Field mapper aliases are independent of projection. A configured mapper path such asfieldMapper.namePath does not make name a valid include path unless that key exists literally at the item top level.
Rollout Validation Checklist
Use this matrix to validate strict-HMAC + projection compatibility end-to-end across engine, SDKs, and widgets.
| Area | Must Verify |
|---|---|
| Engine parity | Unified + legacy endpoints apply identical projection behavior for same inputs |
| Backward compatibility | When projection params are omitted, responses stay backward-compatible |
| GET signed path | Projection fields are query params and part of signed URL |
| POST signed path | items-to-items keeps projection fields in body, not query |
| SDK request shape | Node + Browser send projection params in correct query/body location |
| Widget rendering | Lean/projected payloads render without attribute assumptions |
Suggested Validation Commands
# Engine/API projection checks cd engine && npm test # Node SDK projection propagation checks cd sdks/node && npm test # Browser SDK projection propagation checks cd sdks/js-client && npm test # Widget projection + strict-HMAC smoke checks cd widgets/carousel && npm run build && npm test cd widgets/react && npm run build && npm test
Scenarios
Scenarios are named configurations that encapsulate all the logic, filters, and constraints for a specific recommendation placement.
| Method | Path | Description |
|---|---|---|
POST | /scenarios | Create a scenario |
GET | /scenarios | List all scenarios for tenant |
GET | /scenarios/:slug | Get scenario by slug |
PUT | /scenarios/:slug | Update scenario |
DELETE | /scenarios/:slug | Delete scenario |
Scenario Schema Example
{
"name": "Related Products",
"slug": "pdp-related",
"logicType": "item-to-item",
"algorithm": "co-occurrence",
"filter": "'stock' > 0",
"boosters": ["boost by 1.2 where 'category' = 'featured'"],
"constraints": {
"maxPerCategory": 3,
"purchasedItemsMaxPercent": 10
},
"minItems": 6,
"maxItems": 12,
"autoRelaxConstraints": true
}Segmentations
Segmentations group your catalog into diverse buckets, ensuring that recommendations don't over-represent a single category or brand.
| Method | Path | Description |
|---|---|---|
POST | /segmentations | Create a segmentation |
GET | /segmentations | List segmentations |
GET | /segmentations/:id | Get segmentation by ID |
PUT | /segmentations/:id | Update segmentation |
DELETE | /segmentations/:id | Delete segmentation |
GET | /segmentations/:id/segments | Get computed segments |
POST | /segmentations/validate-expression | Validate a nextQL expression |
Analytics
Query real-time metrics captured from interactions and impressions. All analytics are powered by ClickHouse for sub-second performance.
| Method | Path | Description |
|---|---|---|
GET | /analytics/summary | Aggregate counts across the tenant |
GET | /analytics/interaction-volume | Daily interaction volume time-series |
GET | /analytics/interactions-by-type | Breakdown by event type (view, cart, etc.) |
GET | /analytics/top-items | Top items by interaction count |
GET | /analytics/catalog-coverage | Percentage of catalog surfaced in recs |
GET | /analytics/top-recommended | Top items across all scenarios with funnel metrics |
GET | /analytics/scenario/:slug/summary | Funnel metrics for one scenario (CTR, Conv) |
GET | /analytics/scenario/:slug/funnel-volume | Daily time-series for a scenario |
GET | /analytics/scenario/:slug/top-items | Top recommended items for a scenario |
Catalog & Infrastructure
Low-level endpoints for catalog inspection, vector search configuration, and identity management.
| Method | Path | Description |
|---|---|---|
GET | /catalog/items | Paginated item list |
GET | /catalog/users | Paginated user list |
GET | /catalog/tenant-settings | Get tenant fieldMapper, dimensions, and freshness settings |
PUT | /catalog/tenant-settings | Update tenant settings and invalidate tenant cache (jwt/apiKey auth only) |
GET | /catalog/embedding-templates | List vector embedding templates |
PUT | /catalog/qdrant-defaults | Update global vector search settings |
POST | /identity/merge | Merge anonymous session into known user |
GET | /tenants | List all known tenant IDs (No header required) |
Tenant Settings PUT Body Example
fieldMapper is optional. Configure it only when your catalog uses non-default paths (for example nested identity/name/image keys). When unset, the engine falls back to top-levelexternalId, category, and raw attributes.
{
"fieldMapper": {
"externalIdPath": "attributes.productId",
"namePath": "attributes.name",
"categoryPath": "attributes.primaryCategory",
"coverImagePath": "attributes.images.cover",
"basePricePath": "attributes.countryPrices.IN",
"taxonomyPath": "attributes.taxonomyPath"
},
"dimensions": [
{ "key": "genre", "type": "enum", "label": "Genre", "facetable": true, "filterable": true, "boostable": true }
],
"freshness": {
"keyPath": "attributes.releaseDate",
"type": "date",
"fallbackToCreatedAt": true
}
}