Использование API

В этом документе описывается, что вам нужно знать, чтобы использовать API Google Civic Information. Вы можете просмотреть этот раздел часто задаваемых вопросов по Civic Info API , в котором содержится основная информация об API, а также часто задаваемые вопросы на нашем форуме пользователей. Кроме того, ниже вы можете увидеть примеры поиска информации об избирателях во время выборов.

Идентификация вашего приложения в Google

Ваше приложение должно идентифицировать себя каждый раз, когда оно отправляет запрос к API Google Civic Information, включая ключ API в каждый запрос.

Получение и использование ключа API

Чтобы получить ключ API:

  1. Откройте страницу «Учетные данные» в консоли API.
  2. Этот API поддерживает два типа учетных данных. Создайте учетные данные, подходящие для вашего проекта:
    • OAuth 2.0: всякий раз, когда ваше приложение запрашивает личные данные пользователя, оно должно отправить токен OAuth 2.0 вместе с запросом. Ваше приложение сначала отправляет идентификатор клиента и, возможно, секрет клиента для получения токена. Вы можете создать учетные данные OAuth 2.0 для веб-приложений, учетных записей служб или установленных приложений.

      Примечание. Поскольку в этом API нет методов, требующих авторизации OAuth 2.0, вам может потребоваться только получить ключи API , которые описаны ниже. Однако если ваше приложение вызывает другие API, требующие авторизации пользователя, вам все равно понадобятся учетные данные OAuth 2.0.

      Дополнительную информацию см. в документации OAuth 2.0 .

    • Ключи API. Запрос, который не предоставляет токен OAuth 2.0, должен отправить ключ API. Ключ идентифицирует ваш проект и обеспечивает доступ к API, квоту и отчеты.

      API поддерживает несколько типов ограничений для ключей API. Если нужный вам ключ API еще не существует, создайте ключ API в консоли, нажав Создать учетные данные > Ключ API . Вы можете ограничить ключ перед его использованием в рабочей среде, нажав «Ограничить ключ» и выбрав одно из « Ограничений» .

Чтобы обеспечить безопасность ключей API, следуйте рекомендациям по безопасному использованию ключей API .

Получив ключ API, ваше приложение может добавить параметр запроса key= yourAPIKey ко всем URL-адресам запроса.

Ключ API можно безопасно встраивать в URL-адреса; ему не нужна никакая кодировка.

Ограничения ключей API

По умолчанию ваш ключ API не имеет ограничений, что небезопасно, если кто-либо может либо прочитать этот ключ (например, если он размещен в браузере), либо получить доступ к устройству, на котором размещен ключ. Мы рекомендуем вам установить ограничение на этот ключ API, чтобы предотвратить несанкционированное использование.

Чтобы добавить ограничение, нажмите «Ограничить ключ» в диалоговом окне создания ключа API . Появится панель настройки API-ключа :

Тип ограничения, который вы выберете, будет зависеть от потребностей вашего приложения:

  • Веб-приложения, взаимодействующие напрямую с API (то есть не через какой-либо серверный или промежуточный уровень), должны добавить ограничение HTTP-рефереров . Однако обратите внимание, что такие приложения будут публично раскрывать свой ключ API; вместо этого предпочитайте использовать схему аутентификации учетной записи службы.
  • Серверные приложения, которые иначе не могут поддерживать учетные записи служб (например, встроенные устройства, у которых нет поддерживаемого языка в клиентской библиотеке), должны добавить ограничение IP-адресов , чтобы защититься от использования клиентами с разными IP-адресами.
  • Приложения Android должны добавить ограничение для приложений Android , а также имя вашего пакета и отпечаток сертификата подписи SHA-1.
  • Приложения iOS должны добавить ограничение приложений iOS и любые идентификаторы пакетов iOS, чтобы ограничить вызовы API к этим пакетам iOS.

Для тестирования вы можете вообще не устанавливать никаких ограничений. Однако рекомендуется либо добавить ограничение к этому ключу, либо удалить его после развертывания приложения в рабочей среде.

Пример запроса выборов

Вот пример (с использованием API версии «v2») вызова API choiceQuery для получения списка действительных идентификаторов выборов, а затем использования API VoterInfoQuery с зарегистрированным адресом избирателя для получения информации о выбранных выборах.

Используйте выборку, чтобы получить список действительных идентификаторов выборов:

  https://www.googleapis.com/civicinfo/v2/elections?key=<YOUR_API_KEY>
  

Ответ на запрос выборов:

{
 "kind": "civicinfo#electionsqueryresponse",
 "elections": [
  {
   "id": "2000",
   "name": "VIP Test Election",
   "electionDay": "2013-06-06"
  },
  {
   "id": "2124",
   "name": "Rhode Island 2012 Primary Election",
   "electionDay": "2012-09-11"
  },
  {
   "id": "2126",
   "name": "Delaware 2012 Primary Election",
   "electionDay": "2012-09-11"
  }
 ]
}

VoterInfoQuery с использованием Curl

Используйте curl , чтобы отправить запрос voiceInfoQuery для VIP-идентификатора тестовых выборов 2000 и избирателя по (тестовому) адресу 340 Main St, Venice, CA 90291. Вы можете обратиться к ответу VoterInfoQuery .

curl "https://www.googleapis.com/civicinfo/v2/voterinfo?key=<YOUR_API_KEY>&address=340%20Main%20St.%20Venice%20CA&electionId=2000"

VoterInfoQuery с использованием клиентской библиотеки Google API для JavaScript

В этом примере выдается тот же VoterInfoQuery, что и в предыдущем примере Curl, но он использует клиентскую библиотеку JavaScript . Ответ voicerInfoQuery такой же, как и ответ примера Curl.

