Guides
This guide shows you how to retrieve forecast accuracy metrics (MAPE, WAPE, Bias) and segment them by location.
forecast.read permissionRetrieve planning KPIs which include forecast accuracy metrics.
Request:
1curl -X GET "https://app.betterdata.co/api/planning/kpi?locationId=loc_123&period=LAST_30_DAYS" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Response:
1{2 "forecastAccuracy": {3 "period": "LAST_30_DAYS",4 "skuCount": 180,5 "mape": 18.5,6 "wape": 15.2,7 "bias": 2.3,8 "biasPercent": 2.3,9 "accuracy": 81.5,10 "excellentCount": 45,11 "goodCount": 82,12 "fairCount": 38,13 "poorCount": 15,14 "topOverforecast": [15 {16 "productMasterId": "prod_123",17 "productName": "Product A",18 "mape": 45.2,19 "bias": 15.320 }21 ],22 "topUnderforecast": [23 {24 "productMasterId": "prod_456",25 "productName": "Product B",26 "mape": 38.7,27 "bias": -12.528 }29 ]30 },31 "stockouts": { ... },32 "inventoryTurns": { ... },33 "carryingCosts": { ... },34 "serviceLevel": { ... },35 "weeksOfSupply": { ... }36}Notes:
LAST_7_DAYS, LAST_30_DAYS, LAST_90_DAYS, LAST_365_DAYS, CUSTOMlocationId to filter by locationGet accuracy metrics for each location by making separate requests.
Request (Location 1):
1curl -X GET "https://app.betterdata.co/api/planning/kpi?locationId=loc_123&period=LAST_30_DAYS" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Request (Location 2):
1curl -X GET "https://app.betterdata.co/api/planning/kpi?locationId=loc_456&period=LAST_30_DAYS" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Request (All Locations):
1curl -X GET "https://app.betterdata.co/api/planning/kpi?period=LAST_30_DAYS" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Get detailed accuracy metrics for a specific SKU.
Request:
1curl -X GET "https://app.betterdata.co/api/planning/sku/SKU-123?locationId=loc_123" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Response:
1{2 "productMasterId": "prod_123",3 "sku": "SKU-123",4 "name": "Product Name",5 "forecastAccuracy": 80,6 "forecastBias": 2.3,7 "forecastModel": "ETS",8 "forecastConfidence": 0.75,9 "currentStock": 150,10 "avgDailyDemand": 10.5,11 "weeksOfSupply": 2.0,12 "activeAlerts": []13}Notes:
Get detailed forecast vs actual comparison.
Request:
1curl -X GET "https://app.betterdata.co/api/forecast/change-history?productMasterId=prod_123&locationId=loc_123&limit=50" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Response:
1{2 "entries": [3 {4 "id": "change_123",5 "changeType": "ACCURACY_UPDATED",6 "productMasterId": "prod_123",7 "locationId": "loc_123",8 "beforeValue": 100,9 "afterValue": 95,10 "mape": 18.5,11 "bias": 2.3,12 "timestamp": "2024-03-15T12:00:00Z"13 }14 ],15 "total": 25,16 "hasMore": false17}Here's a complete example that fetches accuracy metrics for all locations:
1#!/bin/bash2 3API_KEY="YOUR_API_KEY"4BASE_URL="https://app.betterdata.co/api"5PERIOD="LAST_30_DAYS"6 7# Get all locations (assuming you have a locations endpoint)8LOCATIONS=$(curl -s -X GET "${BASE_URL}/locations" \9 -H "Authorization: Bearer ${API_KEY}" \10 -H "Content-Type: application/json" | jq -r '.locations[].id')11 12# Fetch accuracy for each location13for LOCATION_ID in $LOCATIONS; do14 echo "Fetching accuracy for location: $LOCATION_ID"15 16 RESPONSE=$(curl -s -X GET "${BASE_URL}/planning/kpi?locationId=${LOCATION_ID}&period=${PERIOD}" \17 -H "Authorization: Bearer ${API_KEY}" \18 -H "Content-Type: application/json")19 20 MAPE=$(echo $RESPONSE | jq -r '.forecastAccuracy.mape')21 WAPE=$(echo $RESPONSE | jq -r '.forecastAccuracy.wape')22 BIAS=$(echo $RESPONSE | jq -r '.forecastAccuracy.bias')23 ACCURACY=$(echo $RESPONSE | jq -r '.forecastAccuracy.accuracy')24 25 echo "Location: $LOCATION_ID"26 echo " MAPE: ${MAPE}%"27 echo " WAPE: ${WAPE}%"28 echo " Bias: ${BIAS}%"29 echo " Accuracy: ${ACCURACY}%"30 echo ""31doneFormula: MAPE = (1/n) × Σ|Actual - Forecast| / Actual × 100
Interpretation:
Formula: WAPE = Σ|Actual - Forecast| / ΣActual × 100
Interpretation: Similar to MAPE but weighted by actual values. Better for high-volume items.
Formula: Bias = (1/n) × Σ(Forecast - Actual)
Interpretation:
limit and offset for pagination (default: 50, max: 100).Symptom: Accuracy metrics are null or default values.
Solutions:
Symptom: Different accuracy metrics for same product at different locations.
Solutions:
Symptom: Large positive or negative bias values.
Solutions:
Reading forecast accuracy metrics requires forecast.read permission. No special roles required beyond basic authentication.
