12

I'm looking to determine the congressional district based on an address my user is providing. This will avoid having the user to look it up themselves.

Does an API of this sort exist?

Note

Through my attempts to find one, I've only come across these:

  • http://www.govtrack.us/developers/api
    (not sure how to submit an an address or zip code however)

    The following resources are available in the API

    ...Bills and resolutions in the U.S. Congress since 1973 (the 93rd Congress).

    ...A (bill, person) pair indicating cosponsorship, with join and withdrawn dates.

    ...Members of Congress and U.S. Presidents since the founding of the nation.

    ...Terms held in office by Members of Congress and U.S. Presidents. Each term corresponds with an election, meaning each term in the House covers two years (one 'Congress'), as President four years, and in the Senate six years (three 'Congresses').

    ...Roll call votes in the U.S. Congress since 1789. How people voted is accessed through the Vote_voter API.

    ...How people voted on roll call votes in the U.S. Congress since 1789. See the Vote API. Filter on the vote field to get the results of a particular vote...

  • http://www.opencongress.org/api
    (seems to be a way to find congress information, but not districts)

    This API provides programmers with structured access to all the data on OpenCongress, everything from official bill info to news and blog coverage to user-generated votes on bills and much more...

    This API defaults to returning XML. All queries can also return JSON...

  • https://groups.google.com/forum/?fromgroups=#!topic/opendems-discuss/CeKyi_aANaE
    (similar question, no resolution)

    I've been looking over Open Dems, and seeing what's exposed at this point and what isn't. I work with Democrats Abroad, and am interested in using stuff from the lab for their sites.

    I quickly looked over the Precinct API, which does both more and less than what I'd need. An ideal resource would be any way of translating addresses into CD at the very least (getting state district data would be good as well), since that would make it easier for DA's membership to make a difference in races like last month's NY26 race...

Update

I'm looking at the source for the govtrack.us website and the 'doGeoCode' function may be useful.

view-source:http://www.govtrack.us/congress/members

If no one has any suggestions, I will try to go off of what they are doing.

  • 1
    I have updated my question with some places I have been looking at. – ardavis Nov 9 '12 at 14:31
  • It might make sense to move this to StackOverflow, or reask it there, and link it here, since this is a valid, important, and useful question. – Chris Moschini Nov 20 '18 at 13:38
7

I haven't used it, but a quick search brought me to Congress API from Sunlight Labs. Check out their districts.getDistrictsFromZip method -- it seems to be what you're looking for. You might get better (more accurate) results geocoding the address yourself and then using districts.getDistrictFromLatLong -- I'd assume that a given zip code could cross district boundaries.

| improve this answer | |
  • 1
    Thank you @Caleb. I didn't come across that when I was searching, that seems to be exactly what I am looking for. I appreciate it. – ardavis Nov 9 '12 at 17:05
  • Update: Sunlight API key page doesn't work anymore. – Seth Connell Sep 3 '17 at 17:02
5

Google Civics API is the best solution. A single API hit gets you both Elected Officials and Districts.

You can get Districts by GPS coords (lat/lng) like so:

public async Task<GoogleCivicsResult> FetchAndParseUSDistrictAsync(
    decimal lat, decimal lng, string address = null)
{
    string googleApiKey = App.GoogleApiKey;
    string reqAddr = Uri.EscapeDataString(address ?? lat + "," + lng);
    string url = "https://www.googleapis.com/civicinfo/v2/representatives?alt=json&key={0}&address={1}";
    url = String.Format(url, googleApiKey, reqAddr);

    var req = new HttpWebRequestAsync(url);
    var data = await req.GetStringAsync();

    var result = JsonConvert.DeserializeObject<GoogleCivicsResult>(data);

    return result;
}

public class GoogleCivicsResult
{
    public Address normalizedInput { get; set; }

    public Dictionary<string, Division> divisions { get; set; }

    public Office[] offices { get; set; }

    public Official[] officials { get; set; }
}

public class Address
{
    public string line1 { get; set; }
    public string line2 { get; set; }
    public string city { get; set; }
    public string state { get; set; }
    public string zip { get; set; }
}

public class Division
{
    public string name { get; set; }

    public int[] officeIndices { get; set; }

    public Office[] offices { get; set; }
}

public class Office
{
    // President of the United States
    // United States Senate
    // United States House of Representatives FL-06
    // Governor
    // Lieutenant Governor
    // Attorney General
    // Sheriff
    // County Judge
    // Council Chair
    public string name { get; set; }

    // ocd-division/country:us/state:fl/cd:6
    // ocd-division/country:us/state:fl
    // ocd-division/country:us/state:fl/county:volusia
    public string divisionId { get; set; }

    // administrativeArea1
    public string[] levels { get; set; }

    // legislatorUpperBody
    // legislatorLowerBody
    // headOfGovernment
    // deputyHeadOfGovernment
    public string[] roles { get; set; }

    public int[] officialIndices { get; set; }
}

public class Official
{
    public string name { get; set; }
    public Address[] address { get; set; }
    public string party { get; set; }
    public string[] phones { get; set; }
    public string[] urls { get; set; }
    public string photoUrl { get; set; }
    public Social[] channels { get; set; }
    public string[] emails { get; set; }
}