<!doctype html>
<html>
  <head>
    <script>
      /**
       * Build and execute request to look up voter info for provided address.
       * @param {string} address Address for which to fetch voter info.
       * @param {function(Object)} callback Function which takes the
       *     response object as a parameter.
       */
       function lookup(address, callback) {
       /**
         * Election ID for which to fetch voter info.
         * @type {number}
         */
        var electionId = 2000;
 
        /**
         * Request object for given parameters.
         * @type {gapi.client.HttpRequest}
         */
        var req = gapi.client.request({
            'path' : '/civicinfo/v2/voterinfo',
            'params' : {'electionId' : electionId, 'address' : address}
        });
       req.execute(callback);
      }

      /**
       * Render results in the DOM.
       * @param {Object} response Response object returned by the API.
       * @param {Object} rawResponse Raw response from the API.
       */
      function renderResults(response, rawResponse) {
        var el = document.getElementById('results');
        if (!response || response.error) {
          el.appendChild(document.createTextNode(
              'Error while trying to fetch polling place'));
          return;
        }
        var normalizedAddress = response.normalizedInput.line1 + ' ' +
            response.normalizedInput.city + ', ' +
            response.normalizedInput.state + ' ' +
            response.normalizedInput.zip;
        if (response.pollingLocations.length > 0) {
          var pollingLocation = response.pollingLocations[0].address;
          var pollingAddress = pollingLocation.locationName + ', ' +
              pollingLocation.line1 + ' ' +
              pollingLocation.city + ', ' +
              pollingLocation.state + ' ' +
              pollingLocation.zip;
          var normEl = document.createElement('strong');
          normEl.appendChild(document.createTextNode(
              'Polling place for ' + normalizedAddress + ': '));
          el.appendChild(normEl);
          el.appendChild(document.createTextNode(pollingAddress));
        } else {
          el.appendChild(document.createTextNode(
              'Could not find polling place for ' + normalizedAddress));
        }
      }

      /**
       * Initialize the API client and make a request.
       */
      function load() {
        gapi.client.setApiKey('YOUR API KEY GOES HERE');
        lookup('1263 Pacific Ave. Kansas City KS', renderResults);
      }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=load"></script>
  </head>
  <body>
    <div id="results"></div>
  </body>
</html>

Ответ voicerInfoQuery

{
  "kind": "civicinfo#voterinforesponse",
  "status": "success",
  "election": {
  "id": "2000",
  "name": "VIP Test Election",
  "electionDay": "2025-06-06",
  "ocdDivisionId": "ocd-division/country:us"
  },
  "normalizedInput": {
    "line1": "340 Main Street",
    "city": "Venice",
    "state": "CA",
    "zip": "90291"
  },
  "pollingLocations": [
    {
      "address": {
        "locationName": "WESTMINSTER AVENUE ELEMENTARY SCHOOL",
        "line1": "1010 ABBOT KINNEY BLVD",
        "city": "VENICE",
        "state": "CA",
        "zip": "90291"
      },
      "pollingHours": "",
      "latitude": 33.9919351,
      "longitude": -118.4722031,
      "startDate": "2024-03-05",
      "endDate": "2024-03-05",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "address": {
        "locationName": "POP UP VOTE CENTER 5",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    }
  ],
  "dropOffLocations": [
    {
      "address": {
        "locationName": "FLEX VOTE CENTER 9",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
  ],
  "contests": [
    {
      "type": "General",
      "ballotTitle": "UNITED STATES REPRESENTATIVE, 36th District",
      "district": {
        "name": "36TH US CONGRESSIONAL",
        "scope": "congressional"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "103",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "ARIANA HAKAMI",
          "party": "Party Preference: Republican"
        },
        {
          "name": "CLAIRE RAGGE ANDERSON",
          "party": "Party Preference: None"
        },
        {
          "name": "MELISSA TOOMIM",
          "party": "Party Preference: Republican"
        },
        {
          "name": "TED W. LIEU",
          "party": "Party Preference: Democratic"
        }
      ]
    },
    {
      "type": "ballot-measure",
      "ballotTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "district": {
        "name": "CITY OF LOS ANGELES",
        "scope": "citywide"
      },
      "ballotPlacement": "116",
      "referendumTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "referendumText": "CITY MOBILITY PLAN STREET IMPROVEMENT MEASURES. INITIATIVE ORDINANCE HLA. Shall an ordinance providing that when the City of Los Angeles makes a qualifying improvement to a City-owned street (e.g., a paving project), the City must also install certain street enhancements described in the City's Mobility Plan network of pedestrian, bicycle, transit, and vehicle routes; and requiring the City to provide publicly accessible information regarding street improvements; be adopted?",
      "referendumPassageThreshold": "MAJORITY OF VOTES CAST",
      "referendumBallotResponses": [
        "YES",
        "NO"
      ],
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "type": "General",
      "ballotTitle": "DISTRICT ATTORNEY",
      "district": {
        "name": "LOS ANGELES COUNTY",
        "scope": "countywide"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "129",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "GEORGE GASCÓN"
        },
        {
          "name": "JONATHAN HATAMI"
        },
        {
          "name": "NATHAN HOCHMAN"
        },
        {
          "name": "DEBRA ARCHULETA"
        },
        {
          "name": "JEFF CHEMERINSKY"
        },
        {
          "name": "ERIC SIDDALL"
        },
        {
          "name": "MARIA RAMIREZ"
        },
        {
          "name": "DAN KAPELOVITZ"
        },
        {
          "name": "LLOYD \"BOBCAT\" MASSON"
        },
        {
          "name": "JOHN MCKINNEY"
        },
        {
          "name": "CRAIG J. MITCHELL"
        },
        {
          "name": "DAVID S. MILTON"
        }
      ]
    }
  ],
  "state": [
    {
      "name": "California",
      "electionAdministrationBody": {
        "name": "Secretary of State",
        "electionInfoUrl": "https://www.sos.ca.gov/elections/",
        "electionRegistrationUrl": "https://registertovote.ca.gov/?t=s",
        "electionRegistrationConfirmationUrl": "https://voterstatus.sos.ca.gov",
        "absenteeVotingInfoUrl": "https://elections.cdn.sos.ca.gov/vote-by-mail/replacement-application.pdf",
        "votingLocationFinderUrl": "https://voterstatus.sos.ca.gov",
        "ballotInfoUrl": "https://www.sos.ca.gov/elections/ballot-status/wheres-my-ballot/",
        "correspondenceAddress": {
          "line1": "1500 11th Street, 5th Floor",
          "city": "Sacramento",
          "state": "California",
          "zip": "95814"
        }
      },
      "local_jurisdiction": {
        "name": "Los Angeles",
        "electionAdministrationBody": {
          "name": "Registrar-Recorder/County Clerk",
          "electionInfoUrl": "http://www.lavote.gov/",
          "electionRegistrationUrl": "http://registertovote.ca.gov/",
          "electionRegistrationConfirmationUrl": "https://lavote.gov/vrstatus/",
          "absenteeVotingInfoUrl": "",
          "ballotInfoUrl": "http://www.lavote.gov/Locator",
          "physicalAddress": {
            "locationName": "Registrar-Recorder/County Clerk",
            "line1": "12400 Imperial Highway",
            "city": "Norwalk",
            "state": "CA",
            "zip": "90650"
          }
        },
        "sources": [
          {
            "name": "Voting Information Project",
            "official": true
          }
        ]
      }
    }
  ]
}
,

