/ Endpoints

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

GEThttps://api.electiondata.my/v1/elections/dropdown

This 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:

FieldTypeDescription
statestringState or aggregation scope (e.g. 'Malaysia', 'Semenanjung', 'Selangor'). Pass this to Steps 2–4.
typestring'parlimen' for parliamentary elections or 'dun' for state assembly elections.
electionstringElection identifier (e.g. 'GE-15' or 'SE-15'). Pass this to Steps 2–4.
datedatePolling 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.

GEThttps://api.electiondata.my/v1/elections/by_party
ParameterTypeRequiredDescription
statestringYesState or aggregation scope, e.g. 'Malaysia' or 'Selangor'. Taken directly from the state field in the dropdown response.
electionstringYesElection 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:

FieldTypeDescription
party_uidstringUnique party identifier (e.g. '004-PAS').
partystringParty acronym (e.g. 'PAS').
coalitionstringCoalition name (e.g. 'PN'). 'ALONE' if the party contested independently.
coalition_uidstringUnique coalition identifier (e.g. '11-PN'). '0' if independent.
seats_contestedintegerNumber of seats the party contested in this election.
seats_wonintegerNumber of seats the party won.
seats_totalintegerTotal seats available in this election (the denominator for share calculations).
seats_contested_percfloatseats_contested as a percentage of seats_total.
seats_won_percfloatseats_won as a percentage of seats_total.
votesintegerTotal votes received by the party across all seats.
votes_totalintegerTotal valid votes cast in the election (the denominator for vote share).
votes_percfloatvotes 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.

GEThttps://api.electiondata.my/v1/elections/by_seat
ParameterTypeRequiredDescription
statestringYesState or aggregation scope, e.g. 'Malaysia' or 'Selangor'. Taken directly from the state field in the dropdown response.
electionstringYesElection 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:

FieldTypeDescription
seatstringConstituency identifier (e.g. 'P.001 Padang Besar, Perlis').
statestringThe state parameter echoed back.
datedatePolling day for this seat in ISO 8601 format (YYYY-MM-DD).
namestringWinner's full name.
partystringAcronym of the winning party (e.g. 'PAS').
party_uidstringUnique identifier for the winning party (e.g. '004-PAS').
coalitionstringCoalition of the winning party (e.g. 'PN'). 'ALONE' if independent.
coalition_uidintegerNumeric coalition identifier (0 if independent).
party_loststring[]Acronyms of parties that lost in this seat.
party_lost_uidstring[]Unique identifiers for the losing parties.
coalition_loststring[]Coalitions represented by the losing parties.
coalition_lost_uidinteger[]Numeric identifiers for the losing coalitions.
n_candidatesintegerTotal number of candidates who contested this seat.
voters_totalintegerTotal number of registered voters for this seat.
voter_turnoutintegerTotal votes cast, including rejected votes.
voter_turnout_percfloatTurnout as a percentage of registered voters.
majorityintegerWinning margin, i.e. winner's votes minus runner-up's votes.
majority_percfloatMajority as a percentage of total valid votes.
votes_rejectedintegerNumber of votes rejected during counting.
votes_rejected_percfloatRejected 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.

GEThttps://api.electiondata.my/v1/elections/stats
ParameterTypeRequiredDescription
statestringYesState or aggregation scope, e.g. 'Malaysia' or 'Selangor'. Taken directly from the state field in the dropdown response.
electionstringYesElection 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:

FieldTypeDescription
voters_totalintegerTotal number of registered voters across all seats in this election.
voter_turnoutintegerTotal votes cast, including rejected votes.
voter_turnout_percfloatTurnout as a percentage of registered voters.
votes_rejectedintegerTotal number of votes rejected across all seats.
votes_rejected_percfloatRejected votes as a percentage of total ballots cast.
n_candidatesintegerTotal 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.