public class Social
{
    public string type { get; set; }
    public string id { get; set; }
}

https://developers.google.com/civic-information/docs/v2/representatives/representativeInfoByAddress

You can get similar for state-level info using OpenStates:

"http://openstates.org/api/v1/legislators/geo/?apikey={0}&lat={1}&long={2}";

Addenda about Google Civics API Going Down Frequently

The Google Civics API is vague on whether it supports lat/lng, and every few months or so, it will just stop supporting lat/lng for a month or so, until someone reports it and Google notices, or more specifically, the one employee there probably working on this in their volunteer time notices ("Chelan") and looks into fixing it:

https://groups.google.com/d/msg/google-civicinfo-api/0td48h7JxYA/Zhij3yQiCgAJ

If your service expects Civics API data it's going to crash, and if it requires Civics API data to be useful, it may not crash but it will be useless for months at a time. The most recent failure was the entire voting period for most states in 2018, so, that's quite the downtime.

You can play defense by explicitly reverse geocoding:

if (!(navigator && navigator.geolocation))
    return geoFail();

navigator.geolocation.getCurrentPosition(function (position) {
    var coords = position.coords;
    var lat = coords.latitude;
    var lng = coords.longitude;

    if (!lat || !lng)
        return geoFail();

    var geocoder = new google.maps.Geocoder;
    geocoder.geocode({ 'location': { lat: lat, lng: lng } },
            function (r, status) {
        if (status !== 'OK' || !r || !r.length) {
            loadReps(lat, lng);
            return;
        }

        var address = r[0].formatted_address;
        $('#address').val(address);
        loadReps(lat, lng, address);
    });
}, geoFail);

So here, we go through the usual HTML5 ask for user's location, and if they say No/Block we show them the "Couldn't get your location" message (with geoFail). Then we've got the lat/lng, but, Google Civics API is erratic so we'll go ask Google explicitly for the address. That comes back as r[0].formatted_address, which in some answers Google recommends you show to the user to confirm the location they're looking up. So we put that in the address textbox and send it off via loadReps(lat, lng, address).

Note that it's possible the geocode call could fail (including because of a flaky internet connection), but, sometimes Google Civics API is fully operational, so, no need to deny the user a result yet in this scenario; the backend I wrote in this case can accept lat/lng and optional address, and tolerate the address missing. Then it tries to talk to Google Civics API, and, if it gets nothing, it needs to survive that and tell the user the Civics API is broken, sorry.

Historical Answer

The Congress API from Sunlight Foundation* is Federal-only - no state-level, if that matters to you. And [Sunlight Foundation is shutting down, because they don't want to be duplicating the efforts of GovTrack.

GovTrack's API* is more complete. Their /role is closest to your question:

https://www.govtrack.us/developers/api#endpoint_role

It tells you all the current Senators and House members, and when their next election is. So you'd have a filtering burden.

For state-level stuff you want OpenStates.org, like:

http://openstates.org/api/v1/legislators/geo/?apikey={0}&lat={1}&long={2}

https://openstates.org/

*Bad news, everything is shutting down all of the time. Sunlight Foundation shutdown their API to avoid duplicating Govtrack's work. Govtrack is shutting down theirs now, to avoid duplicating ProPublica's work. But Propublica's doesn't seem to give you district from location at all:

https://projects.propublica.org/api-docs/congress-api/

So wait you might say, that makes no sense, because ProPublica's Represent site, which is transferred from NYTimes' shutdown Represent project, does let you map an address and get the district from the GPS coords. And they link to their API from that page. Well fooled you, cuz that page does not use their API. In fact, it uses the Sunlight Foundation's district finding API.

What a mess.

| improve this answer | |
3

I realize this question is old, but I figured I'd throw in my two cents for anyone who might still be looking.

First, some background info. Congressional districts are extremely specific - down to an address itself, not just the street. Me and my neighbor across the street could be in different congressional districts. This is why it's so important to get a good ZIP+4 code to ensure that you're placing the address in the correct district. A system (like SmartyStreets or Melissa Data or QAS, etc.) that does address validation would give you a reliable ZIP+4 to ensure that the district is correct.

SmartyStreets has their LiveAddress API, which returns congressional data along with over 40 other data points (geocodes, residential vs commercial, etc.).

| improve this answer | |
  • Given IL-04 I'm not even sure that the ZIP+4 would get the proper district. (geojson in a gist at gist.github.com/anonymous/f2e46f17275f6dbb68db copied from github.com/benbalter/congressional-districts/blob/gh-pages/IL/… because that's not rendering at the moment). – user40980 Apr 25 '14 at 20:32
  • ... though, it says that zip+4 should get you to a building and includes information like what side of the street you are on. So maybe, but then consider that the set of zip+4 that maps to a district would be the number of buildings in that district which could get unwieldy. – user40980 Apr 25 '14 at 23:18
0

Melissa Data makes tools for address verification that includes information on political districts. I do not know if they have a public api; the link above will take you to an address look up page. They offer a limited number of free look ups that can be increased with a subscription. Please check their terms of use before putting this into a production application.

While their data is updated monthly, I have noticed that some of it does not reflect recent redistricting.

Many states have this information available, but I doubt that there is any consistency in their implementation.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.