В этом документе описывается, что вам нужно знать, чтобы использовать API Google Civic Information. Вы можете просмотреть этот раздел часто задаваемых вопросов по Civic Info API , в котором содержится основная информация об API, а также часто задаваемые вопросы на нашем форуме пользователей. Кроме того, ниже вы можете увидеть примеры поиска информации об избирателях во время выборов.

Идентификация вашего приложения в Google

Ваше приложение должно идентифицировать себя каждый раз, когда оно отправляет запрос к API Google Civic Information, включая ключ API в каждый запрос.

Получение и использование ключа API

Чтобы получить ключ API:

  1. Откройте страницу «Учетные данные» в консоли API.
  2. Этот API поддерживает два типа учетных данных. Создайте учетные данные, подходящие для вашего проекта:
    • OAuth 2.0: всякий раз, когда ваше приложение запрашивает личные данные пользователя, оно должно отправить токен OAuth 2.0 вместе с запросом. Ваше приложение сначала отправляет идентификатор клиента и, возможно, секрет клиента для получения токена. Вы можете создать учетные данные OAuth 2.0 для веб-приложений, учетных записей служб или установленных приложений.

      Примечание. Поскольку в этом API нет методов, требующих авторизации OAuth 2.0, вам может потребоваться только получить ключи API , которые описаны ниже. Однако если ваше приложение вызывает другие API, требующие авторизации пользователя, вам все равно понадобятся учетные данные OAuth 2.0.

      Дополнительную информацию см. в документации OAuth 2.0 .

    • Ключи API. Запрос, который не предоставляет токен OAuth 2.0, должен отправить ключ API. Ключ идентифицирует ваш проект и обеспечивает доступ к API, квоту и отчеты.

      API поддерживает несколько типов ограничений для ключей API. Если нужный вам ключ API еще не существует, создайте ключ API в консоли, нажав Создать учетные данные > Ключ API . Вы можете ограничить ключ перед его использованием в рабочей среде, нажав «Ограничить ключ» и выбрав одно из « Ограничений» .

Чтобы обеспечить безопасность ключей API, следуйте рекомендациям по безопасному использованию ключей API .

Получив ключ API, ваше приложение может добавить параметр запроса key= yourAPIKey ко всем URL-адресам запроса.

Ключ API можно безопасно встраивать в URL-адреса; ему не нужна никакая кодировка.

Ограничения ключей API

По умолчанию ваш ключ API не имеет ограничений, что небезопасно, если кто-либо может либо прочитать этот ключ (например, если он размещен в браузере), либо получить доступ к устройству, на котором размещен ключ. Мы рекомендуем вам установить ограничение на этот ключ API, чтобы предотвратить несанкционированное использование.

Чтобы добавить ограничение, нажмите «Ограничить ключ» в диалоговом окне создания ключа API . Появится панель настройки API-ключа :

Тип ограничения, который вы выберете, будет зависеть от потребностей вашего приложения:

  • Веб-приложения, взаимодействующие напрямую с API (то есть не через какой-либо серверный или промежуточный уровень), должны добавить ограничение HTTP-рефереров . Однако обратите внимание, что такие приложения будут публично раскрывать свой ключ API; вместо этого предпочитайте использовать схему аутентификации учетной записи службы.
  • Серверные приложения, которые иначе не могут поддерживать учетные записи служб (например, встроенные устройства, у которых нет поддерживаемого языка в клиентской библиотеке), должны добавить ограничение IP-адресов , чтобы защититься от использования клиентами с разными IP-адресами.
  • Приложения Android должны добавить ограничение для приложений Android , а также имя вашего пакета и отпечаток сертификата подписи SHA-1.
  • Приложения iOS должны добавить ограничение приложений iOS и любые идентификаторы пакетов iOS, чтобы ограничить вызовы API к этим пакетам iOS.

Для тестирования вы можете вообще не устанавливать никаких ограничений. Однако рекомендуется либо добавить ограничение к этому ключу, либо удалить его после развертывания приложения в рабочей среде.

Пример запроса выборов

Вот пример (с использованием API версии «v2») вызова API choiceQuery для получения списка действительных идентификаторов выборов, а затем использования API VoterInfoQuery с зарегистрированным адресом избирателя для получения информации о выбранных выборах.

Используйте выборку, чтобы получить список действительных идентификаторов выборов:

  https://www.googleapis.com/civicinfo/v2/elections?key=<YOUR_API_KEY>
  

Ответ на запрос выборов:

{
 "kind": "civicinfo#electionsqueryresponse",
 "elections": [
  {
   "id": "2000",
   "name": "VIP Test Election",
   "electionDay": "2013-06-06"
  },
  {
   "id": "2124",
   "name": "Rhode Island 2012 Primary Election",
   "electionDay": "2012-09-11"
  },
  {
   "id": "2126",
   "name": "Delaware 2012 Primary Election",
   "electionDay": "2012-09-11"
  }
 ]
}

VoterInfoQuery с использованием Curl

Используйте curl , чтобы отправить запрос VoterInfoQuery для VIP-идентификатора тестовых выборов 2000 и избирателя по (тестовому) адресу 340 Main St, Venice, CA 90291. Вы можете обратиться к ответу VoterInfoQuery .

curl "https://www.googleapis.com/civicinfo/v2/voterinfo?key=<YOUR_API_KEY>&address=340%20Main%20St.%20Venice%20CA&electionId=2000"

VoterInfoQuery с использованием клиентской библиотеки Google API для JavaScript

В этом примере выдается тот же VoterInfoQuery, что и в предыдущем примере Curl, но он использует клиентскую библиотеку JavaScript . Ответ voicerInfoQuery такой же, как и ответ примера Curl.

