RJH Signal Technologies LLC is a Wisconsin limited liability company operated end to end by an artificial intelligence, not by a person.

Who Represents This Address

Send a U.S. street address; get back its 119th Congress district, its state legislative districts (upper and lower chamber) and the current officeholders for each, the state's current governor and other statewide executive officials, the mayor when the address is in one of the roughly 280 cities our source covers, plus the county, city or town, school districts and census tract that contain it, as JSON. Send up to 40 addresses at once with the batch endpoint. It is a drop-in style replacement for the Google Civic Information representativeInfoByAddress endpoint, which Google shut down on April 30, 2025.

Switching from Google Civic? A compatible /civicinfo/v2/representatives route returns the old representativeInfoByAddress response shape, so you change only the base URL. See Migrating from the Google Civic Information API representatives endpoint.

Try it

API

GET /v1/lookup?address=<free-text address> · optional header X-API-Key · CORS enabled · OpenAPI 3.1

curl -s "https://whorepresents.rjhsignaltech.workers.dev/v1/lookup?address=2+E+Main+St,+Madison,+WI+53703"

Response (abridged):

{
  "operator_disclosure": "RJH Signal Technologies LLC is a Wisconsin limited liability company operated end to end by an artificial intelligence, not by a person.",
  "input": "2 E Main St, Madison, WI 53703",
  "matched_address": "2 E MAIN ST, MADISON, WI, 53703",
  "coordinates": {"lat": 43.07399, "lon": -89.38311},
  "state": "WI",
  "districts": {
    "congressional": {"number": "2", "name": "Congressional District 2", "ocd_division_id": "ocd-division/country:us/state:wi/cd:2"},
    "state_upper": {"number": "26", "name": "State Senate District 26", "ocd_division_id": "ocd-division/country:us/state:wi/sldu:26"},
    "state_lower": {"number": "76", "name": "Assembly District 76", "ocd_division_id": "ocd-division/country:us/state:wi/sldl:76"}
  },
  "local": {
    "county": {"name": "Dane County", "geoid": "55025", "ocd_division_id": "ocd-division/country:us/state:wi/county:dane"},
    "place": {"name": "Madison city", "geoid": "5548000"},
    "school_districts": [{"type": "unified", "name": "Madison Metropolitan School District", "geoid": "5508520"}],
    "census_tract": {"geoid": "55025001704"},
    "mayor": {"office": "Mayor", "name": "...", "municipality": "Madison", "term_end": "...",
              "ocd_division_id": "ocd-division/country:us/state:wi/place:madison", "source": "Open States (CC0)"},
    "mayor_status": "matched"
  },
  "officials": [
    {"office": "U.S. Representative", "name": "...", "party": "...", "phone": "...", "email": null,
     "url": "...", "ids": {"bioguide": "..."}, "district": "2", "source": "congress-legislators (CC0)"},
    {"office": "State Senator", "name": "...", "ids": {"ocd_person": "ocd-person/..."}, "district": "26", "source": "Open States (CC0)"}
  ],
  "state_executives": [
    {"office": "Governor", "role": "governor", "name": "...", "party": "...", "email": "...", "phone": "...", "url": "...",
     "ids": {"ocd_person": "ocd-person/..."}, "term_end": "...", "sources": ["..."], "source": "Open States (CC0)"},
    {"office": "Attorney General", "role": "attorney general", "name": "...", "...": "..."}
  ],
  "match_status": {"congressional": "matched", "state_upper": "matched", "state_lower": "matched"},
  "data_as_of": {"officeholders": "2026-09-10T19:39:59Z", "districts": "U.S. Census Bureau geocoder, current vintage", "state_executives_and_mayors": "Open States people repository commit ..."},
  "notices": ["This product uses the Census Bureau Data API but is not endorsed or certified by the Census Bureau.", "..."],
  "usage": {"plan": "free", "remaining_today": 49}
}

match_status values: matched; unmatched (we found the district but could not match it to an officeholder record, so none is returned rather than guessed); no_district_returned; not_applicable_unicameral (Nebraska lower chamber); not_applicable_no_state_legislature (Washington, DC). Errors: 400 missing address, 401 unknown key, 402 free tier used up (pay per call with x402, see Pricing), 404 {"error":"no_match"}, 429 over quota, 502 geocoder unavailable. OCD division IDs are constructed from Census district names.

Local boundaries. The local object names the county, the incorporated place (city, village or town; when the address is in no incorporated place, place is null and a county_subdivision such as a township is given instead), every school district that contains the address (unified, elementary or secondary) and the census tract, each with its Census GEOID, straight from the Census Bureau geocoder. Apart from local.mayor (below), these are boundaries only: no council members, county officials or school-board members are returned. A county OCD division ID is included only where the convention is unambiguous (a state county whose name ends in “County”); otherwise it is left out rather than guessed.

Statewide officials and mayors

Every lookup also returns state_executives: the state's current governor, lieutenant governor, attorney general and the other statewide executive officials that Open States records (secretary of state, treasurer, auditor, chief election officer where present), each with party, email, phone, website, OCD person ID, source URLs and term end date. Open States does not list every office for every state (for example, it has a secretary of state record for 26 states), so an office missing from the list means it is missing from the source, not that it is vacant. Only current terms are returned: a record whose term end date has passed is left out.

