PolicyEngine household API

Send household calculation requests over HTTP using PolicyEngine's hosted REST API or the self-hosted Docker image. Use the API guide when you need tokens, endpoints, request bodies, or deployment instructions.

API path

Choose how you want to run the HTTP interface.

Use the hosted PolicyEngine endpoint with OAuth credentials issued by PolicyEngine.

Getting started

The HTTP interface has two paths: the hosted API and the self-hosted Docker image. Start with Docker if you want to make requests immediately on your own machine. Use the hosted API when you want PolicyEngine-managed infrastructure and issued credentials.

Hosted API

Use our managed endpoint with OAuth credentials issued by PolicyEngine.

Docker image

Run the same household API yourself via GitHub Container Registry, without waiting for credentials.

Need direct Python access?

The package guide is now separate from the API docs. Use policyengine[us] when you want to work locally with calculate_household_impact() or Simulation instead of sending HTTP requests.

Open Python package guide
OptionBest forAuthenticationWait time
Hosted APIManaged infrastructure and remote HTTP accessOAuth client credentialsRequires requesting access
Docker imageSelf-hosting the HTTP API on your own machine or infrastructureNone by defaultImmediate

Selected access path

The page is currently showing REST API examples. Use the sticky selector above to switch the whole page into a different integration path.

Hosted REST API

Use PolicyEngine's managed HTTP endpoint if you want a hosted integration rather than running the API yourself. This path requires OAuth client credentials issued by PolicyEngine.

Contact hello@policyengine.org to request API credentials.

Fetch an access token
curl --request POST \
  --url https://policyengine.uk.auth0.com/oauth/token \
  --header 'Content-Type: application/json' \
  --data '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://household.api.policyengine.org",
    "grant_type": "client_credentials"
  }'
Fetch an access token in Python
import requests

response = requests.post(
    "https://policyengine.uk.auth0.com/oauth/token",
    json={
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "audience": "https://household.api.policyengine.org",
        "grant_type": "client_credentials",
    },
)

token = response.json()["access_token"]
Token response
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
  "token_type": "Bearer"
}

Running a calculation

Both API paths accept the same household payload and return the same response shape. The difference is whether PolicyEngine hosts the endpoint or you run the container yourself.

Current access path: REST API

Send a POST request to the hosted calculate endpoint with your household object and a bearer token.

POST https://household.api.policyengine.org/us/calculate

The request body must contain a household key with your household object. The response returns the same structure with all computable variables filled in under the top-level result field.

Hosted API request
curl --request POST \
  --url https://household.api.policyengine.org/us/calculate \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "household": {
    "people": {
      "you": {
        "age": {
          "2025": 30
        },
        "employment_income": {
          "2025": 50000
        }
      }
    },
    "households": {
      "your household": {
        "members": [
          "you"
        ],
        "state_code": {
          "2025": "CA"
        }
      }
    },
    "families": {
      "your family": {
        "members": [
          "you"
        ]
      }
    },
    "tax_units": {
      "your tax unit": {
        "members": [
          "you"
        ]
      }
    },
    "marital_units": {
      "your marital unit": {
        "members": [
          "you"
        ]
      }
    },
    "spm_units": {
      "your spm unit": {
        "members": [
          "you"
        ]
      }
    }
  }
}'

Household payloads

The request body carries a household object that describes the people and their groupings for tax and benefit calculations. This structure is the same whether you call the hosted endpoint or the Docker container.

LevelDescriptionExample
Entity groupTop-level grouping category"people", "households"
EntityNamed instance within a group"person", "my household"
VariableProperty of an entity"employment_income", "eitc"
YearTime period for the value"2025"
ValueNumber, string, boolean, or null for outputs50000, "CA", null

Entity groups

US households require six entity groups. Each group contains named entities that reference people by name:

GroupPurpose
peopleIndividual persons in the household
householdsPhysical household (state, housing costs)
familiesFamily unit for benefit eligibility
tax_unitsTax filing unit (determines tax liability)
marital_unitsMarried couple pair
spm_unitsSupplemental Poverty Measure unit