<!doctype html>
<html>
  <head>
    <script>
      /**
       * Build and execute request to look up voter info for provided address.
       * @param {string} address Address for which to fetch voter info.
       * @param {function(Object)} callback Function which takes the
       *     response object as a parameter.
       */
       function lookup(address, callback) {
       /**
         * Election ID for which to fetch voter info.
         * @type {number}
         */
        var electionId = 2000;
 
        /**
         * Request object for given parameters.
         * @type {gapi.client.HttpRequest}
         */
        var req = gapi.client.request({
            'path' : '/civicinfo/v2/voterinfo',
            'params' : {'electionId' : electionId, 'address' : address}
        });
       req.execute(callback);
      }

      /**
       * Render results in the DOM.
       * @param {Object} response Response object returned by the API.
       * @param {Object} rawResponse Raw response from the API.
       */
      function renderResults(response, rawResponse) {
        var el = document.getElementById('results');
        if (!response || response.error) {
          el.appendChild(document.createTextNode(
              'Error while trying to fetch polling place'));
          return;
        }
        var normalizedAddress = response.normalizedInput.line1 + ' ' +
            response.normalizedInput.city + ', ' +
            response.normalizedInput.state + ' ' +
            response.normalizedInput.zip;
        if (response.pollingLocations.length > 0) {
          var pollingLocation = response.pollingLocations[0].address;
          var pollingAddress = pollingLocation.locationName + ', ' +
              pollingLocation.line1 + ' ' +
              pollingLocation.city + ', ' +
              pollingLocation.state + ' ' +
              pollingLocation.zip;
          var normEl = document.createElement('strong');
          normEl.appendChild(document.createTextNode(
              'Polling place for ' + normalizedAddress + ': '));
          el.appendChild(normEl);
          el.appendChild(document.createTextNode(pollingAddress));
        } else {
          el.appendChild(document.createTextNode(
              'Could not find polling place for ' + normalizedAddress));
        }
      }

      /**
       * Initialize the API client and make a request.
       */
      function load() {
        gapi.client.setApiKey('YOUR API KEY GOES HERE');
        lookup('1263 Pacific Ave. Kansas City KS', renderResults);
      }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=load"></script>
  </head>
  <body>
    <div id="results"></div>
  </body>
</html>

Ответ voicerInfoQuery

{
  "kind": "civicinfo#voterinforesponse",
  "status": "success",
  "election": {
  "id": "2000",
  "name": "VIP Test Election",
  "electionDay": "2025-06-06",
  "ocdDivisionId": "ocd-division/country:us"
  },
  "normalizedInput": {
    "line1": "340 Main Street",
    "city": "Venice",
    "state": "CA",
    "zip": "90291"
  },
  "pollingLocations": [
    {
      "address": {
        "locationName": "WESTMINSTER AVENUE ELEMENTARY SCHOOL",
        "line1": "1010 ABBOT KINNEY BLVD",
        "city": "VENICE",
        "state": "CA",
        "zip": "90291"
      },
      "pollingHours": "",
      "latitude": 33.9919351,
      "longitude": -118.4722031,
      "startDate": "2024-03-05",
      "endDate": "2024-03-05",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "address": {
        "locationName": "POP UP VOTE CENTER 5",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    }
  ],
  "dropOffLocations": [
    {
      "address": {
        "locationName": "FLEX VOTE CENTER 9",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
  ],
  "contests": [
    {
      "type": "General",
      "ballotTitle": "UNITED STATES REPRESENTATIVE, 36th District",
      "district": {
        "name": "36TH US CONGRESSIONAL",
        "scope": "congressional"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "103",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "ARIANA HAKAMI",
          "party": "Party Preference: Republican"
        },
        {
          "name": "CLAIRE RAGGE ANDERSON",
          "party": "Party Preference: None"
        },
        {
          "name": "MELISSA TOOMIM",
          "party": "Party Preference: Republican"
        },
        {
          "name": "TED W. LIEU",
          "party": "Party Preference: Democratic"
        }
      ]
    },
    {
      "type": "ballot-measure",
      "ballotTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "district": {
        "name": "CITY OF LOS ANGELES",
        "scope": "citywide"
      },
      "ballotPlacement": "116",
      "referendumTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "referendumText": "CITY MOBILITY PLAN STREET IMPROVEMENT MEASURES. INITIATIVE ORDINANCE HLA. Shall an ordinance providing that when the City of Los Angeles makes a qualifying improvement to a City-owned street (e.g., a paving project), the City must also install certain street enhancements described in the City's Mobility Plan network of pedestrian, bicycle, transit, and vehicle routes; and requiring the City to provide publicly accessible information regarding street improvements; be adopted?",
      "referendumPassageThreshold": "MAJORITY OF VOTES CAST",
      "referendumBallotResponses": [
        "YES",
        "NO"
      ],
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "type": "General",
      "ballotTitle": "DISTRICT ATTORNEY",
      "district": {
        "name": "LOS ANGELES COUNTY",
        "scope": "countywide"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "129",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "GEORGE GASCÓN"
        },
        {
          "name": "JONATHAN HATAMI"
        },
        {
          "name": "NATHAN HOCHMAN"
        },
        {
          "name": "DEBRA ARCHULETA"
        },
        {
          "name": "JEFF CHEMERINSKY"
        },
        {
          "name": "ERIC SIDDALL"
        },
        {
          "name": "MARIA RAMIREZ"
        },
        {
          "name": "DAN KAPELOVITZ"
        },
        {
          "name": "LLOYD \"BOBCAT\" MASSON"
        },
        {
          "name": "JOHN MCKINNEY"
        },
        {
          "name": "CRAIG J. MITCHELL"
        },
        {
          "name": "DAVID S. MILTON"
        }
      ]
    }
  ],
  "state": [
    {
      "name": "California",
      "electionAdministrationBody": {
        "name": "Secretary of State",
        "electionInfoUrl": "https://www.sos.ca.gov/elections/",
        "electionRegistrationUrl": "https://registertovote.ca.gov/?t=s",
        "electionRegistrationConfirmationUrl": "https://voterstatus.sos.ca.gov",
        "absenteeVotingInfoUrl": "https://elections.cdn.sos.ca.gov/vote-by-mail/replacement-application.pdf",
        "votingLocationFinderUrl": "https://voterstatus.sos.ca.gov",
        "ballotInfoUrl": "https://www.sos.ca.gov/elections/ballot-status/wheres-my-ballot/",
        "correspondenceAddress": {
          "line1": "1500 11th Street, 5th Floor",
          "city": "Sacramento",
          "state": "California",
          "zip": "95814"
        }
      },
      "local_jurisdiction": {
        "name": "Los Angeles",
        "electionAdministrationBody": {
          "name": "Registrar-Recorder/County Clerk",
          "electionInfoUrl": "http://www.lavote.gov/",
          "electionRegistrationUrl": "http://registertovote.ca.gov/",
          "electionRegistrationConfirmationUrl": "https://lavote.gov/vrstatus/",
          "absenteeVotingInfoUrl": "",
          "ballotInfoUrl": "http://www.lavote.gov/Locator",
          "physicalAddress": {
            "locationName": "Registrar-Recorder/County Clerk",
            "line1": "12400 Imperial Highway",
            "city": "Norwalk",
            "state": "CA",
            "zip": "90650"
          }
        },
        "sources": [
          {
            "name": "Voting Information Project",
            "official": true
          }
        ]
      }
    }
  ]
}
,

В этом документе описывается, что вам нужно знать, чтобы использовать API Google Civic Information. Вы можете просмотреть этот раздел часто задаваемых вопросов по Civic Info API , в котором содержится основная информация об API, а также часто задаваемые вопросы на нашем форуме пользователей. Кроме того, ниже вы можете увидеть примеры поиска информации об избирателях во время выборов.

