Quick start
Get up and running with the PolicyEngine API in minutes.
1. Start the services
Clone the repository and start the services using Docker Compose:
git clone https://github.com/PolicyEngine/policyengine-api-v2 cd policyengine-api-v2 docker compose up -d
Wait for all services to be healthy before proceeding.
2. Create a policy reform
Define a policy reform by specifying parameter changes:
curl -X POST https://v2.api.policyengine.org/policies \
-H "Content-Type: application/json" \
-d '{
"name": "Increased personal allowance",
"description": "Raises personal allowance to £15,000",
"parameter_values": [{
"parameter_id": "<parameter-uuid>",
"value_json": {"value": 15000},
"start_date": "2026-01-01",
"end_date": "2026-12-31"
}]
}'3. Run economic impact analysis
Submit an economic impact analysis request. This creates baseline and reform simulations and queues them for processing:
curl -X POST https://v2.api.policyengine.org/analysis/economic-impact \
-H "Content-Type: application/json" \
-d '{
"tax_benefit_model_name": "policyengine_uk",
"dataset_id": "<dataset-uuid>",
"policy_id": "<policy-uuid>"
}'The response includes a report_id and initial status.
4. Poll for results
Check the status until the report is complete:
curl https://v2.api.policyengine.org/analysis/economic-impact/<report-id>
Once complete, the response includes decile impacts and program statistics:
{
"report_id": "abc123...",
"status": "completed",
"decile_impacts": [
{
"decile": 1,
"baseline_mean": 12500,
"reform_mean": 13200,
"relative_change": 0.056
}
],
"program_statistics": [
{
"program_name": "income_tax",
"baseline_total": 210000000000,
"reform_total": 195000000000,
"change": -15000000000
}
]
}Python example
Complete workflow using httpx:
import httpx
import time
BASE_URL = "https://v2.api.policyengine.org"
# Create economic impact analysis
response = httpx.post(
f"{BASE_URL}/analysis/economic-impact",
json={
"tax_benefit_model_name": "policyengine_uk",
"dataset_id": "<dataset-uuid>",
"policy_id": "<policy-uuid>",
},
).json()
report_id = response["report_id"]
# Poll for completion
while True:
result = httpx.get(f"{BASE_URL}/analysis/economic-impact/{report_id}").json()
if result["status"] == "completed":
break
elif result["status"] == "failed":
raise Exception(f"Analysis failed: {result['error_message']}")
time.sleep(5)
# Access results
for decile in result["decile_impacts"]:
print(f"Decile {decile['decile']}: {decile['relative_change']:.1%} change")
for prog in result["program_statistics"]:
print(f"{prog['program_name']}: £{prog['change']/1e9:.1f}bn change")