Step 1: Start with empty groups

Empty household skeleton
{
  "people": {},
  "households": {},
  "families": {},
  "tax_units": {},
  "marital_units": {},
  "spm_units": {}
}

Step 2: Add people and assign to groups

Create named people and assign them to each group via the members array. Names are arbitrary strings that link people across groups.

Married couple with 2 children
{
  "people": {
    "adult1": {},
    "adult2": {},
    "child1": {},
    "child2": {}
  },
  "households": {
    "my household": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  },
  "families": {
    "my family": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  },
  "tax_units": {
    "my tax unit": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  },
  "marital_units": {
    "my marital unit": {
      "members": [
        "adult1",
        "adult2"
      ]
    }
  },
  "spm_units": {
    "my spm unit": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  }
}

Step 3: Add variables and values

Set input variables as {"year": value} pairs. For outputs you want calculated, set the value to null (or simply omit the variable: all computable variables are returned by default).

With income, ages, and state
{
  "people": {
    "adult1": {
      "age": {
        "2025": 40
      },
      "employment_income": {
        "2025": 30000
      }
    },
    "adult2": {
      "age": {
        "2025": 38
      },
      "employment_income": {
        "2025": 20000
      }
    },
    "child1": {
      "age": {
        "2025": 10
      }
    },
    "child2": {
      "age": {
        "2025": 7
      }
    }
  },
  "households": {
    "my household": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ],
      "state_code": {
        "2025": "AZ"
      }
    }
  },
  "families": {
    "my family": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  },
  "tax_units": {
    "my tax unit": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  },
  "marital_units": {
    "my marital unit": {
      "members": [
        "adult1",
        "adult2"
      ]
    }
  },
  "spm_units": {
    "my spm unit": {
      "members": [
        "adult1",
        "adult2",
        "child1",
        "child2"
      ]
    }
  }
}

Full example: EITC calculation

Putting it all together: a married couple in Arizona with two children and $50,000 combined income, calculating their Earned Income Tax Credit.

Current access path: REST API

Complete EITC calculation via hosted REST API
import requests

token = "YOUR_ACCESS_TOKEN"

household = {
    "people": {
        "adult1": {
            "age": {
                "2025": 40
            },
            "employment_income": {
                "2025": 30000
            }
        },
        "adult2": {
            "age": {
                "2025": 38
            },
            "employment_income": {
                "2025": 20000
            }
        },
        "child1": {
            "age": {
                "2025": 10
            }
        },
        "child2": {
            "age": {
                "2025": 7
            }
        }
    },
    "households": {
        "my household": {
            "members": [
                "adult1",
                "adult2",
                "child1",
                "child2"
            ],
            "state_code": {
                "2025": "AZ"
            }
        }
    },
    "families": {
        "my family": {
            "members": [
                "adult1",
                "adult2",
                "child1",
                "child2"
            ]
        }
    },
    "tax_units": {
        "my tax unit": {
            "members": [
                "adult1",
                "adult2",
                "child1",
                "child2"
            ]
        }
    },
    "marital_units": {
        "my marital unit": {
            "members": [
                "adult1",
                "adult2"
            ]
        }
    },
    "spm_units": {
        "my spm unit": {
            "members": [
                "adult1",
                "adult2",
                "child1",
                "child2"
            ]
        }
    }
}

response = requests.post(
    "https://household.api.policyengine.org/us/calculate",
    json={"household": household},
    headers={"Authorization": f"Bearer {token}"},
)

result = response.json()["result"]
eitc = result["tax_units"]["my tax unit"]["eitc"]["2025"]
print(f"EITC: {eitc:,.2f}")

Variables and parameters

Use variable names as keys in your household object, and parameter names to explore the policy rules that drive the simulation. Browse the full list in the model explorer.

Explore variables and parameters →

API terms and conditions

Review the terms that govern access to the PolicyEngine API before requesting credentials, integrating the hosted endpoint, or self-hosting the same interface.

Read API terms and conditions →