{"openapi":"3.1.0","info":{"title":"Rallybase API","version":"2","summary":"Source-linked officials at every level, by street address, point or county.","description":"Rows show the source and the day we read or recorded them where we hold them, and state on the page when either is missing. A key is required; send it in the Authorization header on a server, never in a URL. Free keys (Open) get 500 lookups a month; paid plans are larger. Browsers are not an intended client: no CORS header is sent."},"servers":[{"url":"/"}],"paths":{"/api/v2/lookup":{"get":{"operationId":"lookupOfficials","summary":"Look up the officials for a street address, a point, or a county","description":"Returns the officials Rallybase holds for a place: federal, state, county, city, school and other local, each row with a stable `id`, an Open Civic Data division id where the published list carries one, the source page it was read from and the day it was read. A street address in the `x-geocode-address` header (URL-encoded) or coordinates in the `x-rb-lat` and `x-rb-lng` headers give every level, plus the districts that contain the point and the governing bodies with their seat counts. A 5-digit county FIPS code in the `county` query parameter gives the county officials only, because a county has no single point: its other levels say `needs a point`. Locations never go in the URL. Worked requests: \"who represents this address?\" is `GET /api/v2/lookup` with the header `x-geocode-address: 1600%20Example%20St%2C%20Austin%2C%20TX`; \"who are the county officials for FIPS 48453?\" is `GET /api/v2/lookup?county=48453`. County rows come from the snapshot named in `snapshot`; the other levels are read when the request is answered, at `point.read_at`. Office phone, email and website are served for federal and state officials, as their offices publish them; county, city and school rows carry none in this API. `coverage.levels` explains every level with no rows: `none held`, `could not check` and `held, not redistributed` are different findings, and none of them is a statement that a government has no officials. A request counts against the monthly allowance only when it returns 200 with at least one official (An authenticated request counts against the monthly quota only if it returned 200 with at least one official row. A malformed request, an auth failure, a 429, a 5xx, and an answer that is only a coverage finding do not count.) An address lookup costs 3 against the per-minute limit.","security":[{"ApiKey":[]}],"parameters":[{"name":"county","in":"query","required":false,"description":"A 5-digit county FIPS code. Use this or the address header.","schema":{"type":"string","pattern":"^\\d{5}$"},"example":"48453"},{"name":"x-geocode-address","in":"header","required":false,"description":"A street address, URL-encoded, 4 to 200 characters. Used when neither `county` nor the coordinate headers are sent. It is never stored and never belongs in the URL. Costs 3 against the per-minute limit.","schema":{"type":"string"},"example":"1600%20Example%20St%2C%20Austin%2C%20TX"},{"name":"x-rb-lat","in":"header","required":false,"description":"Latitude in decimal degrees. Send with `x-rb-lng`; used when `county` is absent. Never in the URL.","schema":{"type":"string"},"example":"30.2711"},{"name":"x-rb-lng","in":"header","required":false,"description":"Longitude in decimal degrees. Send with `x-rb-lat`.","schema":{"type":"string"},"example":"-97.7437"}],"responses":{"200":{"description":"The officials held for the place, and a coverage finding for every level. Counts against the monthly allowance only with at least one official.","headers":{"X-RateLimit-Limit":{"description":"The monthly allowance for this key.","schema":{"type":"string"}},"X-RateLimit-Remaining":{"description":"Lookups left this month.","schema":{"type":"string"}},"X-RateLimit-Reset":{"description":"Unix time the month rolls over (UTC).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLookupResponse"},"examples":{"address":{"summary":"Illustrative values: the names, ids and URLs are placeholders","value":{"license":"Data licensed under the Rallybase API Terms: use, display and analysis in your own product or research; no resale or redistribution as a dataset or competing service; attribution with source links when shown publicly.","snapshot":{"id":"snap-example","built_at":"2026-10-28T06:00:00.000Z"},"freshness":"weekly snapshot","county":{"fips":"48453","name":"Travis","state":"TX"},"officials":[{"id":"federal-rep-X000001","level":"federal","office":null,"office_label":"U.S. Representative, TX-37","name":"Alex Example","jurisdiction":"U.S. House of Representatives","ocd_id":"ocd-division/country:us/state:tx/cd:37","district_key":null,"party":"Example Party","phone":"202-555-0100","email":null,"website":"https://example.house.gov","source_url":"https://www.example.gov/members","read_at":null,"read_basis":"not held — officials.last_synced is a sync or load time, not a read date (see recorded)","recorded_on":"2026-10-27","attribution":null},{"id":"state-ocd-person/00000000-0000-0000-0000-000000000000","level":"state","office":null,"office_label":"State Senator, District 14","name":"Sam Example","jurisdiction":"TX Senate","ocd_id":"ocd-division/country:us/state:tx/sldu:14","district_key":null,"party":"Example Party","phone":"512-555-0100","email":"sam.example@example.gov","website":"https://www.example.gov/senate/14","source_url":"https://www.example.gov/senate","read_at":null,"read_basis":"not held — officials.last_synced is a sync or load time, not a read date (see recorded)","recorded_on":"2026-10-27","attribution":null},{"id":"county-official-48453-county_judge","level":"county","office":"county_judge","office_label":"County Judge","name":"Jane Example","jurisdiction":"Travis County, TX","ocd_id":"ocd-division/country:us/state:tx/county:travis","district_key":null,"party":null,"phone":null,"email":null,"website":null,"source_url":"https://www.example.gov/county-judge","read_at":"2026-10-20","read_basis":"rb.county_official.fetched_at","recorded_on":null,"attribution":null},{"id":"place-official-4805000-mayor-citywide-pat-example","level":"place","office":null,"office_label":"Mayor","name":"Pat Example","jurisdiction":"Austin City Council","ocd_id":null,"district_key":"place_geoid:4805000","party":null,"phone":null,"email":null,"website":null,"source_url":"https://www.example.gov/council","read_at":"2026-10-21","read_basis":"last_verified_on: a person re-read the city page","recorded_on":null,"attribution":null}],"point":{"read_at":"2026-10-28T14:03:11.000Z","districts":[{"name":"Congressional District 37","level":"federal","state":"TX","census_geoid":"4837"},{"name":"State Senate District 14","level":"state","state":"TX","census_geoid":"48014"}],"bodies":[{"body_name":"Commissioners Court","body_kind":"county_commission","seats":5,"composition":"A county judge elected countywide and four commissioners elected by precinct.","election_method":"mixed","citation":"Tex. Const. art. V, § 18","source_url":"https://www.example.gov/constitution","verified_on":"2026-09-01","applies_as":"state_default"}],"place_rosters":[{"place_geoid":"4805000","place_name":"Austin","state":"TX","status":"rostered","count":11,"reason":null,"checked_at":"2026-09-17"}]},"coverage":{"county":"held","levels":{"federal":"served","state":"served","place":"served","school":"none held","local":"none held"},"held_not_redistributed":0,"note":"No row held for this lookup was withheld by the licence filter or the row text rules."}}}}}}},"400":{"description":"`key_in_query`: A key appears in the query string or the path. `address_in_query`: An `address` query parameter was sent. `coordinates_in_query`: A `lat` or `lng` query parameter was sent. `bad_county`: `county` is not exactly five digits. `bad_coordinates`: Only one coordinate header was sent, or either is blank, not a number, or out of range. `bad_address`: The address header cannot be decoded or is not 4 to 200 characters. `missing_query`: None of `county`, the address header or the coordinate headers was sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_in_query":{"value":{"error":"key_in_query","message":"Send the key in the Authorization header as \"Bearer <key>\", never in the URL: URLs are written to access logs."}},"address_in_query":{"value":{"error":"address_in_query","message":"Send the address in the x-geocode-address header (URL-encoded), never in the URL: a URL is cached and logged, and an address should be neither."}},"coordinates_in_query":{"value":{"error":"coordinates_in_query","message":"Send coordinates in the x-rb-lat and x-rb-lng headers, never in the URL: a URL is cached and logged, and a precise location should be neither."}},"bad_county":{"value":{"error":"bad_county","message":"county must be a 5-digit FIPS code, e.g. 48453."}},"bad_coordinates":{"value":{"error":"bad_coordinates","message":"x-rb-lat and x-rb-lng must both be valid coordinates, e.g. 30.2711 and -97.7437."}},"bad_address":{"value":{"error":"bad_address","message":"The address in x-geocode-address must be 4 to 200 characters."}},"missing_query":{"value":{"error":"missing_query","message":"Send county=<5-digit FIPS>, an address in the x-geocode-address header, or coordinates in the x-rb-lat and x-rb-lng headers."}}}}}},"401":{"description":"`invalid_key`: The key is missing, malformed, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_key":{"value":{"error":"invalid_key","message":"A valid API key is required: Authorization: Bearer <key>."}}}}},"headers":{"WWW-Authenticate":{"description":"Sent with `invalid_key`.","schema":{"type":"string"}}}},"404":{"description":"`address_not_found`: The address could not be matched. The lookup is not counted. `point_not_found`: The coordinates are not inside a US county we hold. The lookup is not counted. `not_found`: The API is switched off, or the route under /api/v2 does not exist. Router-level closure returns the same body as an unknown resource.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/RouterNotFound"}]},"examples":{"address_not_found":{"value":{"error":"address_not_found","message":"No match for that address. This lookup was not counted."}},"point_not_found":{"value":{"error":"point_not_found","message":"That point is not inside a US county we hold. This lookup was not counted."}},"not_found":{"value":{"error":"not_found","message":"Not found."}},"router_closed":{"value":{"error":"Not found"}}}}}},"405":{"description":"`method_not_allowed`: Any method other than GET.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"method_not_allowed":{"value":{"error":"method_not_allowed","message":"Use GET."}}}}},"headers":{"Allow":{"description":"Sent with `method_not_allowed`.","schema":{"type":"string"}}}},"429":{"description":"`rate_limited`: A rate or quota limit was reached. `limit` says which: `per_minute`, `per_day`, `stacked_daily`, `free_ip_daily`, `free_asn_daily`, `free_budget`, `geocoder_budget` or `monthly`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"value":{"error":"rate_limited","limit":"per_minute","message":"More than 10 lookups in a minute for this key (an address lookup counts as 3)."}}}}},"headers":{"Retry-After":{"description":"Sent with `rate_limited`.","schema":{"type":"string"}}}},"502":{"description":"`geocoder_unavailable`: The address could not be resolved just now. The lookup is not counted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"geocoder_unavailable":{"value":{"error":"geocoder_unavailable","message":"The address could not be resolved just now. This lookup was not counted."}}}}}},"503":{"description":"`unavailable`: The API failed internally. Nothing was counted past the failing step. `snapshot_unavailable`: No snapshot has been built yet. The lookup is not counted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"value":{"error":"unavailable","message":"The API could not answer just now. This lookup was not counted."}},"snapshot_unavailable":{"value":{"error":"snapshot_unavailable","message":"No snapshot has been built yet. This lookup was not counted."}}}}},"headers":{"Retry-After":{"description":"Sent with `unavailable` and `snapshot_unavailable`.","schema":{"type":"string"}}}}}}}},"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","bearerFormat":"rb_live_<43 characters>","description":"Authorization: Bearer rb_live_<43 characters>"}},"schemas":{"ApiOfficial":{"type":"object","additionalProperties":false,"required":["id","level","office","office_label","name","jurisdiction","ocd_id","district_key","party","phone","email","website","source_url","read_at","read_basis","recorded_on","attribution"],"properties":{"id":{"type":"string","description":"A stable id, the same one the site and the free at-point answer use, e.g. `federal-rep-D000399` or `county-official-48453-county_judge`."},"level":{"type":"string","enum":["federal","state","county","place","school","local"],"description":"`place` is a city or town; `local` is any other local government."},"office":{"type":["string","null"],"description":"The county roster's office key, e.g. `county_judge`, on a county row; null on the other levels."},"office_label":{"type":"string","description":"The office as served, with the holder's name taken out."},"name":{"type":"string","description":"The holder's name as served."},"jurisdiction":{"type":"string","description":"The government the row serves, e.g. `Travis County, TX` or `U.S. Senate`."},"ocd_id":{"type":["string","null"],"description":"An Open Civic Data division id from the published list, or null when the list does not carry this row's division."},"district_key":{"type":["string","null"],"description":"Our handle for a division OCD does not type, e.g. `place_geoid:4805000`, or null."},"party":{"type":["string","null"],"description":"The party as the source gives it, or null. County rosters publish none."},"phone":{"type":["string","null"],"description":"The office phone as the office publishes it. Federal and state rows only; null elsewhere."},"email":{"type":["string","null"],"description":"The office email as the office publishes it. Federal and state rows only; null elsewhere."},"website":{"type":["string","null"],"description":"The office website. Federal and state rows only; null elsewhere."},"source_url":{"type":"string","description":"The public page this row was read from. Cite it.","format":"uri"},"read_at":{"type":["string","null"],"description":"The day the source was read (`YYYY-MM-DD`, or `YYYY-MM` where the source gave a month), or null where we hold only a sync time.","pattern":"^\\d{4}-\\d{2}(-\\d{2})?$"},"read_basis":{"type":"string","description":"What `read_at` is, or why it is null."},"recorded_on":{"type":["string","null"],"description":"When our roster last recorded the row (`YYYY-MM-DD`), or null.","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"attribution":{"type":["string","null"],"description":"A credit the source requires you to show, or null when none is owed."},"term_end":{"type":"string","description":"The day this term gives way to `successor` (`YYYY-MM-DD`). Present only with `successor`.","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"successor":{"type":"object","additionalProperties":false,"required":["name","status","takes_office","source_url","read_at"],"description":"Who was elected to this seat and has not taken it yet. Absent when none is held or its source cannot be redistributed.","properties":{"name":{"type":"string","description":"The winner's name as the result prints it."},"status":{"type":"string","enum":["UNOFFICIAL","CERTIFIED"]},"takes_office":{"type":"string","description":"The day the term starts (`YYYY-MM-DD`).","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"source_url":{"type":"string","description":"The public page the result was read from.","format":"uri"},"read_at":{"type":"string","description":"The day the result was read (`YYYY-MM-DD`).","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}}}},"ApiLookupResponse":{"type":"object","additionalProperties":false,"required":["license","snapshot","freshness","county","officials","point","coverage"],"properties":{"license":{"type":"string","description":"The licence sentence that applies to this data."},"snapshot":{"type":"object","additionalProperties":false,"required":["id","built_at"],"properties":{"id":{"type":"string"},"built_at":{"type":"string","description":"When the snapshot was built.","format":"date-time"}}},"freshness":{"type":"string","enum":["weekly snapshot","daily-confirmed"],"description":"Open keys read the weekly snapshot; paid keys read the nightly one."},"county":{"type":["object","null"],"additionalProperties":false,"required":["fips","name","state"],"properties":{"fips":{"type":"string"},"name":{"type":"string"},"state":{"type":"string"}},"description":"null when the county is not in the snapshot."},"officials":{"type":"array","items":{"$ref":"#/components/schemas/ApiOfficial"},"description":"Every level, federal first."},"point":{"type":["object","null"],"additionalProperties":false,"required":["read_at","districts","bodies","place_rosters"],"description":"What the address or coordinates resolved to; null for a county lookup.","properties":{"read_at":{"type":"string","description":"When the non-county levels were read.","format":"date-time"},"districts":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["name","level","state","census_geoid"],"properties":{"name":{"type":"string"},"level":{"type":"string"},"state":{"type":"string"},"census_geoid":{"type":"string"}}}},"bodies":{"type":"array","description":"Governing bodies with seat counts read from their charter or statute, not counted from the roster.","items":{"type":"object","additionalProperties":false,"required":["body_name","body_kind","seats","composition","election_method","citation","source_url","verified_on","applies_as"],"properties":{"body_name":{"type":"string"},"body_kind":{"type":"string"},"seats":{"type":"integer"},"composition":{"type":"string"},"election_method":{"type":["string","null"],"description":"`by_district`, `at_large`, `hybrid_at_large` or `mixed`; null when not recorded."},"citation":{"type":["string","null"]},"source_url":{"type":["string","null"]},"verified_on":{"type":["string","null"]},"applies_as":{"type":"string","enum":["this_body","state_default"],"description":"`state_default` is the state's general-law composition, not read for this jurisdiction."}}}},"place_rosters":{"type":"array","description":"For each city containing the point, whether we hold its roster.","items":{"type":"object","additionalProperties":false,"required":["place_geoid","place_name","state","status","count","reason","checked_at"],"properties":{"place_geoid":{"type":"string"},"place_name":{"type":"string"},"state":{"type":"string"},"status":{"type":"string","enum":["rostered","unsupported","not_yet"]},"count":{"type":"integer","minimum":0},"reason":{"type":["string","null"]},"checked_at":{"type":["string","null"]}}}}}},"coverage":{"type":"object","additionalProperties":false,"required":["county","levels","held_not_redistributed","note"],"description":"Why the list is what it is. `county` is the snapshot's finding for the county; `levels` gives one finding for each other level. None of them is a statement that a government has no officials.","properties":{"county":{"type":"string","enum":["none held","not yet read","not in this API yet","held"]},"levels":{"type":"object","additionalProperties":false,"required":["federal","state","place","school","local"],"properties":{"federal":{"type":"string","enum":["served","held, not redistributed","none held","could not check","needs a point"]},"state":{"type":"string","enum":["served","held, not redistributed","none held","could not check","needs a point"]},"place":{"type":"string","enum":["served","held, not redistributed","none held","could not check","needs a point"]},"school":{"type":"string","enum":["served","held, not redistributed","none held","could not check","needs a point"]},"local":{"type":"string","enum":["served","held, not redistributed","none held","could not check","needs a point"]}}},"held_not_redistributed":{"type":"integer","minimum":0,"description":"Rows held but withheld: their source host is not cleared for redistribution, or their text broke the API row rules."},"note":{"type":"string"}}}}},"Error":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string","description":"A stable machine-readable code."},"message":{"type":"string"},"limit":{"type":"string","enum":["per_minute","per_day","stacked_daily","free_ip_daily","free_asn_daily","free_budget","geocoder_budget","monthly"],"description":"Present on 429 only: which limit was reached."}}},"RouterNotFound":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","enum":["Not found"]}},"description":"The router-level closed-route answer, identical to an unknown resource."}}}}