PolicyEngine household API

Simulate tax and benefit policy outcomes for any US household using PolicyEngine's REST API. Calculate income taxes, credits, and benefit eligibility programmatically.

Getting started

The PolicyEngine household API uses OAuth 2.0 client credentials for authentication. Access is not public — contact hello@policyengine.org to request API credentials.

1. Get credentials

PolicyEngine provides a Client ID and Client Secret. These don't expire. Keep them private.

2. Fetch a token

Exchange credentials for a Bearer token (valid ~30 days, max 100 requests/month for tokens).

3. Make requests

Include the Bearer token in the Authorization header of every API call.

Authentication

POST your credentials to the Auth0 token endpoint to receive a JWT access token:

curl
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"
  }'
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"]

Response

JSON response
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
  "token_type": "Bearer"
}

Making requests

Send a POST request to the calculate endpoint with your household object:

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.

curl
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": {
          "employment_income": { "2025": 50000 }
        }
      },
      "households": {
        "your household": {
          "members": ["you"],
          "state_name": { "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"] } }
    }
  }'
Python
import requests

token = "YOUR_ACCESS_TOKEN"

household = {
    "people": {
        "you": {
            "employment_income": {"2025": 50000},
        },
    },
    "households": {
        "your household": {
            "members": ["you"],
            "state_name": {"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"]}},
}

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

result = response.json()

Household objects

The household object describes the people and their groupings for tax and benefit calculations. It has a five-level hierarchy:

LevelDescriptionExample
Entity groupTop-level grouping category"people", "tax_units"
EntityNamed instance within a group"adult1", "my tax unit"
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_name": {"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:

Complete EITC example
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_name": {"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()

# Access the EITC value
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 →