Base URL:

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")