Recommendations API
MXP RecSys REST endpoints — PredictApp inference and EditApp configuration
MXP RecSys exposes two FastAPI services. PredictApp serves real-time recommendations; EditApp manages model
deployment and container configuration. Locally, EditApp runs on port 8080 and PredictApp on port 8081; both expose
Swagger UI at /docs. In deployed environments both are served at /.
Every endpoint except /health requires a tenant query parameter that scopes the request to a tenant's configuration.
PredictApp (inference)
| Method | Path | Description |
|---|---|---|
GET | /health | Service health check |
POST | /predict | Get recommendations for a container's model(s) |
POST | /evaluation | Evaluate a single named model (quality checks / LLM-as-a-Judge) |
GET | /bundles | Get the bundle plan (categories) for a seed product |
POST | /bundles/recommendations | Fill a bundle plan with concrete product candidates |
POST /predict
Returns recommendations from the model(s) assigned to a container. Routing is by containerId, not by page type.
Request body:
{
"eventType": "details-page-view",
"containerId": "pdp-recommendations",
"modelIds": ["fbt_model_1"],
"productIds": ["SKU|12345"],
"visitorId": "visitor_xyz",
"userId": "user_abc",
"predictParams": { "returnProduct": true, "returnScore": true },
"actions": []
}| Field | Type | Required | Description |
|---|---|---|---|
containerId | string | Yes | The container (placement) to serve |
productIds | string[] | Yes | Seed product IDs (at least one) |
modelIds | string[] | No | Restrict to specific models in the container; if omitted, all run |
eventType | string | No | Context tag (e.g. details-page-view); passed through, not used for routing |
visitorId | string | No | Visitor identifier — enables session personalization |
userId | string | No | User identifier — enables brand-affinity personalization |
predictParams | object | No | Serving options (returnProduct, returnScore, strictFiltering, diversityLevel, debug, …) |
actions | PredictAction[] | No | Filter / boost / bury rules (see Actions) |
Response:
{
"success": true,
"response_data": [
{ "id": "SKU|54321", "name": "Premium Oil Filter", "score": 0.92, "price": 12.99, "label": "GOOD", "explanation": {} }
],
"error": null
}Each item in response_data has id, and optionally name, description, score, price, label, and explanation.
POST /evaluation
Evaluates a single named model, used for quality checks and the LLM-as-a-Judge job. The body mirrors /predict but adds
modelType and modelName to target one specific model.
GET /bundles
Returns the bundle plan for a seed product: a list of bundles, each with a name, description, and category list. Takes
tenant and productId query parameters. No products are attached yet — call /bundles/recommendations to fill them.
POST /bundles/recommendations
Fills a bundle plan with concrete product candidates per category.
{
"productId": "SKU|12345",
"containerId": "pdp-getbundle",
"bundles": [ /* ProductBundle plans, typically from GET /bundles */ ],
"strategy": "hybrid",
"visitorId": "visitor_xyz",
"userId": "user_abc",
"actions": []
}strategy is one of hybrid (default), fbt, or top_products. The response returns each bundle with its categories
populated by product candidates.
EditApp (configuration)
Models
| Method | Path | Description |
|---|---|---|
GET | /models | List models for a tenant (filterable by page/model type) |
GET | /models/{model_id} | Get a single model |
POST | /models/{model_id}/deploy | Deploy a model to a Vertex AI Endpoint (async job) |
POST | /models/{model_id}/undeploy | Undeploy a model (async job) |
GET | /jobs/{job_id} | Check deploy/undeploy job status |
Deploy and undeploy are asynchronous: they return a job with a status (accepted → in_progress → completed/failed)
and progress. A model attached to any container cannot be undeployed.
Containers
| Method | Path | Description |
|---|---|---|
GET | /containers | List containers for a tenant |
GET | /containers/{container_id} | Get a single container |
POST | /containers | Create a container |
PUT | /containers/{container_id} | Replace a container (increments version) |
DELETE | /containers/{container_id} | Delete a container |
A container holds one or more slotConfigurations; each slot binds a modelId to a placement and gets a unique
slotConfigId. Configuration is persisted to GCS and read by PredictApp on the next request.
Events & user features
| Method | Path | Description |
|---|---|---|
POST | /events | Store a visitor session event in Redis |
GET | /events | Retrieve a visitor's recent events |
GET | /events/types | List supported event types for a tenant |
POST | /user_features | Store a user feature vector in Redis |
Model types
Model configurations support these types:
| Type | Description |
|---|---|
CUSTOMERS_ALSO_VIEW | Items other users viewed after this product (session model, Vertex AI Endpoint) |
FREQUENTLY_BOUGHT_TOGETHER | Items commonly purchased together (session model, Vertex AI Endpoint) |
SIMILAR_ITEMS | Semantically similar products via embedding kNN (served in PredictApp) |
GOOD_BETTER_BEST | Three price-tiered options in a category (served in PredictApp) |
BUNDLE_RECOMMENDATIONS | Complementary product bundles (GetBundle pipeline) |
Actions
Filtering and boosting are applied at request time through the actions array. A PredictAction has a type
(FILTER, BOOST, or BURY), an optional weight, an optional recursive condition, and an optional slotConfigId
that scopes it to a single model slot (or all models when omitted).
Recommendation rules are authored in the Discovery rules UI. When a recommendation request is made, those rules are
passed to PredictApp as actions. See Recommendation Rules.
Related pages
- Recommendations overview — the merchandiser-facing view
- Recommendations architecture — services, data stores, and flows
- Search API — the Discovery service endpoints