Skip to main content

PolicyEngine Household API

A version of the PolicyEngine API that runs the calculate endpoint over household object. To debug locally, run make debug.

Quick self-hosted run

If you want to try the API without requesting hosted credentials, run a published Docker image:

docker run --rm -p 8080:8080 ghcr.io/policyengine/policyengine-household-api:current

Image tags mirror the hosted API's release channels:

Tag Meaning
current (also latest) Same model version as the hosted API's default channel
frontier Next week's model version, same as the hosted frontier channel
us-<version> Exact policyengine-us version, e.g. us-1.726.0

current and frontier move weekly — docker pull to refresh. A container serves exactly one model version; the hosted API's request-body version routing does not exist locally, so run one container per version to compare.

The image can take a little time to initialize on first start and is best run on a machine with roughly 4 GB of RAM available.

Then inspect the service metadata:

curl http://localhost:8080/

and send calculations to:

http://localhost:8080/us/calculate

To run a policyengine-us version that has no published tag, build and run it yourself:

docker build -f gcp/policyengine_household_api/Dockerfile.production \
  --build-arg POLICYENGINE_US_VERSION=1.725.0 -t household-api:us-1.725.0 .
docker run --rm -p 8080:8080 household-api:us-1.725.0

Hosted API docs live at https://www.policyengine.org/us/api.

Local development with Docker Compose

To run this app locally via Docker Compose:

% make docker-build
% make docker-run

and point your browser at http://localhost:8080 to access the API.

To develop the code locally, you will want to instead start only the Redis docker container and a one-off API container, with your local filesystem mounted into the running docker container.

% make services-start
% make docker-console

Then inside the container, start the Flask service:

policyapi@[your-docker-id]:/code$ make debug

and point your browser at http://localhost:8080 to access the API.

Running with other PolicyEngine services

If you're running this alongside other PolicyEngine services (e.g., the main API) and need containers to communicate across projects, use the external network mode:

% make docker-network-create   # Create shared network (once)
% make docker-run-external     # Run with external network

This connects the household API to a shared policyengine-api_default network that other PolicyEngine docker-compose projects can also join.

For development with external networking:

% make docker-network-create
% make services-start-external
% make docker-console

Period-key conventions

Every input and output on /calculate is keyed by a period string. Two shapes are supported:

  • Year key — "2026". Treated as the value for the entire year.
  • Month key — "2026-01". Treated as the value for that single month.

Each PolicyEngine variable has a fixed definition_period (year or month). Annual variables like employment_income and state_name are defined for the year; monthly variables like snap_earned_income, snap_gross_income, and rent are defined for the month.

Recommended pattern: stay consistent within a request

Pick one cadence per request and use it everywhere:

You want Send inputs as Request outputs as
Annual totals {"2026": V} {"2026": null}
A specific month {"2026-01": V} {"2026-01": null}

If you only think in yearly amounts, use year keys for everything — including monthly variables. For numeric inputs, the API treats the year value as the annual total and distributes it as V/12 across the 12 months before the engine runs; the engine returns the annual sum on the way back. Booleans, strings, and enums are broadcast unchanged across months.

If you need per-month variation, key both the input and the output to the same month.

Sending both annual and monthly inputs for the same variable

You can pin specific months while letting the year value cover the rest. For numeric MONTH-defined variables, the year value is treated as the annual total: explicit monthly values consume part of the budget, and the remainder splits evenly across the unset months. This matches the hosted v1 API and OpenFisca's set_input_divide_by_period.

// Annual $1200 with June pinned to $600. Remaining $600 splits across
// the other 11 months as raw float ≈ $54.55/mo.
"snap_earned_income": {"2026": 1200, "2026-06": 600}

For boolean / string / enum MONTH-defined variables, explicit monthly values override the year-broadcast for that month while the year value applies to the rest:

// "SUA all year except LUA in June".
"snap_utility_allowance_type": {"2026": "SUA", "2026-06": "LUA"}

The API only rejects with a 400 when every month of the year is explicit AND those monthlies don't sum to the annual total — that's an "Inconsistent input" the engine can't reconcile. Partial monthly overrides (any number from 0 to 11 explicit months) are accepted; the remainder is distributed across the unset months even when it's negative (matching v1 / OpenFisca exactly). Output-request null slots don't count as inputs, so {"2026": 1200, "2026-06": null} keeps both: the year expands as usual and the engine returns June's value.

What goes wrong when you mix shapes

Sending a single-month input ({"2026-01": V}) on a monthly variable but requesting an annual output ({"2026": null}) is the most common pitfall. The other 11 months default to 0 in the engine, so the annual sum looks like a year of benefits even though only January was actually specified. The API returns a warnings array in the response when it detects this combination so you can correct the request before relying on the number.

What the API echoes back

Output keys are echoed back exactly as you sent them. Input keys are preserved unchanged; the year-to-month split happens internally and never shows up in the response.

Development rules

  1. Every endpoint should return a JSON object with at least a "status" and "message" field.

Please note that we do not support branched operations at this time.

Release files for policyengine-household-api 0.32.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for policyengine-household-api 0.32.5
File Size Uploaded
policyengine_household_api-0.32.5.tar.gz 36.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for policyengine-household-api 0.32.5
File Interpreter ABI Platform
policyengine_household_api-0.32.5-py3-none-any.whl Python 3 none any Details

Total release size: 82.9 kB

Release files / policyengine_household_api-0.32.5.tar.gz

Download URL policyengine_household_api-0.32.5.tar.gz
Size 36.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7e1d280136c8d5acb2bb42ee00e28e78361c843a8f236e69ca048e56594eab8f
BLAKE2b-256 checksum
How to use checksums
31f84e669ee5dbfe561e7064c90c3f97c2b4687228bcfffe49bcd029ef8f352f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / policyengine_household_api-0.32.5-py3-none-any.whl

Download URL policyengine_household_api-0.32.5-py3-none-any.whl
Size 46.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e5701ea91dcc69ba6a1e23438da9b2741920c78dc9101ee7bf8e51c668e37602
BLAKE2b-256 checksum
How to use checksums
dd4b5652fc2a151dcb0e536a4097f3edb1a753219a66a272df4d2a976104697c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.32.9

2 release files

0.32.8

2 release files

0.32.6

2 release files

This release

0.32.5 This release

2 release files

0.32.1

2 release files

0.32.0

2 release files

0.31.2

2 release files

0.31.1

2 release files

0.31.0

2 release files

0.30.1

2 release files

0.30.0

2 release files

0.29.8

2 release files

0.29.7

2 release files

0.29.6

2 release files

0.29.5

2 release files

0.29.4

2 release files

0.29.3

2 release files

0.29.2

2 release files

0.28.3

2 release files

0.25.4

2 release files

0.25.3

2 release files

0.25.2

2 release files

0.24.0

2 release files

0.23.4

2 release files

0.23.2

2 release files

0.22.5

2 release files

0.22.4

2 release files

0.22.3

2 release files

0.21.4

2 release files

0.21.2

2 release files

0.21.1

2 release files

0.20.3

2 release files

0.20.2

2 release files

0.19.9

2 release files

0.19.6

2 release files

0.19.4

2 release files

0.18.0

2 release files

0.17.0

2 release files

0.16.2

2 release files

0.15.0

2 release files

0.14.4

2 release files

0.14.3

2 release files

0.5.53

1 release file

0.3.10

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page