Elections
Use Case
Use these endpoints to build an elections explorer, similar to the one on our Elections dashboard. A user picks an election from a dropdown, and your app fetches the party breakdown, the seat-by-seat winner map, and the headline turnout statistics. The four endpoints work together: start with /elections/dropdown to get valid election identifiers, then pass them to whichever of the three data endpoints you need.
Just follow the 4 simple steps below, and you’ll be up and running!
Prerequisite: API Key
All requests to this API require a Bearer token. Requests without a token (or with an invalid one) will return a 401 Unauthorized error. Paste yours below—every code snippet and the live testers at the bottom of this page will be pre-filled and ready to run.
Step 1: Get list of elections
https://api.electiondata.my/v1/elections/dropdownThis endpoint takes no parameters and returns every general and state election in the database. The state and election values it returns are the exact parameters required by Steps 2–4. Because the list is only updated when a new election is called, we recommend fetching it once and caching it for the duration of a session (or bundling it at build time for static pages).
A successful 200 OK response returns a JSON object with a single elections key containing an array of every election. Each object contains:
| Field | Type | Description |
|---|---|---|
state | string | State or aggregation scope (e.g. 'Malaysia', 'Semenanjung', 'Selangor'). Pass this to Steps 2–4. |
type | string | 'parlimen' for parliamentary elections or 'dun' for state assembly elections. |
election | string | Election identifier (e.g. 'GE-15' or 'SE-15'). Pass this to Steps 2–4. |
date | date | Polling day in ISO 8601 format (YYYY-MM-DD). |
Step 2: Get results by party
Pass the state and election from Step 1 to get party-level vote and seat aggregates.
https://api.electiondata.my/v1/elections/by_party| Parameter | Type | Required | Description |
|---|---|---|---|
state | string | Yes | State or aggregation scope, e.g. 'Malaysia' or 'Selangor'. Taken directly from the state field in the dropdown response. |
election | string | Yes | Election identifier, e.g. 'GE-15' or 'SE-15'. Taken directly from the election field in the dropdown response. |
A successful 200 OK response returns a JSON object with a by_party key containing an array of party results, ordered by votes received (descending). Each object contains:
| Field | Type | Description |
|---|---|---|
party_uid | string | Unique party identifier (e.g. '004-PAS'). |
party | string | Party acronym (e.g. 'PAS'). |
coalition | string | Coalition name (e.g. 'PN'). 'ALONE' if the party contested independently. |
coalition_uid | string | Unique coalition identifier (e.g. '11-PN'). '0' if independent. |
seats_contested | integer | Number of seats the party contested in this election. |
seats_won | integer | Number of seats the party won. |
seats_total | integer | Total seats available in this election (the denominator for share calculations). |
seats_contested_perc | float | seats_contested as a percentage of seats_total. |
seats_won_perc | float | seats_won as a percentage of seats_total. |
votes | integer | Total votes received by the party across all seats. |
votes_total | integer | Total valid votes cast in the election (the denominator for vote share). |
votes_perc | float | votes as a percentage of votes_total. |
Step 3: Get results by seat
Pass the same state and election to get data constituency in that election.
https://api.electiondata.my/v1/elections/by_seat| Parameter | Type | Required | Description |
|---|---|---|---|
state | string | Yes | State or aggregation scope, e.g. 'Malaysia' or 'Selangor'. Taken directly from the state field in the dropdown response. |
election | string | Yes | Election identifier, e.g. 'GE-15' or 'SE-15'. Taken directly from the election field in the dropdown response. |
A successful 200 OK response returns a JSON object with a by_seat key containing an array of seat results, one entry per constituency. Each object contains:
| Field | Type | Description |
|---|---|---|
seat | string | Constituency identifier (e.g. 'P.001 Padang Besar, Perlis'). |
state | string | The state parameter echoed back. |
date | date | Polling day for this seat in ISO 8601 format (YYYY-MM-DD). |
name | string | Winner's full name. |
party | string | Acronym of the winning party (e.g. 'PAS'). |
party_uid | string | Unique identifier for the winning party (e.g. '004-PAS'). |
coalition | string | Coalition of the winning party (e.g. 'PN'). 'ALONE' if independent. |
coalition_uid | integer | Numeric coalition identifier (0 if independent). |
party_lost | string[] | Acronyms of parties that lost in this seat. |
party_lost_uid | string[] | Unique identifiers for the losing parties. |
coalition_lost | string[] | Coalitions represented by the losing parties. |
coalition_lost_uid | integer[] | Numeric identifiers for the losing coalitions. |
n_candidates | integer | Total number of candidates who contested this seat. |
voters_total | integer | Total number of registered voters for this seat. |
voter_turnout | integer | Total votes cast, including rejected votes. |
voter_turnout_perc | float | Turnout as a percentage of registered voters. |
majority | integer | Winning margin, i.e. winner's votes minus runner-up's votes. |
majority_perc | float | Majority as a percentage of total valid votes. |
votes_rejected | integer | Number of votes rejected during counting. |
votes_rejected_perc | float | Rejected votes as a percentage of total ballots cast. |
Step 4: Get summary stats
Pass the same state and election to get aggregate turnout and rejection statistics for the entire election.
https://api.electiondata.my/v1/elections/stats| Parameter | Type | Required | Description |
|---|---|---|---|
state | string | Yes | State or aggregation scope, e.g. 'Malaysia' or 'Selangor'. Taken directly from the state field in the dropdown response. |
election | string | Yes | Election identifier, e.g. 'GE-15' or 'SE-15'. Taken directly from the election field in the dropdown response. |
A successful 200 OK response returns a JSON object with a stats key containing an array with a single aggregate statistics object:
| Field | Type | Description |
|---|---|---|
voters_total | integer | Total number of registered voters across all seats in this election. |
voter_turnout | integer | Total votes cast, including rejected votes. |
voter_turnout_perc | float | Turnout as a percentage of registered voters. |
votes_rejected | integer | Total number of votes rejected across all seats. |
votes_rejected_perc | float | Rejected votes as a percentage of total ballots cast. |
n_candidates | integer | Total number of candidates who contested across all seats. |
Try It Out
Start on the Dropdown tab to fetch the list of elections, then switch to By Party, By Seat, or Stats—load the elections once and the selection stays synced across all tabs.