Canadian parliamentary vote intelligence: party cohesion and controversy
Monthly intelligence panel of every recorded division in the 45th Parliament, 1st session, from the keyless openparliament.ca API (a volunteer mirror of official House of Commons data): vote tallies, per-party Yes/No positions with intra-party disagreement rates, turnout against 343 seats, and a documented 0-100 controversy score (closeness of the division, caucus dissent, party split) ranked as controversy_rank. Flags identify unanimous votes, Liberal/Conservative splits, cross-partisan alignment, caucus dissent, and suspected free votes (>=1% mean disagreement, a heuristic). Caveats: disagreement rates are computed by openparliament from official division lists; paired votes are excluded from margins; only recorded divisions appear (no voice votes); bill titles are a best-effort parse of the procedural description. Underlying material is House of Commons parliamentary data mirrored by openparliament.ca, which holds no copyright on API data and requests link-back attribution; commercial_use=unclear.
- Rows
- 174
- Columns
- 44
- Source cadence
- Monthly
- Last refreshed
- Sep 26, 2026
- Theme
- government
| Column | Type | Description |
|---|---|---|
| vote_id | string | Stable vote identifier: '<session>/<division number>', e.g. '45-1/174'. Primary key. |
| session | string | Parliamentary session covered by the panel (45-1). |
| vote_number | integer | Division number within the session (order of occurrence). |
| vote_date | string | Date the division was held (ISO date). (unit: ISO date) |
| country_code | string | ISO alpha-3 country code (CAN for every row). (unit: ISO 3166-1 alpha-3) |
| description_en | string | Short procedural description of the vote in English, verbatim from openparliament (e.g. '2nd reading of Bill C-266, ...'). |
| description_fr | string | Short procedural description of the vote in French, verbatim from openparliament. |
| bill_number | string | Bill number parsed from the vote's bill_url (e.g. 'C-266'); null for procedural votes with no associated bill. |
| bill_title_en | string | Best-effort bill title parsed from the English description (text after the bill reference); null for procedural votes. |
| result | string | Official division outcome: Passed, Failed, or Tie. |
| yea_total | integer | Recorded votes in favour. |
| nay_total | integer | Recorded votes against. |
| paired_total | integer | Paired votes (MPs absent by mutual agreement; excluded from the yea/nay margin). |
| total_ballots | integer | yea_total + nay_total + paired_total. |
| margin_votes | integer | Absolute vote margin |yea - nay|. |
| margin_pct | float | 100 * margin_votes / (yea + nay); null when no yea/nay votes were cast. (unit: percent) |
| turnout_pct | float | 100 * total_ballots / 343 (the 45th Parliament has 343 seats). (unit: percent) |
| conservative_vote | string | Conservative caucus position: 'yes', 'no', 'didnt_vote' (coordinated caucus abstention), or null when the party did not vote as a recognized bloc on this division. |
| conservative_disagreement | float | Fraction of Conservative MPs who voted against the caucus position (0 = full discipline), as computed by openparliament. (unit: fraction) |
| liberal_vote | string | Liberal caucus position: 'yes', 'no', 'didnt_vote', or null. |
| liberal_disagreement | float | Fraction of Liberal MPs voting against the caucus position. (unit: fraction) |
| bloc_vote | string | Bloc Québécois caucus position: 'yes', 'no', 'didnt_vote', or null. |
| bloc_disagreement | float | Fraction of Bloc MPs voting against the caucus position. (unit: fraction) |
| ndp_vote | string | NDP caucus position: 'yes', 'no', 'didnt_vote', or null. |
| ndp_disagreement | float | Fraction of NDP MPs voting against the caucus position. (unit: fraction) |
| green_vote | string | Green caucus position: 'yes', 'no', 'didnt_vote', or null. |
| green_disagreement | float | Fraction of Green MPs voting against the caucus position. (unit: fraction) |
| unmapped_parties | string | Semicolon-joined 'label:vote:disagreement' entries for any party label upstream that is not one of the five recognized parties; empty string when none. |
| n_parties_yes | integer | Recognized parties voting yes. |
| n_parties_no | integer | Recognized parties voting no. |
| n_parties_abstain | integer | Recognized parties whose whole caucus abstained ('didnt_vote' position); excluded from the yes/no counts. |
| n_dissenting_parties | integer | Recognized parties with disagreement > 0 on this division. |
| max_disagreement | float | Largest intra-party disagreement fraction on this division. (unit: fraction) |
| max_disagreement_party | string | Column prefix of the party with the largest disagreement (null when every party voted with full discipline). |
| mean_disagreement | float | Mean intra-party disagreement across recognized parties present on this division. (unit: fraction) |
| unanimous_flag | boolean | True when every recognized party voted the same way and none abstained as a caucus. |
| lib_con_split_flag | boolean | True when the Liberal and Conservative caucuses voted opposite ways (the classic government/opposition divide). |
| cross_partisan_flag | boolean | True when the Liberal and Conservative caucuses voted the same way. |
| dissent_flag | boolean | True when any recognized party had intra-party disagreement > 0 on this division. |
| free_vote_suspect_flag | boolean | Heuristic only: true when mean_disagreement >= 0.01. openparliament does not publish whip designations, so this is an inference, not an official label. |
| controversy_score | float | 0-100 controversy score = 100 * (0.45 * closeness + 0.35 * max_disagreement + 0.20 * party_split), where closeness = 1 - |yea-nay|/(yea+nay), and party_split = min(n_yes, n_no)/n_parties. 0 = unanimous whipped vote; ~100 = tied division with caucus dissent and an even party split. (unit: 0-100 score) |
| controversy_rank | integer | Rank of controversy_score (1 = most controversial; deterministic tie-break: vote_date desc, vote_number desc). |
| provenance_url | string | openparliament.ca URL of this division's vote page. |
| row_hash | string | Deterministic 16-hex-char row hash over vote_id, date, tallies and per-party positions/disagreement (idempotency). |
First 10 sample rows — a preview, not the complete dataset.
| vote_id | session | vote_number | vote_date | country_code | description_en | description_fr | bill_number | bill_title_en | result | yea_total | nay_total | paired_total | total_ballots | margin_votes | margin_pct | turnout_pct | conservative_vote | conservative_disagreement | liberal_vote | liberal_disagreement | bloc_vote | bloc_disagreement | ndp_vote | ndp_disagreement | green_vote | green_disagreement | unmapped_parties | n_parties_yes | n_parties_no | n_parties_abstain | n_dissenting_parties | max_disagreement | max_disagreement_party | mean_disagreement | unanimous_flag | lib_con_split_flag | cross_partisan_flag | dissent_flag | free_vote_suspect_flag | controversy_score | controversy_rank | provenance_url | row_hash |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 45-1/1 | 45-1 | 1 | 2025-05-29 | CAN | Address in Reply to the Speech from the Throne (subamendment) | Adresse en réponse au discours du Trône (sous-amendement) | — | — | Passed | 337 | 0 | 0 | 337 | 337 | 100 | 98.25 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | — | 5 | 0 | 0 | 0 | 0 | — | 0 | true | false | true | false | false | 0 | 174 | https://openparliament.ca/votes/45-1/1/ | ad8032b051e5b3d3 |
| 45-1/2 | 45-1 | 2 | 2025-06-02 | CAN | Address in Reply to the Speech from the Throne (subamendment) | Adresse en réponse au discours du Trône (sous-amendement) | — | — | Passed | 331 | 0 | 8 | 339 | 331 | 100 | 98.83 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | — | 5 | 0 | 0 | 0 | 0 | — | 0 | true | false | true | false | false | 0 | 173 | https://openparliament.ca/votes/45-1/2/ | 44028cbb8bb364d9 |
| 45-1/3 | 45-1 | 3 | 2025-06-02 | CAN | Address in Reply to the Speech from the Throne (amendment as amended with subamendment) | Adresse en réponse au discours du Trône (amendement tel que modifié avec sous-amendement) | — | — | Passed | 166 | 164 | 8 | 338 | 2 | 0.606 | 98.54 | yes | 0 | no | 0.006 | yes | 0 | yes | 0 | yes | 0 | — | 4 | 1 | 0 | 1 | 0.006 | liberal | 0.001 | false | true | false | true | false | 48.94 | 33 | https://openparliament.ca/votes/45-1/3/ | d8d8c949e627422f |
| 45-1/4 | 45-1 | 4 | 2025-06-05 | CAN | Ways and means motion No. 1 | Motion des voies et moyens no 1 | — | — | Passed | 333 | 0 | 8 | 341 | 333 | 100 | 99.42 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | — | 5 | 0 | 0 | 0 | 0 | — | 0 | true | false | true | false | false | 0 | 172 | https://openparliament.ca/votes/45-1/4/ | f6b68cea7a2832b6 |
| 45-1/5 | 45-1 | 5 | 2025-06-10 | CAN | Opposition Motion (Food inflation and budgetary policy) | Motion de l’opposition (Inflation alimentaire et politiques budgétaires) | — | — | Failed | 162 | 174 | 4 | 340 | 12 | 3.571 | 99.13 | yes | 0 | no | 0 | yes | 0 | no | 0 | no | 0 | — | 2 | 3 | 0 | 0 | 0 | — | 0 | false | true | false | false | false | 51.39 | 12 | https://openparliament.ca/votes/45-1/5/ | 851153327a85a56c |
| 45-1/6 | 45-1 | 6 | 2025-06-11 | CAN | Opposition Motion (Canada carbon rebate and payment to Quebec) (amendment) | Motion de l’opposition (Remise canadienne sur le carbone et indemnité au Québec) (amendement) | — | — | Failed | 30 | 310 | 2 | 342 | 280 | 82.353 | 99.71 | no | 0 | no | 0 | yes | 0 | yes | 0 | yes | 0 | — | 3 | 2 | 0 | 0 | 0 | — | 0 | false | false | true | false | false | 15.94 | 141 | https://openparliament.ca/votes/45-1/6/ | 2e9a84ed8954e5fd |
| 45-1/7 | 45-1 | 7 | 2025-06-11 | CAN | Opposition Motion (Canada carbon rebate and payment to Quebec) | Motion de l’opposition (Remise canadienne sur le carbone et indemnité au Québec) | — | — | Failed | 30 | 308 | 2 | 340 | 278 | 82.249 | 99.13 | no | 0 | no | 0 | yes | 0 | yes | 0 | yes | 0 | — | 3 | 2 | 0 | 0 | 0 | — | 0 | false | false | true | false | false | 15.99 | 140 | https://openparliament.ca/votes/45-1/7/ | dc414916a6697a5b |
| 45-1/8 | 45-1 | 8 | 2025-06-12 | CAN | 2nd reading of Bill C-4, An Act respecting certain affordability measures for Canadians and another measure | 2e lecture du projet de loi C-4, Loi concernant certaines mesures d'abordabilité pour les Canadiens et une autre mesure | C-4 | An Act respecting certain affordability measures for Canadians and another measure | Passed | 335 | 0 | 6 | 341 | 335 | 100 | 99.42 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | yes | 0 | — | 5 | 0 | 0 | 0 | 0 | — | 0 | true | false | true | false | false | 0 | 171 | https://openparliament.ca/votes/45-1/8/ | 06cdbbb4dfacd354 |
| 45-1/9 | 45-1 | 9 | 2025-06-16 | CAN | Motion for closure | Motion de clôture | — | — | Passed | 307 | 29 | 4 | 340 | 278 | 82.738 | 99.13 | yes | 0 | yes | 0 | no | 0 | no | 0 | no | 0 | — | 2 | 3 | 0 | 0 | 0 | — | 0 | false | false | true | false | false | 15.77 | 144 | https://openparliament.ca/votes/45-1/9/ | 53134173578400d6 |
| 45-1/10 | 45-1 | 10 | 2025-06-16 | CAN | Opposition Motion (GCStrategies Inc.) | Motion de l’opposition (GCStrategies Inc.) | — | — | Passed | 172 | 166 | 4 | 342 | 6 | 1.775 | 99.71 | yes | 0 | no | 0 | yes | 0 | yes | 0 | yes | 0 | — | 4 | 1 | 0 | 0 | 0 | — | 0 | false | true | false | false | false | 48.2 | 46 | https://openparliament.ca/votes/45-1/10/ | 429b76e9e0956a57 |
- Current
20260926T132336Z-278875fad0f0 · sha256 278875fad0f0…
174 rows · first snapshot
Point any LLM at the metadata endpoint — the documentation above is machine-readable too (JSON-LD + Croissant).
curl "https://datazimuts.com/v1/datasets/openparliament_signals/ca_parliament_vote_intel" | jq '{title, rows, columns_count, license}'import requests
ds = requests.get("https://datazimuts.com/v1/datasets/openparliament_signals/ca_parliament_vote_intel").json()
print(ds["title"], ds["rows"], "rows")
# Sample rows for an LLM context window
for row in ds.get("sample_rows", [])[:5]:
print(row)API endpoint: https://datazimuts.com/v1/datasets/openparliament_signals/ca_parliament_vote_intel
Tip: fetch /llms.txt for the full machine-readable catalog.
Where this data comes from and what was made from it. Other people's work shows as counts; only shared projects are named.
Cite this snapshot
Pinned to snapshot 20260926T132336Z-278875fad0f0 and its content hash, so readers get exactly the data you used.
openparliament.ca (House of Commons data mirror). (2026). Canadian parliamentary vote intelligence: party cohesion and controversy [Data set, snapshot 20260926T132336Z-278875fad0f0, sha256 278875fad0f0]. Datazimuts. Retrieved 2026-09-26, from https://datazimuts.com/en/datasets/openparliament_signals/ca_parliament_vote_intel?snapshot=20260926T132336Z-278875fad0f0
@misc{dz_openparliament_signals_ca_parliament_vot_278875fa,
title = {{Canadian parliamentary vote intelligence: party cohesion and controversy}},
author = {{openparliament.ca (House of Commons data mirror)}},
year = {2026},
publisher = {Datazimuts},
howpublished = {\url{https://datazimuts.com/en/datasets/openparliament_signals/ca_parliament_vote_intel?snapshot=20260926T132336Z-278875fad0f0}},
note = {Snapshot 20260926T132336Z-278875fad0f0, sha256 278875fad0f04aba1d3628be8a30ab6c89162cc1edb4233bba8a3b4fcf9b358d; accessed 2026-09-26}
}Embed a table or a chart
Paste this into any page. The embed is pinned to the same snapshot, follows the reader's light or dark setting, and always shows the source, license and a link back.
<iframe src="https://datazimuts.com/embed/chart?dataset=openparliament_signals%2Fca_parliament_vote_intel&lang=en&theme=auto&snapshot=20260926T132336Z-278875fad0f0&x=vote_date&y=vote_number&agg=avg" title="Canadian parliamentary vote intelligence: party cohesion and controversy" width="100%" height="380" style="border:0" loading="lazy"></iframe>
Ask about this dataset. Answers come only from its catalog record, measured profile and change history, and list the facts they used.