Subchapter 8.38
references/ecommerce/api-recommendation-tracking.mdMarkdown13 KBView on GitHub
This service persists recommendations in a database and tracks their lifecycle state. Every recommendation generated by any domain (discounts, shipping, etc.) MUST be persisted here before being presented to the merchant.
Service:
wix.ecom.agentic.recommendations.v1.AgenticRecommendationsServiceBase URL: https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations
Internal-but-callable API. This is a Wix-internal service with NO public
dev.wix.comdocs page. It IS callable viaCallWixSiteAPIin the authenticated editor/dashboard context the MCP runs in (verified: the endpoints return auth/validation errors, not 404). This file is the authoritative spec — do not try toReadFullDocsArticlean external doc for it.
Use CallWixSiteAPI to invoke each endpoint:
CallWixSiteAPI(
url: "https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/<endpoint>",
method: "POST",
body: { ... }
)| Field | Type | Access | Description |
|---|---|---|---|
id | string (GUID) | readOnly | Auto-generated unique identifier |
revision | int64 | readOnly | Optimistic lock — must match current value for state transitions |
createdDate | Timestamp | readOnly | When the recommendation was created |
updatedDate | Timestamp | readOnly | When the recommendation was last updated |
title | string | writable | Short human-readable title (max 200 chars) |
reasoning | string | writable | Why this recommendation is being made, citing specific data (max 2000 chars) |
domain | string | writable | Business domain: "shipping", "discounts", etc. (max 50 chars) |
urgency | enum | writable | CRITICAL, HIGH, MEDIUM, or LOW |
advice | Advice | writable | The action to take (see below) |
state | enum | readOnly | Current lifecycle state (see State Machine) |
expiresAt | Timestamp | writable | When the recommendation auto-expires |
conversationId | string (GUID) | writable | Links all recommendations in a session |
decidedBy | string | readOnly | Who made the last state transition |
rejectionReason | string | readOnly | Reason for rejection (max 1000 chars) |
rejectionPermanent | boolean | readOnly | If true, this action type is permanently blocked for this site |
executionResult | ExecutionResult | readOnly | Result of execution (set on DONE/FAILED) |
| Field | Type | Description |
|---|---|---|
action | string | Action identifier (e.g., "apply_discount", "create_shipping_option") (max 100 chars) |
params | object | Domain-specific parameters (discount config, shipping option details, etc.) |
successCriteria | string | How to verify the action succeeded (max 500 chars) |
| Field | Type | Description |
|---|---|---|
status | enum | SUCCESS, PARTIAL_FAILURE, or FAILURE |
summary | string | Description of what happened (max 2000 chars) |
error | string | Error message if failed (max 2000 chars) |
resultPayload | object | Additional result data |
PROPOSED → APPROVED → EXECUTING → DONE
│ └──→ FAILED
├──→ REJECTED
└──→ EXPIRED (scheduler)| From | To | Trigger | API Method |
|---|---|---|---|
| — | PROPOSED | Recommendation created | BatchCreate / Create |
| PROPOSED | APPROVED | Merchant approves | Approve |
| PROPOSED | REJECTED | Merchant rejects | Reject |
| PROPOSED | EXPIRED | expiresAt passed | Automatic (scheduler) |
| PROPOSED | PROPOSED | Merchant modifies parameters | Update (state unchanged) |
| APPROVED | EXECUTING | Execution begins | MarkExecuting |
| EXECUTING | DONE | Execution succeeded | MarkDone |
| EXECUTING | FAILED | Execution failed | MarkFailed |
Creates multiple recommendations (1-100) atomically. All start in PROPOSED state. Use this as the default — always batch recommendations together.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/batch-create
Request:
{
"agenticRecommendations": [
{
"title": "15% Off Electronics — Orders Over $200",
"reasoning": "AOV is $165. Electronics avg margin 42%. $200 threshold incentivizes adding one more item.",
"domain": "discounts",
"urgency": "HIGH",
"advice": {
"action": "apply_discount",
"params": {
"mechanism": "AUTOMATIC",
"scope": "CATEGORY",
"discountType": "PERCENTAGE",
"discount": 15,
"conditions": { "minSubTotal": 200 }
},
"successCriteria": "15% discount applied to Electronics for orders above $200"
}
}
],
"conversationId": "<conversationId>"
}Response:
{
"results": [
{
"agenticRecommendation": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"revision": "1",
"state": "PROPOSED",
"title": "15% Off Electronics — Orders Over $200",
"reasoning": "...",
"domain": "discounts",
"urgency": "HIGH",
"advice": { "..." : "..." },
"conversationId": "...",
"createdDate": "2026-05-10T10:00:00Z",
"updatedDate": "2026-05-10T10:00:00Z"
}
}
]
}Important: Save the id and revision from each result — you need them for all subsequent state transitions.
Creates a single recommendation in PROPOSED state. Prefer BatchCreate for multiple recommendations.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations
Request:
{
"agenticRecommendation": {
"title": "Add Free Shipping for Orders Over $75",
"reasoning": "No free shipping option. delivery_step_cvr is 48%, below 65% benchmark. AOV is $62.",
"domain": "shipping",
"urgency": "HIGH",
"advice": {
"action": "create_shipping_option",
"params": {
"category": "free_shipping",
"ids": ["region-guid"],
"rates": [{ "amount": "0", "conditions": [{ "type": "BY_TOTAL_PRICE", "operator": "GTE", "value": "75" }] }]
},
"successCriteria": "Free shipping option created for orders above $75"
},
"conversationId": "<conversationId>"
}
}Response: Single agenticRecommendation object with id, revision, and state: "PROPOSED".
Query recommendations by conversation ID, state, or domain. Returns paginated results.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/query
Request:
{
"query": {
"filter": {
"conversationId": "<conversationId>",
"state": { "$in": ["PROPOSED", "APPROVED"] }
},
"cursorPaging": { "limit": 50 }
}
}Filterable fields: conversationId, state, domain, urgency, id
Response:
{
"agenticRecommendations": [
{
"id": "a1b2c3d4-...",
"revision": "1",
"state": "PROPOSED",
"title": "...",
"domain": "discounts",
"urgency": "HIGH",
"advice": { "..." : "..." }
}
],
"pagingMetadata": { "count": 1, "cursors": {}, "hasNext": false }
}Fetch a single recommendation by ID.
Endpoint: GET https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}
Response: Single agenticRecommendation object with all fields.
Get recommendation counts grouped by state for the current site.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/count
Request: {}
Response:
{
"counts": {
"PROPOSED": 3,
"APPROVED": 1,
"EXECUTING": 0,
"DONE": 5,
"FAILED": 1,
"REJECTED": 2
}
}Update a PROPOSED recommendation. Only title, reasoning, urgency, advice, and expiresAt can be updated. State stays PROPOSED.
Endpoint: PATCH https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}
Request:
{
"agenticRecommendation": {
"id": "a1b2c3d4-...",
"revision": "1",
"advice": {
"action": "apply_discount",
"params": { "discount": 20 },
"successCriteria": "20% discount applied"
}
},
"fieldMask": { "paths": ["advice"] }
}Response: Updated agenticRecommendation with incremented revision.
Constraint: Only works on PROPOSED recommendations. Non-PROPOSED returns INVALID_STATE_TRANSITION.
PROPOSED → APPROVED. Call when the merchant agrees with a recommendation.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}/approve
Request:
{
"revision": "1"
}Response: Updated agenticRecommendation with state: "APPROVED" and incremented revision.
PROPOSED → REJECTED. Call when the merchant declines.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}/reject
Request:
{
"revision": "1",
"reason": "Merchant prefers flat-rate discount instead",
"permanent": false
}| Field | Type | Required | Description |
|---|---|---|---|
revision | int64 | Yes | Current revision for optimistic locking |
reason | string | No | Why the merchant rejected (max 1000 chars) |
permanent | boolean | No | If true, permanently blocks this action type for this site |
Response: Updated agenticRecommendation with state: "REJECTED".
APPROVED → EXECUTING. Call immediately before applying the recommendation.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}/mark-executing
Request:
{
"revision": "2"
}Response: Updated agenticRecommendation with state: "EXECUTING" and incremented revision.
EXECUTING → DONE. Call after the recommendation was successfully applied.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}/mark-done
Request:
{
"revision": "3",
"executionResult": {
"status": "SUCCESS",
"summary": "Created 15% discount rule for Electronics with $200 minimum"
}
}Response: Updated agenticRecommendation with state: "DONE" and executionResult.
EXECUTING → FAILED. Call when execution fails.
Endpoint: POST https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations/{agenticRecommendationId}/mark-failed
Request:
{
"revision": "3",
"executionResult": {
"status": "FAILURE",
"summary": "Failed to create discount rule",
"error": "REVISION_MISMATCH: discount rule was modified by another process"
}
}Response: Updated agenticRecommendation with state: "FAILED" and executionResult.
| Error | HTTP | Meaning |
|---|---|---|
| RECOMMENDATION_SUPPRESSED | 400 | Action + site blocked by permanent rejection |
| INVALID_STATE_TRANSITION | 400 | Wrong source state for the requested transition |
| VERSION_MISMATCH | 400 | Optimistic lock conflict — re-fetch and retry |
| RECOMMENDATION_NOT_FOUND | 404 | ID doesn’t exist |
On VERSION_MISMATCH: Query to get the latest revision, then retry the operation with the updated revision.
Every recommendation flow MUST follow this lifecycle:
Step 1: Generate recommendations (domain-specific analysis)
Step 2: BatchCreate → persist ALL recommendations as PROPOSED (save id + revision for each)
Step 3: Present recommendations to merchant (include id + revision)
Step 4: On each merchant action:
- APPROVE: Approve → MarkExecuting → apply the change → MarkDone or MarkFailed
- REJECT: Reject (with reason, permanent flag)
- MODIFY: Update (field mask) → stays PROPOSED → re-presentRules:
revision from the previous API response