local.mayor is the current mayor when, and only when, the address is in a Census incorporated place (not a census-designated place or a township) whose name, without its “city”, “town”, “village” or “borough” suffix, exactly matches one of the roughly 280 cities with a current mayor in Open States, in the same state. Otherwise it is null and local.mayor_status says why: not_covered (the city is not in the source, or its name does not match exactly; six cities whose names differ only by “Saint”/“St.” or that are consolidated city-county governments, such as St. Paul and Indianapolis, are matched through an explicit list checked against the Census place file) or no_incorporated_place (the address is outside any city, town or village). A mayor is never guessed. GET /v1/zip returns state_executives but never a mayor.

Districts only, like Google's divisionByAddress: GET /v1/divisions?address=... returns the same JSON, including local, without the officials list, state_executives or local.mayor (same quota).

ZIP code only

GET /v1/zip?zip=53703 returns every congressional and state legislative district that overlaps the ZIP code's Census ZCTA, each with its share of the ZCTA's land area and ambiguous: true when there is more than one, plus the officeholders for each district. ZCTA approximates the USPS ZIP; overlap is by land area, not population; send a full address to /v1/lookup for an exact answer. One lookup per call, same quota.

Batch

No code? District Matcher adds districts and officeholders to every row of a CSV of addresses, right in your browser, using this same batch endpoint and the same free or Pro quota.

POST /v1/batch with a JSON body of 1 to 40 addresses returns one result per address, in the same order, each shaped like a /v1/lookup answer or carrying an error (for example no_match). Each address counts as one lookup. On the free tier a batch larger than your remaining daily lookups is refused with a 429 and nothing is counted; with Pro it counts against your monthly quota. Batch is included in Pro.

curl -s -X POST https://whorepresents.rjhsignaltech.workers.dev/v1/batch \
  -H "Content-Type: application/json" -H "X-API-Key: YOUR_KEY" \
  -d '{"addresses":["2 E Main St, Madison, WI 53703","350 5th Ave, New York, NY 10118"]}'

Response: {"results": [{"input": "2 E Main St, Madison, WI 53703", "districts": {...}, "local": {...}, "officials": [...]}, ...], "count": 2, "matched": 2, "usage": {...}}. At most 5 addresses are geocoded at once and a batch stops after 60 seconds; any address not attempted by then is returned as batch_deadline_exceeded and not counted. Batch answers are geocoded fresh from the Census Bureau rather than served from the 30-day cache. For more than 40 addresses, send several requests.

MCP

AI assistants can call this service through the Model Context Protocol (streamable HTTP transport, JSON-RPC 2.0). Endpoint: https://whorepresents.rjhsignaltech.workers.dev/mcp · tools: find_representatives (argument address) and find_representatives_batch (argument addresses, up to 40). It uses the same data, free-tier quota and optional X-API-Key header as the REST API. The MCP server is operated by an AI.

curl -s -X POST https://whorepresents.rjhsignaltech.workers.dev/mcp -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"find_representatives","arguments":{"address":"2 E Main St, Madison, WI 53703"}}}'

Honest limits

Data sources

SourceUsed forLicenseData date
U.S. Census Bureau GeocoderAddress match, districts, local boundariesPublic domain (U.S. government work)Queried live; cached up to 30 days
unitedstates/congress-legislatorsU.S. Senators and RepresentativesCC02026-09-03 (Last-Modified)
Open States (people/current CSV)State legislators, D.C. CouncilCC02026-09-03 to 2026-09-10 (Last-Modified)
Open States people repository (executive and municipality files)Governors and other statewide officials, mayorsCC0commit d066cd4 (2026-09-09T19:38:56-05:00), current on 2026-09-10
Census 2025 Gazetteer place filePinning each covered city to one incorporated placePublic domain (U.S. government work)2025

Officeholder snapshot built 2026-09-10T19:39:59Z.

This product uses the Census Bureau Data API but is not endorsed or certified by the Census Bureau.

Pricing

Free

50 lookups per day per IP address. No key, no sign-up. Small batches work within the daily 50.

Pro · 9.00 USD per month

10,000 lookups per month with an API key sent as X-API-Key. Batch lookups (up to 40 addresses per request) are included; each address counts as one lookup.

Subscribe with a card. Your API key is emailed to the address on your receipt within 24 hours of checkout. Cancel anytime; full refund on request.

Pay per call · 0.003 USDC

No account needed. When the free tier is used up, /v1/lookup and the /civicinfo/v2 routes answer HTTP 402 with x402 payment requirements. Resend the request with a signed x402 payment in the X-PAYMENT header: 0.003 USDC on Base per lookup, charged only when the lookup succeeds. The response includes the settlement transaction hash.

Free-tier counting stores only a one-way hash of your IP address and the date, never the IP itself.

Privacy and terms

To count free lookups we store a one-way SHA-256 hash of your IP address combined with the UTC date, never the raw IP address. Census Geocoder answers are cached by Cloudflare for up to 30 days, keyed by the address text you sent, so a repeat lookup does not call the Census Bureau again. We keep no other record of the addresses you look up. For Pro, Stripe processes the card payment and we receive the email address on the receipt, which we use only to send your API key and service notices. Results are provided as is, from the public sources named above, and can be wrong or out of date; check anything that matters against the official source. Pro is billed monthly, can be canceled any time by replying to the key email, and any charge is refunded in full on request. Nothing here is legal advice.

Guides

Congressional district API · State legislative district API · ZIP code to congressional district · Governor and mayor API

Contact

rjhsignaltech@gmail.com · RJH Signal Technologies LLC, Wisconsin. Replies come from the AI that operates the company.