Flow: Optimize Shipping Rates
Routing rule: BEFORE taking any action, call
ReadFullDocsArticleon Shipping API Reference. The Query Shipping Options and Update/Create Shipping Option endpoints used in Steps 2–4 live there. Do NOT query or modify any shipping options without loading it first.
Rate pricing sanity (inline guardrail)
Validate every rate you create or update against the store's AOV; flag any that fail:
| Check | Threshold | Why / fix |
|---|---|---|
| Excessive rate | amount > AOV × 0.15 | top cart-abandonment driver |
| Per-item penalty | multiplyByQuantity: true |
penalizes larger orders → use flat/tiered |
| Free threshold too high | threshold > AOV × 2 | unreachable; lower to ~AOV × 1.2 |
| Free threshold too low | threshold < AOV × 0.8 | no upsell incentive; raise to ~AOV × 1.2 |
| Backup rate shock | backupRate.amount > AOV × 0.15 |
set to 5–10% of AOV |
| Hidden surcharges | total additionalCharges > AOV × 0.10 |
review necessity |
Analyzes the site's catalog price distribution and current shipping rate structure to determine if the rate strategy is optimal. Recommends and applies changes when flat rates should become tiered, when tier gaps exist, or when per-item penalties are harming conversion.
Prerequisites
- Wix Stores (or another eCommerce business solution) installed on the site
- Catalog stats available (product_count, price quantiles, price_stddev)
- Site metrics available for AOV calculation
- At least one shipping option configured
Required APIs
Step 1: Gather catalog price distribution
Retrieve catalog statistics for the "All Products" category group. Required fields:
| Metric | Description |
|---|---|
product_count |
Total number of products |
price_min |
Lowest product price |
price_max |
Highest product price |
price_avg |
Average product price |
price_stddev |
Standard deviation of prices |
price_p25 |
25th percentile price |
price_p50 |
50th percentile (median) price |
price_p75 |
75th percentile price |
price_p90 |
90th percentile price |
1a: Calculate price spread ratio
price_spread_ratio = price_max / price_minThis ratio indicates how diverse the catalog pricing is. A ratio of 3 means the most expensive product is 3x the cheapest; a ratio of 50 means extreme price diversity.
Step 2: Query current shipping options
Retrieve all shipping options to analyze the existing rate structure.
Endpoint: POST https://www.wixapis.com/ecom/v1/shipping-options/query
Request:
{
"query": {
"cursorPaging": {
"limit": 100
}
}
}Response:
{
"shippingOptions": [
{
"id": "c0e5be8f-5266-4720-a732-5f571e4750db",
"revision": "1",
"deliveryRegionId": "42b0ed3b-fc54-4ac0-89cf-5d2d17ec441c",
"deliveryRegionIds": [],
"title": "Standard Shipping",
"estimatedDeliveryTime": "5-7 business days",
"rates": [
{
"amount": "15.00",
"conditions": [],
"multiplyByQuantity": false
}
]
}
],
"pagingMetadata": {
"count": 1,
"cursors": {},
"hasNext": false
}
}For each option, classify its rate structure:
- Flat rate:
conditions[]is empty - Tiered: Multiple rates with
BY_TOTAL_PRICE,BY_TOTAL_WEIGHT, orBY_TOTAL_QUANTITYconditions - Free shipping:
amount="0" - Per-item:
multiplyByQuantity=true
Step 3: Apply the rate strategy decision tree
3a: Check for per-item penalty (highest priority)
If any shipping option has multiplyByQuantity=true, flag it immediately.
Problem: Per-item charging means shipping cost = amount x cart quantity. A $5 rate on a 5-item order charges $25 for shipping. This discourages larger carts and directly conflicts with AOV growth goals.
Recommendation: Switch to flat rate or tiered pricing. Update the option to set multiplyByQuantity=false.
3b: Evaluate flat-to-tiered conversion
Check ALL three conditions. If all are true, recommend converting flat rates to price-based tiers:
| Condition | Threshold |
|---|---|
price_spread_ratio > 10 |
Catalog has extreme price diversity |
price_stddev > price_avg x 0.5 |
High variance in pricing |
| Only flat rates currently exist | No tiered structure in place |
If all three conditions are met, recommend price-based tiers:
| Tier | Price Range | Rate Strategy |
|---|---|---|
| Tier 1 | Orders below price_p50 |
Lower flat rate |
| Tier 2 | Orders price_p50 to price_p75 |
Standard rate |
| Tier 3 | Orders above price_p75 |
Higher rate or free shipping |
3c: Confirm flat rate is optimal
If ALL of the following are true, flat rate is the correct strategy -- no changes needed:
| Condition | Threshold |
|---|---|
price_spread_ratio <= 3 |
Narrow price range |
price_stddev < price_avg x 0.3 |
Low variance |
Report: "Your catalog has a narrow price range. Flat rate shipping is the optimal strategy. No changes recommended."
3d: Check for tier gaps in existing tiered options
For options that already use tiered pricing (weight-based or price-based conditions):
- Sort all rates by their condition
value - Look for gaps between tier boundaries
Example gap: Tier 1 has LTE 5 (kg or $), Tier 2 has GT 10. A cart at 7 matches neither tier and gets no shipping rate for this option.
Fix: Adjust condition boundaries to ensure complete, contiguous coverage.
Step 4: Apply recommended changes
4a: Fix per-item penalty
Update the shipping option to disable per-item multiplication.
Endpoint: PATCH https://www.wixapis.com/ecom/v1/shipping-options/{shippingOptionId}
Request:
{
"shippingOption": {
"id": "c0e5be8f-5266-4720-a732-5f571e4750db",
"revision": "1",
"title": "Standard Shipping",
"estimatedDeliveryTime": "5-7 business days",
"rates": [
{
"amount": "9.99",
"multiplyByQuantity": false,
"conditions": []
}
]
}
}Response:
{
"shippingOption": {
"id": "c0e5be8f-5266-4720-a732-5f571e4750db",
"revision": "2",
"createdDate": "2026-04-14T14:43:24.804Z",
"updatedDate": "2026-04-15T13:14:13.716Z",
"deliveryRegionId": "42b0ed3b-fc54-4ac0-89cf-5d2d17ec441c",
"deliveryRegionIds": [],
"title": "Standard Shipping",
"estimatedDeliveryTime": "5-7 business days",
"rates": [
{
"amount": "9.99",
"conditions": [],
"multiplyByQuantity": false
}
]
}
}4b: Create tiered shipping option
When converting from flat to tiered, create a new option with price-based tiers. Use catalog quantiles to set tier boundaries.
Example with price_p50=$35, price_p75=$80:
Endpoint: POST https://www.wixapis.com/ecom/v1/shipping-options
Request:
{
"shippingOption": {
"title": "Standard Shipping",
"estimatedDeliveryTime": "5-7 business days",
"deliveryRegionId": "42b0ed3b-fc54-4ac0-89cf-5d2d17ec441c",
"rates": [
{
"amount": "9.99",
"multiplyByQuantity": false,
"conditions": [
{
"type": "BY_TOTAL_PRICE",
"operator": "LTE",
"value": "35"
}
]
},
{
"amount": "7.99",
"multiplyByQuantity": false,
"conditions": [
{
"type": "BY_TOTAL_PRICE",
"operator": "GT",
"value": "35"
},
{
"type": "BY_TOTAL_PRICE",
"operator": "LTE",
"value": "80"
}
]
},
{
"amount": "0",
"multiplyByQuantity": false,
"conditions": [
{
"type": "BY_TOTAL_PRICE",
"operator": "GT",
"value": "80"
}
]
}
]
}
}Response:
{
"shippingOption": {
"id": "f3a4b5c6-d7e8-9012-fghi-345678901def",
"revision": "1",
"createdDate": "2026-04-15T14:00:00.000Z",
"updatedDate": "2026-04-15T14:00:00.000Z",
"deliveryRegionId": "42b0ed3b-fc54-4ac0-89cf-5d2d17ec441c",
"deliveryRegionIds": [],
"title": "Standard Shipping",
"estimatedDeliveryTime": "5-7 business days",
"rates": [
{
"amount": "9.99",
"conditions": [
{
"type": "BY_TOTAL_PRICE",
"operator": "LTE",
"value": "35"
}
],
"multiplyByQuantity": false
},
{
"amount": "7.99",
"conditions": [
{
"type": "BY_TOTAL_PRICE",
"operator": "GT",
"value": "35"
},
{
"type": "BY_TOTAL_PRICE",
"operator": "LTE",
"value": "80"
}
],
"multiplyByQuantity": false
},
{
"amount": "0",
"conditions": [
{
"type": "BY_TOTAL_PRICE",
"operator": "GT",
"value": "80"
}
],
"multiplyByQuantity": false
}
]
}
}Tier logic: Multiple conditions within the same rate use AND logic. The middle tier (GT 35 AND LTE 80) matches cart totals between $35 and $80.
Step 5: Verify updated rates
Re-query shipping options to confirm changes took effect.
Endpoint: POST https://www.wixapis.com/ecom/v1/shipping-options/query
Verify:
- Per-item options now have
multiplyByQuantity=false - Tiered options have contiguous tier boundaries with no gaps
- All options have
estimatedDeliveryTimepopulated - Rate amounts are reasonable (no single rate exceeds 15% of effective_aov)
- Updated options show incremented
revisionvalues
Error Handling
| Error | Cause | Fix |
|---|---|---|
SHIPPING_OPTION_NOT_FOUND |
Option ID doesn't exist | Re-query shipping options to get current IDs |
REVISION_MISMATCH |
Revision doesn't match the current version | Re-fetch the option for the latest revision, then retry |
deliveryRegionId is not a valid GUID |
Used deliveryRegionIds (plural) instead of deliveryRegionId (singular) |
Use the singular deliveryRegionId field |
| Tier gap detected after update | Condition boundaries don't cover all ranges | Verify tier boundaries are contiguous: use LTE for upper bounds and GT for lower bounds of adjacent tiers |
| Rate exceeds 15% of AOV | Shipping cost is a cart abandonment risk | Lower the rate amount or add a free shipping tier for larger orders |