Идентификация вашего приложения в Google

Ваше приложение должно идентифицировать себя каждый раз, когда оно отправляет запрос к API Google Civic Information, включая ключ API в каждый запрос.

Получение и использование ключа API

Чтобы получить ключ API:

  1. Откройте страницу «Учетные данные» в консоли API.
  2. Этот API поддерживает два типа учетных данных. Создайте учетные данные, подходящие для вашего проекта:
    • OAuth 2.0: всякий раз, когда ваше приложение запрашивает личные данные пользователя, оно должно отправить токен OAuth 2.0 вместе с запросом. Ваше приложение сначала отправляет идентификатор клиента и, возможно, секрет клиента для получения токена. Вы можете создать учетные данные OAuth 2.0 для веб-приложений, учетных записей служб или установленных приложений.

      Примечание. Поскольку в этом API нет методов, требующих авторизации OAuth 2.0, вам может потребоваться только получить ключи API , которые описаны ниже. Однако если ваше приложение вызывает другие API, требующие авторизации пользователя, вам все равно понадобятся учетные данные OAuth 2.0.

      Дополнительную информацию см. в документации OAuth 2.0 .

    • Ключи API. Запрос, который не предоставляет токен OAuth 2.0, должен отправить ключ API. Ключ идентифицирует ваш проект и обеспечивает доступ к API, квоту и отчеты.

      API поддерживает несколько типов ограничений для ключей API. Если нужный вам ключ API еще не существует, создайте ключ API в консоли, нажав Создать учетные данные > Ключ API . Вы можете ограничить ключ перед его использованием в рабочей среде, нажав «Ограничить ключ» и выбрав одно из « Ограничений» .

Чтобы обеспечить безопасность ключей API, следуйте рекомендациям по безопасному использованию ключей API .

Получив ключ API, ваше приложение может добавить параметр запроса key= yourAPIKey ко всем URL-адресам запроса.

Ключ API можно безопасно встраивать в URL-адреса; ему не нужна никакая кодировка.

Ограничения ключей API

По умолчанию ваш ключ API не имеет ограничений, что небезопасно, если кто-либо может либо прочитать этот ключ (например, если он размещен в браузере), либо получить доступ к устройству, на котором он размещен. Мы рекомендуем вам установить ограничение на этот ключ API, чтобы предотвратить несанкционированное использование.

Чтобы добавить ограничение, нажмите «Ограничить ключ» в диалоговом окне создания ключа API . Появится панель настройки API-ключа :

Тип ограничения, который вы выберете, будет зависеть от потребностей вашего приложения:

  • Веб-приложения, взаимодействующие напрямую с API (то есть не через какой-либо серверный или промежуточный уровень), должны добавить ограничение HTTP-рефереров . Однако обратите внимание, что такие приложения будут публично раскрывать свой ключ API; вместо этого предпочитайте использовать схему аутентификации учетной записи службы.
  • Серверные приложения, которые иначе не могут поддерживать учетные записи служб (например, встроенные устройства, у которых нет поддерживаемого языка в клиентской библиотеке), должны добавить ограничение IP-адресов , чтобы защититься от использования клиентами с разными IP-адресами.
  • Приложения Android должны добавить ограничение для приложений Android , а также имя вашего пакета и отпечаток сертификата подписи SHA-1.
  • Приложения iOS должны добавить ограничение приложений iOS и любые идентификаторы пакетов iOS, чтобы ограничить вызовы API к этим пакетам iOS.

Для тестирования вы можете вообще не устанавливать никаких ограничений. Однако рекомендуется либо добавить ограничение к этому ключу, либо удалить его после развертывания приложения в рабочей среде.

Пример запроса выборов

Ниже приведен пример (с использованием API версии «v2») вызова API choiceQuery для получения списка действительных идентификаторов выборов, а затем использования API VoterInfoQuery с зарегистрированным адресом избирателя для получения информации о выбранных выборах.

Используйте выборку, чтобы получить список действительных идентификаторов выборов:

  https://www.googleapis.com/civicinfo/v2/elections?key=<YOUR_API_KEY>
  

Ответ на запрос выборов:

{
 "kind": "civicinfo#electionsqueryresponse",
 "elections": [
  {
   "id": "2000",
   "name": "VIP Test Election",
   "electionDay": "2013-06-06"
  },
  {
   "id": "2124",
   "name": "Rhode Island 2012 Primary Election",
   "electionDay": "2012-09-11"
  },
  {
   "id": "2126",
   "name": "Delaware 2012 Primary Election",
   "electionDay": "2012-09-11"
  }
 ]
}

VoterInfoQuery с использованием Curl

Используйте curl , чтобы отправить запрос VoterInfoQuery для VIP-идентификатора тестовых выборов 2000 и избирателя по (тестовому) адресу 340 Main St, Venice, CA 90291. Вы можете обратиться к ответу VoterInfoQuery .

curl "https://www.googleapis.com/civicinfo/v2/voterinfo?key=<YOUR_API_KEY>&address=340%20Main%20St.%20Venice%20CA&electionId=2000"

VoterInfoQuery с использованием клиентской библиотеки Google API для JavaScript

В этом примере выдается тот же VoterInfoQuery, что и в предыдущем примере Curl, но он использует клиентскую библиотеку JavaScript . Ответ voicerInfoQuery такой же, как и ответ примера Curl.

<!doctype html>
<html>
  <head>
    <script>
      /**
       * Build and execute request to look up voter info for provided address.
       * @param {string} address Address for which to fetch voter info.
       * @param {function(Object)} callback Function which takes the
       *     response object as a parameter.
       */
       function lookup(address, callback) {
       /**
         * Election ID for which to fetch voter info.
         * @type {number}
         */
        var electionId = 2000;
 
        /**
         * Request object for given parameters.
         * @type {gapi.client.HttpRequest}
         */
        var req = gapi.client.request({
            'path' : '/civicinfo/v2/voterinfo',
            'params' : {'electionId' : electionId, 'address' : address}
        });
       req.execute(callback);
      }

      /**
       * Render results in the DOM.
       * @param {Object} response Response object returned by the API.
       * @param {Object} rawResponse Raw response from the API.
       */
      function renderResults(response, rawResponse) {
        var el = document.getElementById('results');
        if (!response || response.error) {
          el.appendChild(document.createTextNode(
              'Error while trying to fetch polling place'));
          return;
        }
        var normalizedAddress = response.normalizedInput.line1 + ' ' +
            response.normalizedInput.city + ', ' +
            response.normalizedInput.state + ' ' +
            response.normalizedInput.zip;
        if (response.pollingLocations.length > 0) {
          var pollingLocation = response.pollingLocations[0].address;
          var pollingAddress = pollingLocation.locationName + ', ' +
              pollingLocation.line1 + ' ' +
              pollingLocation.city + ', ' +
              pollingLocation.state + ' ' +
              pollingLocation.zip;
          var normEl = document.createElement('strong');
          normEl.appendChild(document.createTextNode(
              'Polling place for ' + normalizedAddress + ': '));
          el.appendChild(normEl);
          el.appendChild(document.createTextNode(pollingAddress));
        } else {
          el.appendChild(document.createTextNode(
              'Could not find polling place for ' + normalizedAddress));
        }
      }

      /**
       * Initialize the API client and make a request.
       */
      function load() {
        gapi.client.setApiKey('YOUR API KEY GOES HERE');
        lookup('1263 Pacific Ave. Kansas City KS', renderResults);
      }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=load"></script>
  </head>
  <body>
    <div id="results"></div>
  </body>
