Skip to content

API

cd-api is a small FastAPI service with one real job: serve current_members over HTTP for cd-lookup to consume. It’s wrapped with Mangum and deployed as an AWS Lambda function behind API Gateway — there’s no long-running server to patch or scale.

GET /members?state={state}&district={district}

Returns senators for the given state, and — if district is provided — the House representative for that district too.

{
"senators": [
{ "first_name": "Jane", "last_name": "Example", "role": "Senator", "party": "Democratic", "phone": "", "website": "", "photo_url": "" }
],
"representatives": [ { "...": "..." } ]
}

GET /version — returns the deployed version string, baked into the Lambda package at deploy time. Useful for confirming a deploy actually landed without digging through CloudWatch.

Errors are returned as application/problem+json, per RFC 9457 (“Problem Details for HTTP APIs”), instead of a bespoke { "error": "..." } shape. That means every error response is self-describing and machine-parseable in a standard way, not something a client has to guess at from reading the source.

This is the detail that’s easy to get wrong: not every “no representative found” is an error.

  • Unknown state404.
  • District number that doesn’t exist for that state → 404, validated against real U.S. House apportionment data (apportionment.py) — so a typo’d district number fails clearly instead of silently returning nothing.
  • District that exists but is currently vacant200 with an empty list. A vacancy is a true, valid state, not an error.

Collapsing these into one generic “not found” would make the API lie about which case actually happened.

  • Lambda + RDS Proxy. Lambda’s connection model (many short-lived invocations) doesn’t play well with Postgres’s per-connection overhead, so cd-api connects through RDS Proxy rather than directly to RDS.
  • Tag-triggered deploys. A cd-api-v* tag triggers cd-api-deploy.yml, which builds a Lambda zip with uv, checks it against Lambda’s 50MB limit, and calls aws lambda update-function-code.
  • Keyless CI. The deploy workflow assumes an IAM role via GitHub OIDC — no static AWS credentials stored in GitHub. More on this in CI/CD & Automation.