Create and Apply Forecast Events
This guide shows you how to create a promotional event and apply it to a forecast scenario to adjust demand predictions.
Prerequisites
- API Key: Valid API key with
forecast.write permission
- Organization Access: Access to your organization’s forecasting features
- Product ID: Product master ID for product-specific events (optional)
- Location ID: Location ID for location-specific events (optional)
Step-by-Step Guide
Step 1: Create an External Event
Create a promotional event that will drive demand adjustments.
Request:
curl -X POST "https://app.betterdata.co/api/forecast/events" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale 2024",
"type": "PROMOTION",
"startsAt": "2024-06-01T00:00:00Z",
"endsAt": "2024-06-30T23:59:59Z",
"value": {
"liftPct": 0.25,
"stackingMode": "MULTIPLICATIVE",
"description": "25% lift during summer sale promotion"
},
"productMasterId": "prod_123"
}'
Response:
{
"id": "event_789",
"name": "Summer Sale 2024",
"type": "PROMOTION",
"startsAt": "2024-06-01T00:00:00Z",
"endsAt": "2024-06-30T23:59:59Z",
"value": {
"liftPct": 0.25,
"stackingMode": "MULTIPLICATIVE"
},
"isGlobal": false,
"isOrgWide": true,
"productMaster": {
"id": "prod_123",
"name": "Product Name",
"sku": "SKU-123"
},
"createdAt": "2024-03-15T00:00:00Z"
}
Notes:
- Event Types:
PROMOTION, PRICE_CHANGE, HOLIDAY, WEATHER, BOOKING, MACRO, OTHER
- Lift Percentage: Range from -0.99 (99% reduction) to 5 (500% increase)
- Stacking Mode:
MULTIPLICATIVE: Events multiply together (e.g., 1.25 × 1.15 = 1.4375)
ADDITIVE: Events add together (e.g., 0.25 + 0.15 = 0.40)
- Global Events: Set
productMasterId to null for organization-wide events
- Org-Wide Events: Set
locationId to null for location-agnostic events
Step 2: Create or Select a Forecast Scenario
Create a new forecast scenario or use an existing one.
Request:
curl -X POST "https://app.betterdata.co/api/forecast/scenarios" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Q2 2024 with Promotions",
"description": "Forecast including summer sale promotion",
"type": "PROMOTIONAL",
"assumptions": {
"narrative": "Q2 includes major promotional campaign",
"includedEventIds": ["event_789"]
}
}'
Response:
{
"scenario": {
"id": "scenario_456",
"name": "Q2 2024 with Promotions",
"description": "Forecast including summer sale promotion",
"type": "PROMOTIONAL",
"status": "DRAFT",
"createdAt": "2024-03-15T00:00:00Z"
}
}
Notes:
- Scenario Types:
BASELINE, PROMOTIONAL, CONSERVATIVE, OPTIMISTIC, CHANNEL_LAUNCH, CUSTOM
- Event Inclusion: Add event IDs to
includedEventIds array
- Multiple Events: Include multiple events to model complex scenarios
Step 3: Generate Forecasts for the Scenario
Generate forecasts that incorporate the event.
Request:
curl -X POST "https://app.betterdata.co/api/forecast/scenarios/scenario_456/generate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"productMasterIds": ["prod_123"],
"locationIds": ["loc_123"],
"horizonDays": 90,
"forceRegenerate": false
}'
Response:
{
"success": true,
"generated": 1,
"forecasts": [
{
"productMasterId": "prod_123",
"locationId": "loc_123",
"horizonDays": 90,
"generatedAt": "2024-03-15T12:00:00Z"
}
]
}
Notes:
- Horizon Days: Forecast period (7-365 days)
- Force Regenerate: Set to
true to regenerate existing forecasts
- Selective Generation: Specify
productMasterIds and locationIds to limit scope
Step 4: Verify Event Impact
Check the forecast change history to see how the event affected forecasts.
Request:
curl -X GET "https://app.betterdata.co/api/forecast/change-history?productMasterId=prod_123&locationId=loc_123&changeTypes=EVENT_APPLIED" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"
Response:
{
"entries": [
{
"id": "change_123",
"changeType": "EVENT_APPLIED",
"eventId": "event_789",
"eventName": "Summer Sale 2024",
"beforeValue": 100,
"afterValue": 125,
"changePercent": 25,
"timestamp": "2024-03-15T12:00:00Z"
}
],
"total": 1,
"hasMore": false
}
Complete Example
Here’s a complete workflow combining all steps:
#!/bin/bash
API_KEY="YOUR_API_KEY"
BASE_URL="https://app.betterdata.co/api"
# Step 1: Create event
EVENT_RESPONSE=$(curl -s -X POST "${BASE_URL}/forecast/events" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale 2024",
"type": "PROMOTION",
"startsAt": "2024-06-01T00:00:00Z",
"endsAt": "2024-06-30T23:59:59Z",
"value": {
"liftPct": 0.25,
"stackingMode": "MULTIPLICATIVE"
}
}')
EVENT_ID=$(echo $EVENT_RESPONSE | jq -r '.id')
echo "Created event: $EVENT_ID"
# Step 2: Create scenario
SCENARIO_RESPONSE=$(curl -s -X POST "${BASE_URL}/forecast/scenarios" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"Q2 2024 with Promotions\",
\"type\": \"PROMOTIONAL\",
\"assumptions\": {
\"includedEventIds\": [\"${EVENT_ID}\"]
}
}")
SCENARIO_ID=$(echo $SCENARIO_RESPONSE | jq -r '.scenario.id')
echo "Created scenario: $SCENARIO_ID"
# Step 3: Generate forecasts
curl -X POST "${BASE_URL}/forecast/scenarios/${SCENARIO_ID}/generate" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"horizonDays": 90
}'
echo "Forecasts generated successfully"
Idempotency Notes
- Event Creation: Creating an event with the same name and date range will create a new event (not idempotent). Use event IDs to track which events you’ve already created.
- Scenario Generation: Generating forecasts for the same scenario multiple times will update existing forecasts unless
forceRegenerate is set to false and forecasts already exist.
- Event Application: Events are applied during forecast generation. Regenerating forecasts will reapply events.
- List Events: The events list endpoint supports pagination with
page and limit parameters (default: 20, max: 100).
- Change History: The change history endpoint uses
limit and offset for pagination (default: 50, max: 100).
Common Issues
Event Not Applied
Symptom: Event created but forecast doesn’t reflect the lift.
Solutions:
- Verify event is included in scenario’s
includedEventIds
- Check event date range overlaps with forecast period
- Ensure forecasts were generated after event was created
- Verify event
productMasterId and locationId match forecast scope
Invalid Lift Percentage
Symptom: Error when creating event with lift percentage.
Solutions:
- Ensure
liftPct is between -0.99 and 5
- Use decimal format (0.25 for 25%, not 25)
- Check
stackingMode is either MULTIPLICATIVE or ADDITIVE
Forecast Generation Fails
Symptom: Error when generating forecasts.
Solutions:
- Verify scenario status is
DRAFT or PUBLISHED (not ARCHIVED)
- Check product and location IDs are valid
- Ensure
horizonDays is between 7 and 365
- Verify you have
forecast.write permission
Related Pages
Permissions & Roles
Creating events and scenarios requires forecast.write permission. Generating forecasts requires ADMIN, MANAGER, or PLANNER role.