</html>

Ответ voicerInfoQuery

{
  "kind": "civicinfo#voterinforesponse",
  "status": "success",
  "election": {
  "id": "2000",
  "name": "VIP Test Election",
  "electionDay": "2025-06-06",
  "ocdDivisionId": "ocd-division/country:us"
  },
  "normalizedInput": {
    "line1": "340 Main Street",
    "city": "Venice",
    "state": "CA",
    "zip": "90291"
  },
  "pollingLocations": [
    {
      "address": {
        "locationName": "WESTMINSTER AVENUE ELEMENTARY SCHOOL",
        "line1": "1010 ABBOT KINNEY BLVD",
        "city": "VENICE",
        "state": "CA",
        "zip": "90291"
      },
      "pollingHours": "",
      "latitude": 33.9919351,
      "longitude": -118.4722031,
      "startDate": "2024-03-05",
      "endDate": "2024-03-05",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "address": {
        "locationName": "POP UP VOTE CENTER 5",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    }
  ],
  "dropOffLocations": [
    {
      "address": {
        "locationName": "FLEX VOTE CENTER 9",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
  ],
  "contests": [
    {
      "type": "General",
      "ballotTitle": "UNITED STATES REPRESENTATIVE, 36th District",
      "district": {
        "name": "36TH US CONGRESSIONAL",
        "scope": "congressional"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "103",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "ARIANA HAKAMI",
          "party": "Party Preference: Republican"
        },
        {
          "name": "CLAIRE RAGGE ANDERSON",
          "party": "Party Preference: None"
        },
        {
          "name": "MELISSA TOOMIM",
          "party": "Party Preference: Republican"
        },
        {
          "name": "TED W. LIEU",
          "party": "Party Preference: Democratic"
        }
      ]
    },
    {
      "type": "ballot-measure",
      "ballotTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "district": {
        "name": "CITY OF LOS ANGELES",
        "scope": "citywide"
      },
      "ballotPlacement": "116",
      "referendumTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "referendumText": "CITY MOBILITY PLAN STREET IMPROVEMENT MEASURES. INITIATIVE ORDINANCE HLA. Shall an ordinance providing that when the City of Los Angeles makes a qualifying improvement to a City-owned street (e.g., a paving project), the City must also install certain street enhancements described in the City's Mobility Plan network of pedestrian, bicycle, transit, and vehicle routes; and requiring the City to provide publicly accessible information regarding street improvements; be adopted?",
      "referendumPassageThreshold": "MAJORITY OF VOTES CAST",
      "referendumBallotResponses": [
        "YES",
        "NO"
      ],
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "type": "General",
      "ballotTitle": "DISTRICT ATTORNEY",
      "district": {
        "name": "LOS ANGELES COUNTY",
        "scope": "countywide"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "129",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "GEORGE GASCÓN"
        },
        {
          "name": "JONATHAN HATAMI"
        },
        {
          "name": "NATHAN HOCHMAN"
        },
        {
          "name": "DEBRA ARCHULETA"
        },
        {
          "name": "JEFF CHEMERINSKY"
        },
        {
          "name": "ERIC SIDDALL"
        },
        {
          "name": "MARIA RAMIREZ"
        },
        {
          "name": "DAN KAPELOVITZ"
        },
        {
          "name": "LLOYD \"BOBCAT\" MASSON"
        },
        {
          "name": "JOHN MCKINNEY"
        },
        {
          "name": "CRAIG J. MITCHELL"
        },
        {
          "name": "DAVID S. MILTON"
        }
      ]
    }
  ],
  "state": [
    {
      "name": "California",
      "electionAdministrationBody": {
        "name": "Secretary of State",
        "electionInfoUrl": "https://www.sos.ca.gov/elections/",
        "electionRegistrationUrl": "https://registertovote.ca.gov/?t=s",
        "electionRegistrationConfirmationUrl": "https://voterstatus.sos.ca.gov",
        "absenteeVotingInfoUrl": "https://elections.cdn.sos.ca.gov/vote-by-mail/replacement-application.pdf",
        "votingLocationFinderUrl": "https://voterstatus.sos.ca.gov",
        "ballotInfoUrl": "https://www.sos.ca.gov/elections/ballot-status/wheres-my-ballot/",
        "correspondenceAddress": {
          "line1": "1500 11th Street, 5th Floor",
          "city": "Sacramento",
          "state": "California",
          "zip": "95814"
        }
      },
      "local_jurisdiction": {
        "name": "Los Angeles",
        "electionAdministrationBody": {
          "name": "Registrar-Recorder/County Clerk",
          "electionInfoUrl": "http://www.lavote.gov/",
          "electionRegistrationUrl": "http://registertovote.ca.gov/",
          "electionRegistrationConfirmationUrl": "https://lavote.gov/vrstatus/",
          "absenteeVotingInfoUrl": "",
          "ballotInfoUrl": "http://www.lavote.gov/Locator",
          "physicalAddress": {
            "locationName": "Registrar-Recorder/County Clerk",
            "line1": "12400 Imperial Highway",
            "city": "Norwalk",
            "state": "CA",
            "zip": "90650"
          }
        },
        "sources": [
          {
            "name": "Voting Information Project",
            "official": true
          }
        ]
      }
    }
  ]
}
,

В этом документе описывается, что вам нужно знать, чтобы использовать API Google Civic Information. Вы можете просмотреть этот раздел часто задаваемых вопросов по Civic Info API , в котором содержится основная информация об API, а также часто задаваемые вопросы на нашем форуме пользователей. Кроме того, ниже вы можете увидеть примеры поиска информации об избирателях во время выборов.

Идентификация вашего приложения в Google

