Simulation
Contents
Simulation#
For: developers
Run and analyze scenario-based program simulations through the API.
Warning
Known issue: The simulation:write scope is checked by every create/update/archive endpoint but cannot be granted — write is not a valid scope action in OpenSPP (the standard set is read, search, create, update, delete, all). Until the module is fixed, all create/update/archive operations on scenarios will return 403. Read-only operations (simulation:read) and execution (simulation:execute) work normally. Track this in the OpenSPP modules repo.
Overview#
The Simulation API (spp_api_v2_simulation) enables scenario-based testing of program designs before implementation. You can:
Design scenarios with targeting criteria, budgets, and entitlement rules
Run simulations against real registry data
Compare results across multiple scenarios
Convert scenarios into production programs
This is used for program design, impact analysis, and budget planning.
Prerequisites#
Install
spp_api_v2_simulationmoduleAPI client with appropriate scopes:
Scope |
Permissions |
|---|---|
|
View scenarios, runs, comparisons, templates |
|
Create/update/archive scenarios |
|
Run simulations |
|
Convert scenarios to programs |
Scenario Lifecycle#
┌───────┐ ┌───────┐ ┌──────────────┐
│ Draft │────►│ Ready │────►│ Run (N times) │
└───────┘ └───────┘ └──────────────┘
│
└──► Convert to Program
Templates#
List pre-built scenario templates for common program designs.
GET /api/v2/spp/simulation/templates
Authorization: Bearer TOKEN
Scenario Management#
List Scenarios#
GET /api/v2/spp/simulation/scenarios?state=ready&limit=50
Authorization: Bearer TOKEN
Query parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
|
|
string |
Scenario category |
|
integer |
Max results (default 100, max 500) |
|
integer |
Skip N results (default 0) |
Create Scenario#
POST /api/v2/spp/simulation/scenarios
Authorization: Bearer TOKEN
Content-Type: application/json
{
"name": "CCT for Female Adults",
"description": "Cash transfer targeting women aged 18+",
"category": "poverty_reduction",
"target_type": "individual",
"targeting_expression": "age >= 18 AND gender == 'F'",
"targeting_expression_explanation": "Female adults aged 18 and above",
"budget_amount": 5000000,
"budget_strategy": "per_beneficiary",
"ideal_population_expression": "poverty_score > 0.7",
"entitlement_rules": [
{
"amount_mode": "fixed",
"amount": 5000,
"multiplier_field": null,
"max_multiplier": 1
}
],
"program_id": 5
}
Key fields:
Field |
Type |
Description |
|---|---|---|
|
string |
CEL expression for eligibility |
|
number |
Total budget |
|
string |
|
|
string |
CEL expression defining the "ideal" target (for equity scoring) |
|
array |
Benefit amount rules |
Response (201 Created): Scenario object with computed fields like targeting_preview_count and equity_score.
Get Scenario#
GET /api/v2/spp/simulation/scenarios/{scenario_id}
Authorization: Bearer TOKEN
Update Scenario#
Only draft scenarios can be updated.
PUT /api/v2/spp/simulation/scenarios/{scenario_id}
Authorization: Bearer TOKEN
Content-Type: application/json
{
"budget_amount": 7500000,
"entitlement_rules": [
{"amount_mode": "fixed", "amount": 7500, "max_multiplier": 1}
]
}
Archive Scenario#
DELETE /api/v2/spp/simulation/scenarios/{scenario_id}
Authorization: Bearer TOKEN
Returns 204 No Content. This is a soft delete (archive).
Mark Scenario as Ready#
Transition from draft to ready (enables running simulations).
POST /api/v2/spp/simulation/scenarios/{scenario_id}/ready
Authorization: Bearer TOKEN
Running Simulations#
Execute Simulation#
POST /api/v2/spp/simulation/scenarios/{scenario_id}/run
Authorization: Bearer TOKEN
Response:
{
"run_id": 42,
"scenario_id": 5,
"state": "completed",
"message": "Simulation completed: 12,500 beneficiaries, total cost PHP 62,500,000"
}
List Runs#
GET /api/v2/spp/simulation/runs?scenario_id=5&state=completed
Authorization: Bearer TOKEN
Query parameters: scenario_id, state, limit, offset
Get Run Results#
GET /api/v2/spp/simulation/runs/{run_id}?include_details=true
Authorization: Bearer TOKEN
Response (with include_details=true):
{
"run_id": 42,
"scenario_id": 5,
"state": "completed",
"beneficiary_count": 12500,
"total_cost": 62500000,
"coverage_rate": 0.85,
"equity_score": 0.72,
"scenario_snapshot": {
"targeting_expression": "age >= 18 AND gender == 'F'",
"budget_amount": 5000000
},
"distribution_data": {
"percentiles": {"p10": 5000, "p25": 5000, "p50": 5000, "p75": 5000, "p90": 5000},
"gini_coefficient": 0.0,
"standard_deviation": 0.0
},
"fairness_data": {
"demographic_breakdown": {
"gender": {"F": 12500}
}
},
"targeting_efficiency_data": {
"leakage_rate": 0.05,
"undercoverage_rate": 0.15
},
"geographic_data": {
"area_breakdowns": []
}
}
Comparisons#
Compare results across multiple simulation runs.
Create Comparison#
POST /api/v2/spp/simulation/comparisons
Authorization: Bearer TOKEN
Content-Type: application/json
{
"name": "CCT: Fixed vs Variable Amount",
"run_ids": [42, 43]
}
Minimum 2 runs required. Returns overlap data (Jaccard similarity between beneficiary sets).
Get Comparison#
GET /api/v2/spp/simulation/comparisons/{comparison_id}
Authorization: Bearer TOKEN
Convert to Program#
Convert a ready scenario into a production program with CEL eligibility criteria and cash entitlement managers.
POST /api/v2/spp/simulation/scenarios/{scenario_id}/convert-to-program
Authorization: Bearer TOKEN
Content-Type: application/json
{
"name": "CCT for Female Adults 2024",
"currency_code": "PHP",
"is_one_time_distribution": false,
"import_beneficiaries": true,
"rrule_type": "monthly",
"cycle_duration": 1,
"day": 1,
"month_by": "date"
}
Response (201 Created):
{
"program_id": 15,
"program_name": "CCT for Female Adults 2024",
"warnings": []
}
Requires simulation:write and simulation:convert scopes. Only ready scenarios with entitlement rules can be converted. Program name must be unique.
Common mistakes#
Scenario won't transition to "ready"?
The scenario must pass validation. Check that targeting expression, budget, and entitlement rules are all configured.
Simulation run failed?
Check the state and message fields in the run response. Common causes: invalid CEL expression, no matching beneficiaries, or database timeout.
How are equity scores calculated?
The equity score compares the actual targeted population against the ideal_population_expression. Higher scores mean better targeting accuracy.
Can I re-run a simulation?
Yes. You can run a ready scenario multiple times. Each run creates a separate result record.
Convert-to-program fails?
Check that the scenario is in "ready" state, has entitlement rules, and the program name is unique.
What's next#
API Resources - Core program and membership resources
Entitlements and Cycles - Entitlements created by programs
Data API - Variable data for targeting expressions
See also#
API V2 Overview - API V2 design principles
Authentication - OAuth 2.0 setup and scopes
openspp.org