Skip to main content

Fetch Forecast Accuracy Metrics

This guide shows you how to retrieve forecast accuracy metrics (MAPE, WAPE, Bias) and segment them by location.

Prerequisites

  • API Key: Valid API key with forecast.read permission
  • Organization Access: Access to your organization’s forecasting features
  • Location IDs: Location IDs to segment metrics (optional)

Step-by-Step Guide

Step 1: Get Planning KPIs (Includes Forecast Accuracy)

Retrieve planning KPIs which include forecast accuracy metrics. Request:
curl -X GET "https://app.betterdata.co/api/planning/kpi?locationId=loc_123&period=LAST_30_DAYS" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "forecastAccuracy": {
    "period": "LAST_30_DAYS",
    "skuCount": 180,
    "mape": 18.5,
    "wape": 15.2,
    "bias": 2.3,
    "biasPercent": 2.3,
    "accuracy": 81.5,
    "excellentCount": 45,
    "goodCount": 82,
    "fairCount": 38,
    "poorCount": 15,
    "topOverforecast": [
      {
        "productMasterId": "prod_123",
        "productName": "Product A",
        "mape": 45.2,
        "bias": 15.3
      }
    ],
    "topUnderforecast": [
      {
        "productMasterId": "prod_456",
        "productName": "Product B",
        "mape": 38.7,
        "bias": -12.5
      }
    ]
  },
  "stockouts": { ... },
  "inventoryTurns": { ... },
  "carryingCosts": { ... },
  "serviceLevel": { ... },
  "weeksOfSupply": { ... }
}
Notes:
  • Period Options: LAST_7_DAYS, LAST_30_DAYS, LAST_90_DAYS, LAST_365_DAYS, CUSTOM
  • Location Filter: Include locationId to filter by location
  • Accuracy Categories:
    • Excellent: MAPE < 10%
    • Good: MAPE 10-20%
    • Fair: MAPE 20-30%
    • Poor: MAPE > 30%

Step 2: Segment by Location

Get accuracy metrics for each location by making separate requests. Request (Location 1):
curl -X GET "https://app.betterdata.co/api/planning/kpi?locationId=loc_123&period=LAST_30_DAYS" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Request (Location 2):
curl -X GET "https://app.betterdata.co/api/planning/kpi?locationId=loc_456&period=LAST_30_DAYS" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Request (All Locations):
curl -X GET "https://app.betterdata.co/api/planning/kpi?period=LAST_30_DAYS" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Step 3: Get SKU-Level Accuracy

Get detailed accuracy metrics for a specific SKU. Request:
curl -X GET "https://app.betterdata.co/api/planning/sku/SKU-123?locationId=loc_123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "productMasterId": "prod_123",
  "sku": "SKU-123",
  "name": "Product Name",
  "forecastAccuracy": 80,
  "forecastBias": 2.3,
  "forecastModel": "ETS",
  "forecastConfidence": 0.75,
  "currentStock": 150,
  "avgDailyDemand": 10.5,
  "weeksOfSupply": 2.0,
  "activeAlerts": []
}
Notes:
  • Forecast Accuracy: Percentage (100 - MAPE)
  • Forecast Bias: Positive = overforecast, Negative = underforecast
  • Forecast Model: Model used (e.g., ETS, ARIMA, Prophet)
  • Forecast Confidence: Confidence level (0-1)

Step 4: Compare Forecast to Actuals

Get detailed forecast vs actual comparison. Request:
curl -X GET "https://app.betterdata.co/api/forecast/change-history?productMasterId=prod_123&locationId=loc_123&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "entries": [
    {
      "id": "change_123",
      "changeType": "ACCURACY_UPDATED",
      "productMasterId": "prod_123",
      "locationId": "loc_123",
      "beforeValue": 100,
      "afterValue": 95,
      "mape": 18.5,
      "bias": 2.3,
      "timestamp": "2024-03-15T12:00:00Z"
    }
  ],
  "total": 25,
  "hasMore": false
}

Complete Example

Here’s a complete example that fetches accuracy metrics for all locations:
#!/bin/bash

API_KEY="YOUR_API_KEY"
BASE_URL="https://app.betterdata.co/api"
PERIOD="LAST_30_DAYS"

# Get all locations (assuming you have a locations endpoint)
LOCATIONS=$(curl -s -X GET "${BASE_URL}/locations" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" | jq -r '.locations[].id')

# Fetch accuracy for each location
for LOCATION_ID in $LOCATIONS; do
  echo "Fetching accuracy for location: $LOCATION_ID"
  
  RESPONSE=$(curl -s -X GET "${BASE_URL}/planning/kpi?locationId=${LOCATION_ID}&period=${PERIOD}" \
    -H "Authorization: Bearer ${API_KEY}" \
    -H "Content-Type: application/json")
  
  MAPE=$(echo $RESPONSE | jq -r '.forecastAccuracy.mape')
  WAPE=$(echo $RESPONSE | jq -r '.forecastAccuracy.wape')
  BIAS=$(echo $RESPONSE | jq -r '.forecastAccuracy.bias')
  ACCURACY=$(echo $RESPONSE | jq -r '.forecastAccuracy.accuracy')
  
  echo "Location: $LOCATION_ID"
  echo "  MAPE: ${MAPE}%"
  echo "  WAPE: ${WAPE}%"
  echo "  Bias: ${BIAS}%"
  echo "  Accuracy: ${ACCURACY}%"
  echo ""
done

Understanding Metrics

MAPE (Mean Absolute Percentage Error)

Formula: MAPE = (1/n) × Σ|Actual - Forecast| / Actual × 100 Interpretation:
  • < 10%: Excellent
  • 10-20%: Good
  • 20-30%: Fair
  • > 30%: Poor

WAPE (Weighted Absolute Percentage Error)

Formula: WAPE = Σ|Actual - Forecast| / ΣActual × 100 Interpretation: Similar to MAPE but weighted by actual values. Better for high-volume items.

Bias

Formula: Bias = (1/n) × Σ(Forecast - Actual) Interpretation:
  • Positive: Overforecasting (forecast > actual)
  • Negative: Underforecasting (forecast < actual)
  • Zero: Unbiased

Idempotency Notes

  • KPI Endpoints: KPI calculations are read-only and idempotent. Multiple requests return the same results for the same period.
  • Change History: Change history is append-only. New entries are added but existing entries don’t change.

Pagination Notes

  • Change History: Uses limit and offset for pagination (default: 50, max: 100).
  • KPI Endpoints: Return aggregated data and don’t require pagination.
  • SKU Endpoints: Return single SKU data and don’t require pagination.

Common Issues

No Accuracy Data

Symptom: Accuracy metrics are null or default values. Solutions:
  1. Verify forecasts have been generated
  2. Check that actuals data exists for the period
  3. Ensure sufficient historical data (minimum 7 days recommended)
  4. Verify product and location IDs are correct

Inconsistent Metrics Across Locations

Symptom: Different accuracy metrics for same product at different locations. Solutions:
  1. This is expected - each location has different demand patterns
  2. Verify location-specific forecasts were generated
  3. Check that actuals are location-specific
  4. Review location-specific events that may affect forecasts

High Bias Values

Symptom: Large positive or negative bias values. Solutions:
  1. Review forecast model parameters
  2. Check for systematic over/under-forecasting
  3. Consider adjusting forecast assumptions
  4. Review events that may affect forecasts


Permissions & Roles

Reading forecast accuracy metrics requires forecast.read permission. No special roles required beyond basic authentication.