Ваше приложение должно идентифицировать себя каждый раз, когда оно отправляет запрос к API Google Civic Information, включая ключ API в каждый запрос.

Получение и использование ключа API

Чтобы получить ключ API:

  1. Откройте страницу «Учетные данные» в консоли API.
  2. Этот API поддерживает два типа учетных данных. Создайте учетные данные, подходящие для вашего проекта:
    • OAuth 2.0: всякий раз, когда ваше приложение запрашивает личные данные пользователя, оно должно отправить токен OAuth 2.0 вместе с запросом. Ваше приложение сначала отправляет идентификатор клиента и, возможно, секрет клиента для получения токена. Вы можете создать учетные данные OAuth 2.0 для веб-приложений, учетных записей служб или установленных приложений.

      Примечание. Поскольку в этом API нет методов, требующих авторизации OAuth 2.0, вам может потребоваться только получить ключи API , которые описаны ниже. Однако если ваше приложение вызывает другие API, требующие авторизации пользователя, вам все равно понадобятся учетные данные OAuth 2.0.

      Дополнительную информацию см. в документации OAuth 2.0 .

    • Ключи API. Запрос, который не предоставляет токен OAuth 2.0, должен отправить ключ API. Ключ идентифицирует ваш проект и обеспечивает доступ к API, квоту и отчеты.

      API поддерживает несколько типов ограничений для ключей API. Если нужный вам ключ API еще не существует, создайте ключ API в консоли, нажав Создать учетные данные > Ключ API . Вы можете ограничить ключ перед его использованием в рабочей среде, нажав «Ограничить ключ» и выбрав одно из « Ограничений» .

Чтобы обеспечить безопасность ключей API, следуйте рекомендациям по безопасному использованию ключей API .

Получив ключ API, ваше приложение может добавить параметр запроса key= yourAPIKey ко всем URL-адресам запроса.

Ключ API можно безопасно встраивать в URL-адреса; ему не нужна никакая кодировка.

Ограничения ключей API

По умолчанию ваш ключ API не имеет ограничений, что небезопасно, если кто-либо может либо прочитать этот ключ (например, если он размещен в браузере), либо получить доступ к устройству, на котором он размещен. Мы рекомендуем вам установить ограничение на этот ключ API, чтобы предотвратить несанкционированное использование.

Чтобы добавить ограничение, нажмите «Ограничить ключ» в диалоговом окне создания ключа API . Появится панель настройки API-ключа :

Тип ограничения, который вы выберете, будет зависеть от потребностей вашего приложения:

  • Веб-приложения, взаимодействующие напрямую с API (то есть не через какой-либо серверный или промежуточный уровень), должны добавить ограничение HTTP-рефереров . Однако обратите внимание, что такие приложения будут публично раскрывать свой ключ API; вместо этого предпочитайте использовать схему аутентификации учетной записи службы.
  • Серверные приложения, которые иначе не могут поддерживать учетные записи служб (например, встроенные устройства, у которых нет поддерживаемого языка в клиентской библиотеке), должны добавить ограничение IP-адресов , чтобы защититься от использования клиентами с разными IP-адресами.
  • Приложения Android должны добавить ограничение для приложений Android , а также имя вашего пакета и отпечаток сертификата подписи SHA-1.
  • Приложения iOS должны добавить ограничение приложений iOS и любые идентификаторы пакетов iOS, чтобы ограничить вызовы API к этим пакетам iOS.

Для тестирования вы можете вообще не устанавливать никаких ограничений. Однако рекомендуется либо добавить ограничение к этому ключу, либо удалить его после развертывания приложения в рабочей среде.

Пример запроса выборов

Ниже приведен пример (с использованием API версии «v2») вызова API choiceQuery для получения списка действительных идентификаторов выборов, а затем использования API VoterInfoQuery с зарегистрированным адресом избирателя для получения информации о выбранных выборах.

Используйте выборку, чтобы получить список действительных идентификаторов выборов:

  https://www.googleapis.com/civicinfo/v2/elections?key=<YOUR_API_KEY>
  

Ответ на запрос выборов:

{
 "kind": "civicinfo#electionsqueryresponse",
 "elections": [
  {
   "id": "2000",
   "name": "VIP Test Election",
   "electionDay": "2013-06-06"
  },
  {
   "id": "2124",
   "name": "Rhode Island 2012 Primary Election",
   "electionDay": "2012-09-11"
  },
  {
   "id": "2126",
   "name": "Delaware 2012 Primary Election",
   "electionDay": "2012-09-11"
  }
 ]
}

VoterInfoQuery с использованием Curl

Используйте curl , чтобы отправить запрос VoterInfoQuery для VIP-идентификатора тестовых выборов 2000 и избирателя по (тестовому) адресу 340 Main St, Venice, CA 90291. Вы можете обратиться к ответу VoterInfoQuery .

curl "https://www.googleapis.com/civicinfo/v2/voterinfo?key=<YOUR_API_KEY>&address=340%20Main%20St.%20Venice%20CA&electionId=2000"

VoterInfoQuery с использованием клиентской библиотеки Google API для JavaScript

В этом примере выдается тот же VoterInfoQuery, что и в предыдущем примере Curl, но он использует клиентскую библиотеку JavaScript . Ответ voicerInfoQuery такой же, как и ответ примера Curl.

<!doctype html>
<html>
  <head>
    <script>
      /**
       * Build and execute request to look up voter info for provided address.
       * @param {string} address Address for which to fetch voter info.
       * @param {function(Object)} callback Function which takes the
       *     response object as a parameter.
       */
       function lookup(address, callback) {
       /**
         * Election ID for which to fetch voter info.
         * @type {number}
         */
        var electionId = 2000;
 
        /**
         * Request object for given parameters.
         * @type {gapi.client.HttpRequest}
         */
        var req = gapi.client.request({
            'path' : '/civicinfo/v2/voterinfo',
            'params' : {'electionId' : electionId, 'address' : address}
        });
       req.execute(callback);
      }

      /**
       * Render results in the DOM.
       * @param {Object} response Response object returned by the API.
       * @param {Object} rawResponse Raw response from the API.
       */
      function renderResults(response, rawResponse) {
        var el = document.getElementById('results');
        if (!response || response.error) {
          el.appendChild(document.createTextNode(
              'Error while trying to fetch polling place'));
          return;
        }
        var normalizedAddress = response.normalizedInput.line1 + ' ' +
            response.normalizedInput.city + ', ' +
            response.normalizedInput.state + ' ' +
            response.normalizedInput.zip;
        if (response.pollingLocations.length > 0) {
          var pollingLocation = response.pollingLocations[0].address;
          var pollingAddress = pollingLocation.locationName + ', ' +
              pollingLocation.line1 + ' ' +
              pollingLocation.city + ', ' +
              pollingLocation.state + ' ' +
              pollingLocation.zip;
          var normEl = document.createElement('strong');
          normEl.appendChild(document.createTextNode(
              'Polling place for ' + normalizedAddress + ': '));
          el.appendChild(normEl);
          el.appendChild(document.createTextNode(pollingAddress));
        } else {
          el.appendChild(document.createTextNode(
              'Could not find polling place for ' + normalizedAddress));
        }
      }

      /**
       * Initialize the API client and make a request.
       */
      function load() {
        gapi.client.setApiKey('YOUR API KEY GOES HERE');
        lookup('1263 Pacific Ave. Kansas City KS', renderResults);
      }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=load"></script>
  </head>
  <body>
    <div id="results"></div>
  </body>
