V1
Verify an Indian EPIC (Voter ID) number against electoral records. Server-side POST with Bearer auth.
Voter ID Verification (V1)
API reference
JWT Bearer token authentication. Obtain a token from the KwikID dashboard.
In: header
EPIC (Voter ID) number. Must be 3 uppercase letters followed by 7 digits.
^[A-Z]{3}[0-9]{7}$Response Body
curl -X POST "https://__playground__/verification/v2/voterid/verify" \ -H "Content-Type: application/json" \ -d '{ "voter_id_number": "XXY4829103" }'{
"captcha_tries": 0,
"response": {
"docs": [
{
"content": {
"acId": 131,
"acNumber": 132,
"age": 26,
"applicantFirstName": "AMIT",
"applicantFirstNameL1": "अमित",
"applicantFirstNameL2": null,
"applicantLastName": "VERMA",
"applicantLastNameL1": "वर्मा",
"applicantLastNameL2": null,
"asmblyName": "Andheri East",
"asmblyNameL1": "अंधेरी पूर्व",
"atSupplementDate": null,
"atSupplementStatus": null,
"birthYear": null,
"buildingAddress": "Sector 4",
"buildingAddressL1": "सेक्टर ४",
"createdDttm": "2023-05-23 14:45:07",
"disabilityAny": null,
"disabilityType": null,
"districtCd": "S1336",
"districtId": null,
"districtNo": 36,
"districtValue": "Mumbai Suburban",
"districtValueL1": "मुंबई उपनगर",
"electionDate": null,
"electionTime": null,
"epicDatetime": "2024-12-28T12:37:02.926+00:00",
"epicId": 48291031,
"epicNumber": "XXY4829103",
"formReferenceNo": null,
"formType": null,
"fullName": "amit verma",
"fullNameL1": "अमित वर्मा",
"gender": "M",
"genderL1": null,
"id": "48291031_XXY4829103_S13",
"isActive": true,
"isDeleted": null,
"isForm8Migration": null,
"isLocomotorDisabled": null,
"isSpeechHearingDisabled": null,
"isValidated": null,
"isVip": null,
"isVisuallyImpaired": null,
"isWheelchairRequired": null,
"joSupplementDate": null,
"joSupplementStatus": null,
"modifiedDttm": null,
"otherDisability": null,
"partId": 225473,
"partLatLong": null,
"partName": "Sector 4",
"partNameL1": "सेक्टर ४",
"partNumber": "333",
"partSerialNumber": 362,
"pollingDate": null,
"prlmntName": "Mumbai North",
"prlmntNameL1": null,
"prlmntNo": "22",
"processType": null,
"psBuildingNameL1": "नगरपालिका माध्यमिक विद्यालय",
"psRoomDetails": "Ground Floor, Room 5",
"psRoomDetailsL1": "तळ मजला, खोली ५",
"psbuildingName": "Municipal Secondary School",
"pwd": null,
"pwdMarkingFormType": null,
"pwdMarkingRefNo": null,
"relationLName": "SHARMA",
"relationLNameL1": null,
"relationName": "RAKESH",
"relationNameL1": "राकेश",
"relationNameL2": null,
"relationType": "OTHR",
"relationTypeL1": null,
"relativeFullName": "rakesh sharma",
"relativeFullNameL1": "राकेश",
"revisionId": null,
"sectionNo": 1,
"stateCd": "S13",
"stateId": 12,
"stateName": "Maharashtra",
"stateNameL1": "महाराष्ट्र",
"statusType": null,
"underJo": null
},
"explanation": null,
"highlightFields": {},
"id": "48291031_XXY4829103_S13",
"index": "national-electoral-display",
"innerHits": {},
"matchedQueries": [],
"nestedMetaData": null,
"routing": null,
"score": 17.017735,
"sortValues": []
}
]
},
"segment_flag": 0,
"credits_consumed": 2
}{
"message": "Invalid voter_id_number format. Must be 3 letters followed by 7 digits (e.g., ABC1234567).",
"captcha_tries": 0
}{
"message": "Authorization header is required",
"captcha_tries": 0
}{
"message": "Electoral Search website down. Please try again later",
"captcha_tries": 3,
"segment_flag": 0
}Overview
Call POST /verification/v2/voterid/verify from your backend with Authorization: Bearer <token> and JSON voter_id_number. The value must be 3 uppercase letters followed by 7 digits (for example XXY4829103). On 200 OK, the body includes electoral record data under response.docs, plus captcha_tries, segment_flag, and credits_consumed.
Key features
- EPIC lookup against national electoral display records.
- Structured elector fields such as name, age, gender, state, and polling part details inside each doc's
contentobject.
Implementation
Step 1: Prepare the request body
Send voter_id_number in JSON. Format: 3 uppercase letters + 7 digits.
| Field | Type | Required | Description |
|---|---|---|---|
| voter_id_number | string | Yes | EPIC (Voter ID) number. Pattern: ^[A-Z]{3}[0-9]{7}$ (for example XXY4829103). |
Example request:
{
"voter_id_number": "XXY4829103"
}Step 2: Call from your backend
POST /verification/v2/voterid/verify HTTP/1.1
Host: <verification-api-base-url>
Authorization: Bearer <token>
Content-Type: application/json
{
"voter_id_number": "XXY4829103"
}Step 3: Use the response
Read response.docs. Each array item is one elector match with a content object (profile and polling metadata). Treat the payload as PII; do not log full names or EPIC numbers in client-side analytics.
Response
Top-level wrapper:
| Field | Type | Description |
|---|---|---|
| captcha_tries | integer | Captcha solve attempts used for this request. |
| response | object | Electoral search results (see below). |
| segment_flag | integer | Internal captcha segmentation flag for this request. |
| credits_consumed | number | Verification credits consumed for this request. |
response object:
| Field | Type | Description |
|---|---|---|
| docs | array | Matching elector records from the national electoral display index. |
docs[] item fields (search metadata):
| Field | Type | Description |
|---|---|---|
| content | object | Elector profile and polling metadata (see below). |
| id | string | Unique document id in the electoral index (for example 48291031_XXY4829103_S13). |
| index | string | Source index name (for example national-electoral-display). |
| score | number | Search relevance score. |
| explanation | object / null | Optional search explanation metadata. |
| highlightFields | object | Highlight map from the search engine; often empty. |
| innerHits | object | Nested hit metadata; often empty. |
| matchedQueries | array | Matched query tokens; often empty. |
| nestedMetaData | object / null | Optional nested metadata. |
| routing | string / null | Optional routing key. |
| sortValues | array | Sort values from the search engine; often empty. |
content object fields (key elector and polling fields):
| Field | Type | Description |
|---|---|---|
| epicNumber | string | EPIC (Voter ID) number on record. |
| epicId | integer | Internal EPIC record id. |
| epicDatetime | string | EPIC record timestamp (ISO 8601). |
| applicantFirstName | string | Elector first name. |
| applicantLastName | string | Elector last name. |
| applicantFirstNameL1 | string | First name in regional script (L1). |
| applicantLastNameL1 | string | Last name in regional script (L1). |
| fullName | string | Full name as stored on the roll. |
| fullNameL1 | string | Full name in regional script (L1). |
| age | integer | Age as per electoral record. |
| birthYear | integer / null | Birth year when present. |
| gender | string | Gender code (for example M or F). |
| stateName | string | State name. |
| stateNameL1 | string | State name in regional script (L1). |
| stateCd | string | State code (for example S13). |
| districtValue | string | District name. |
| districtValueL1 | string | District name in regional script (L1). |
| districtNo | integer | District number. |
| buildingAddress | string | Building or locality address on the roll. |
| buildingAddressL1 | string | Building address in regional script (L1). |
| asmblyName | string | Assembly constituency name. |
| asmblyNameL1 | string | Assembly constituency name in regional script (L1). |
| acNumber | integer | Assembly constituency number. |
| acId | integer | Assembly constituency id. |
| prlmntName | string | Parliamentary constituency name. |
| prlmntNo | string | Parliamentary constituency number. |
| partName | string | Polling part / area name. |
| partNameL1 | string | Polling part name in regional script (L1). |
| partNumber | string | Polling part number. |
| partSerialNumber | integer | Serial number within the polling part. |
| partId | integer | Polling part id. |
| psbuildingName | string | Polling station building name. |
| psRoomDetails | string | Polling station room or hall details. |
| psbuildingNameL1 | string | Polling station name in regional script (L1). |
| psRoomDetailsL1 | string | Room details in regional script (L1). |
| relationName | string | Relative or guardian first name. |
| relationLName | string | Relative or guardian last name. |
| relationType | string | Relation type code (for example FTHR, MTHR, OTHR). |
| relativeFullName | string | Relative full name as on the roll. |
| relativeFullNameL1 | string | Relative name in regional script (L1). |
| isActive | boolean | Whether the elector record is active. |
| createdDttm | string | Record creation timestamp. |
| id | string | Content-level record id (often matches outer docs[].id). |
Additional disability, supplement, VIP, and election-date fields may appear in content; they are often null when not applicable.
Example response (mock values):
{
"captcha_tries": 0,
"response": {
"docs": [
{
"content": {
"acId": 131,
"acNumber": 132,
"age": 26,
"applicantFirstName": "AMIT",
"applicantFirstNameL1": "अमित",
"applicantFirstNameL2": null,
"applicantLastName": "VERMA",
"applicantLastNameL1": "वर्मा",
"applicantLastNameL2": null,
"asmblyName": "Andheri East",
"asmblyNameL1": "अंधेरी पूर्व",
"atSupplementDate": null,
"atSupplementStatus": null,
"birthYear": null,
"buildingAddress": "Sector 4",
"buildingAddressL1": "सेक्टर ४",
"createdDttm": "2023-05-23 14:45:07",
"disabilityAny": null,
"disabilityType": null,
"districtCd": "S1336",
"districtId": null,
"districtNo": 36,
"districtValue": "Mumbai Suburban",
"districtValueL1": "मुंबई उपनगर",
"electionDate": null,
"electionTime": null,
"epicDatetime": "2024-12-28T12:37:02.926+00:00",
"epicId": 48291031,
"epicNumber": "XXY4829103",
"formReferenceNo": null,
"formType": null,
"fullName": "amit verma",
"fullNameL1": "अमित वर्मा",
"gender": "M",
"genderL1": null,
"id": "48291031_XXY4829103_S13",
"isActive": true,
"isDeleted": null,
"isForm8Migration": null,
"isLocomotorDisabled": null,
"isSpeechHearingDisabled": null,
"isValidated": null,
"isVip": null,
"isVisuallyImpaired": null,
"isWheelchairRequired": null,
"joSupplementDate": null,
"joSupplementStatus": null,
"modifiedDttm": null,
"otherDisability": null,
"partId": 225473,
"partLatLong": null,
"partName": "Sector 4",
"partNameL1": "सेक्टर ४",
"partNumber": "333",
"partSerialNumber": 362,
"pollingDate": null,
"prlmntName": "Mumbai North",
"prlmntNameL1": null,
"prlmntNo": "22",
"processType": null,
"psBuildingNameL1": "नगरपालिका माध्यमिक विद्यालय",
"psRoomDetails": "Ground Floor, Room 5",
"psRoomDetailsL1": "तळ मजला, खोली ५",
"psbuildingName": "Municipal Secondary School",
"pwd": null,
"pwdMarkingFormType": null,
"pwdMarkingRefNo": null,
"relationLName": "SHARMA",
"relationLNameL1": null,
"relationName": "RAKESH",
"relationNameL1": "राकेश",
"relationNameL2": null,
"relationType": "OTHR",
"relationTypeL1": null,
"relativeFullName": "rakesh sharma",
"relativeFullNameL1": "राकेश",
"revisionId": null,
"sectionNo": 1,
"stateCd": "S13",
"stateId": 12,
"stateName": "Maharashtra",
"stateNameL1": "महाराष्ट्र",
"statusType": null,
"underJo": null
},
"explanation": null,
"highlightFields": {},
"id": "48291031_XXY4829103_S13",
"index": "national-electoral-display",
"innerHits": {},
"matchedQueries": [],
"nestedMetaData": null,
"routing": null,
"score": 17.017735,
"sortValues": []
}
]
},
"segment_flag": 0,
"credits_consumed": 2
}Error handling
| HTTP status | When |
|---|---|
| 400 | Missing or invalid voter_id_number, captcha attempts exceeded, or ECI source unavailable. |
| 401 | Missing or invalid Bearer token. |
| 500 | Verification failed or upstream electoral search error. |
Example 400 (invalid format):
{
"message": "Invalid voter_id_number format. Must be 3 letters followed by 7 digits (e.g., ABC1234567).",
"captcha_tries": 0
}Security notes
- Responses contain PII (name, EPIC, address, relative name). Log only correlation ids.
- Call only from your backend; never expose the Bearer token or raw response to the browser.
Benefits
- Confirms EPIC against electoral records without manual portal checks.
- Returns constituency and polling metadata useful for address corroboration.