</html>

Ответ voicerInfoQuery

{
  "kind": "civicinfo#voterinforesponse",
  "status": "success",
  "election": {
  "id": "2000",
  "name": "VIP Test Election",
  "electionDay": "2025-06-06",
  "ocdDivisionId": "ocd-division/country:us"
  },
  "normalizedInput": {
    "line1": "340 Main Street",
    "city": "Venice",
    "state": "CA",
    "zip": "90291"
  },
  "pollingLocations": [
    {
      "address": {
        "locationName": "WESTMINSTER AVENUE ELEMENTARY SCHOOL",
        "line1": "1010 ABBOT KINNEY BLVD",
        "city": "VENICE",
        "state": "CA",
        "zip": "90291"
      },
      "pollingHours": "",
      "latitude": 33.9919351,
      "longitude": -118.4722031,
      "startDate": "2024-03-05",
      "endDate": "2024-03-05",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "address": {
        "locationName": "POP UP VOTE CENTER 5",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    }
  ],
  "dropOffLocations": [
    {
      "address": {
        "locationName": "FLEX VOTE CENTER 9",
        "line1": "12400 IMPERIAL HWY",
        "city": "NORWALK",
        "state": "CA",
        "zip": "90650"
      },
      "latitude": 33.915989,
      "longitude": -118.0677283,
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
  ],
  "contests": [
    {
      "type": "General",
      "ballotTitle": "UNITED STATES REPRESENTATIVE, 36th District",
      "district": {
        "name": "36TH US CONGRESSIONAL",
        "scope": "congressional"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "103",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "ARIANA HAKAMI",
          "party": "Party Preference: Republican"
        },
        {
          "name": "CLAIRE RAGGE ANDERSON",
          "party": "Party Preference: None"
        },
        {
          "name": "MELISSA TOOMIM",
          "party": "Party Preference: Republican"
        },
        {
          "name": "TED W. LIEU",
          "party": "Party Preference: Democratic"
        }
      ]
    },
    {
      "type": "ballot-measure",
      "ballotTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "district": {
        "name": "CITY OF LOS ANGELES",
        "scope": "citywide"
      },
      "ballotPlacement": "116",
      "referendumTitle": "LOS ANGELES CITY MUNICIPAL ELECTION - MEASURE HLA",
      "referendumText": "CITY MOBILITY PLAN STREET IMPROVEMENT MEASURES. INITIATIVE ORDINANCE HLA. Shall an ordinance providing that when the City of Los Angeles makes a qualifying improvement to a City-owned street (e.g., a paving project), the City must also install certain street enhancements described in the City's Mobility Plan network of pedestrian, bicycle, transit, and vehicle routes; and requiring the City to provide publicly accessible information regarding street improvements; be adopted?",
      "referendumPassageThreshold": "MAJORITY OF VOTES CAST",
      "referendumBallotResponses": [
        "YES",
        "NO"
      ],
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ]
    },
    {
      "type": "General",
      "ballotTitle": "DISTRICT ATTORNEY",
      "district": {
        "name": "LOS ANGELES COUNTY",
        "scope": "countywide"
      },
      "numberElected": "1",
      "numberVotingFor": "1",
      "ballotPlacement": "129",
      "sources": [
        {
          "name": "Voting Information Project",
          "official": true
        }
      ],
      "candidates": [
        {
          "name": "GEORGE GASCÓN"
        },
        {
          "name": "JONATHAN HATAMI"
        },
        {
          "name": "NATHAN HOCHMAN"
        },
        {
          "name": "DEBRA ARCHULETA"
        },
        {
          "name": "JEFF CHEMERINSKY"
        },
        {
          "name": "ERIC SIDDALL"
        },
        {
          "name": "MARIA RAMIREZ"
        },
        {
          "name": "DAN KAPELOVITZ"
        },
        {
          "name": "LLOYD \"BOBCAT\" MASSON"
        },
        {
          "name": "JOHN MCKINNEY"
        },
        {
          "name": "CRAIG J. MITCHELL"
        },
        {
          "name": "DAVID S. MILTON"
        }
      ]
    }
  ],
  "state": [
    {
      "name": "California",
      "electionAdministrationBody": {
        "name": "Secretary of State",
        "electionInfoUrl": "https://www.sos.ca.gov/elections/",
        "electionRegistrationUrl": "https://registertovote.ca.gov/?t=s",
        "electionRegistrationConfirmationUrl": "https://voterstatus.sos.ca.gov",
        "absenteeVotingInfoUrl": "https://elections.cdn.sos.ca.gov/vote-by-mail/replacement-application.pdf",
        "votingLocationFinderUrl": "https://voterstatus.sos.ca.gov",
        "ballotInfoUrl": "https://www.sos.ca.gov/elections/ballot-status/wheres-my-ballot/",
        "correspondenceAddress": {
          "line1": "1500 11th Street, 5th Floor",
          "city": "Sacramento",
          "state": "California",
          "zip": "95814"
        }
      },
      "local_jurisdiction": {
        "name": "Los Angeles",
        "electionAdministrationBody": {
          "name": "Registrar-Recorder/County Clerk",
          "electionInfoUrl": "http://www.lavote.gov/",
          "electionRegistrationUrl": "http://registertovote.ca.gov/",
          "electionRegistrationConfirmationUrl": "https://lavote.gov/vrstatus/",
          "absenteeVotingInfoUrl": "",
          "ballotInfoUrl": "http://www.lavote.gov/Locator",
          "physicalAddress": {
            "locationName": "Registrar-Recorder/County Clerk",
            "line1": "12400 Imperial Highway",
            "city": "Norwalk",
            "state": "CA",
            "zip": "90650"
          }
        },
        "sources": [
          {
            "name": "Voting Information Project",
            "official": true
          }
        ]
      }
    }
  ]
}