Oakland
Menu

Data & downloads

7 CSV files behind Oakland’s pages, plus two five-city files, with what each column means. Data as of Oct 9, 2026 (version 2ea162c); meetings Oct 24, 2025 – Oct 8, 2026.

Reading the files. The first line of each file starts with # and names the city, the data date, the data version and the window; read it as a comment (pandas comment="#", R comment.char = "#") or skip one line. The saved file’s name carries the same date and version, for example oakland-meetings-2026-10-09-2ea162c.csv, so a citation can name the exact version. Counts, minutes and shares are as the pages print them before rounding.

What isn’t here. Public commenters are never named in any file: they are counted, not listed. Full transcripts aren’t published because they can carry private people’s names. School-board meetings are in meetings.csv, marked school_board, because the city’s counts include them; who spoke at them is on our school-board site. Withheld until they clear our accuracy bar: rising topics. What is and isn’t transcribed is on How we count; the checks behind each number are on Accuracy checks.

Topic time · topics.csv

Download topics.csv (47 rows)

One row: One topic in one cut (citywide, or one body), plus three unranked rows per cut: routine, unsure and held. In San Francisco and Oakland, time comes from the clerk's agenda times (which cover meetings we haven't read); elsewhere, from stretches of transcript two AI readers labelled. Shares are of that timed speech, not of the whole video.

ColumnWhat it holdsUnitsOut of
cut_idThe cut: city for citywide, else the body's id.id
cutThe cut's name.text
rankRank among the cut's ranked topics. A topic's rank counts only topics clearly above it.integer; empty on unranked rows
tiedTrue when the topic's 90% range overlaps a neighbour's, so the rank is shared.true/false
topicTopic key, or routine, unsure or held.id
labelTopic name as the pages print it.text
shareThe topic's minutes as a share of all the cut's timed minutes.0 to 1every timed minute of the cut's meetings, the routine, unsure and held rows included
loLow end of the 90% range for share, from resampling whole meetings.0 to 1
hiHigh end of that range.0 to 1
minutesTimed minutes on the topic.minutes
meetingsMeetings (one body on one day) with any timed minutes on the topic.count

Talk time · talk.csv

Download talk.csv (8 rows)

One row: One member of the council (or board) the city's ranking covers. Minutes are speech we named by voice, so every figure undercounts what a member said. Ranked only when the body clears our naming bar (/how).

ColumnWhat it holdsUnitsOut of
bodyThe body ranked.text
personThe member.name
seatSeat or district.text
presidesTrue for the body's chair, who runs the meeting and is shown apart, not ranked.true/false
rank_rangeRank range, e.g. 1st–8th: overlapping ranges share ranks.text
tiedTrue when the rank is shared with a neighbour inside the margin.true/false
minutes_per_meetingNamed minutes divided by meetings held while seated.minutes per meetingmeetings_held
loLow end of the 90% range for minutes per meeting (resampled meetings; method on /how).minutes per meeting
hiHigh end of that range, which allows for member speech we couldn't name.minutes per meeting
meetings_countedMeetings where we named the member's voice at least once.count
meetings_heldMeetings of the body read while the member was seated.count
reasonWhy the row has no rank, when it has none.text

People · people.csv

Download people.csv (96 rows)

One row: One official on one council, committee, commission or board: every official on the People page, one row for each body they sit on (school-board members are on the school-board site).

ColumnWhat it holdsUnitsOut of
personThe official.name
seatSeat or district.text
roleTheir role on this body, as the roster gives it (President, Chair, Member).text
bodyThe body.text
presidesTrue when they chair this body.true/false
meetings_namedMeetings of this body where we named their voice.count
meetings_heldMeetings of this body held while they were seated (0 when term dates are unknown).count
minutes_namedMinutes of their speech we named by voice, not all they said: a floor, not a ranking (a body whose ranking is held still shows each member's named minutes).minutes

Bodies · bodies.csv

Download bodies.csv (18 rows)

One row: One public body we follow. Meeting counts here are listed meetings, transcribed or not; meetings.csv says which were transcribed.

ColumnWhat it holdsUnitsOut of
idBody id.id
nameThe body's name, as the city lists it.text
groupLegislative, Land use, Money, Safety, Schools or Other.text
meetingsListed meetings in the window (one body on one day), transcribed or not.count
hoursHours of meeting video; empty when we know too few lengths.hours
meetings_per_monthListed meetings per month of the window.meetings per month
newestNewest listed meeting.date (YYYY-MM-DD)
newest_urlThat meeting's video.URL
top_topicsTop topics as "label share", separated by semicolons.0 to 1 per topicthe body's itemised minutes

Accuracy ledger · checks.csv

Download checks.csv (50 rows)

One row: One of the 50 questions on the ledger page.

ColumnWhat it holdsUnitsOut of
idQuestion number.Q01 to Q50
areaCoverage, Meetings, Time, Topics, Talk or Display.text
questionThe question.text
answerThe answer, computed from the data.text
statuspass, fail (a problem the page works around), held (feature withheld) or n/a.text
effectWhat the pages do because of it.text

Meetings · meetings.csv

Download meetings.csv (244 rows)

One row: One listed meeting: one body on one day, transcribed or not. Every meeting the city's counts include, school boards and their committees too: the rows marked read = yes add up to the meetings read on the city page, and the body_id values to its public bodies. School-board meetings are marked school_board = yes; who spoke at them is on our school-board site, not in speakers.csv.

ColumnWhat it holdsUnitsOut of
body_idBody id.id
bodyThe body.text
school_boardyes for a school board or one of its committees, whose pages are on our school-board site.yes/no
dateMeeting date, from the clerk's video listing.date (YYYY-MM-DD)
page_urlThe meeting's page on this site; for a school-board meeting, the district's page on our school-board site.URL; empty for a school board held off Hamlet
video_urlThe government's own video of the meeting.URL
video_hostWhere the video is hosted: granicus, youtube, viebit, vimeo, swagit or audio.text
recordingsVideos that make up the meeting (a recess can split one).count
length_sLength; empty when not known or held.seconds
length_kindvideo: the full recording; at_least: first word to last word, so a floor; unknown.text
readyes when we have a transcript; only read meetings count toward talk time, issues and quotes.yes/no
why_unreadafter_read_through: newer than the city's newest meeting read; not_transcribed: a meeting on or before that date that we hold the video of but haven't transcribed yet. We don't record a cause per meeting; video_host shows where the gaps cluster.text; empty when read
officials_namedOfficials whose voice we named in this meeting.count; empty when unread
minutes_namedTheir named minutes, summed.minutes; empty when unreadspeech we named by voice, not the meeting's length

Officials' talk time · speakers.csv

Download speakers.csv (783 rows)

One row: One official in one transcribed meeting. Officials only: no member of the public is in this file. The same rows as each meeting page's "Who spoke" list. Minutes undercount what was said: a voice we couldn't name is in no row.

ColumnWhat it holdsUnitsOut of
person_idThe official's id, as in their page URL (/people/<id>).id
personThe official.name
body_idBody id.id
bodyThe body.text
dateMeeting date.date (YYYY-MM-DD)
page_urlThe meeting's page.URL
recordingWhich of the meeting's videos first_s is in.1-based index
minutes_namedMinutes of their speech we named in this meeting.minutes
first_sSecond of their first named remark; empty when it falls in the first 5 seconds (the start of the video).seconds from the start of the recording
first_video_urlThe video at that second, where the host allows a cue.URL

Across the five cities

The same two files on every city’s Data page and on the findings.

Findings, five cities · findings.csv

Download findings.csv (203 rows)

One row: One number behind one finding on /findings: a bar, a point on a line, or a total. Only findings the page publishes (each with a clip to play). Counts are of meetings we transcribed, one body on one day, where the topic was mentioned at least once, by anyone.

ColumnWhat it holdsUnitsOut of
finding_idThe finding's id, as in its page anchor (/findings#<id>).id
titleThe finding's headline as the page prints it.text
page_urlThe finding on /findings.URL
serieschart: the bars or points the page draws; total: the finding's own totals; any other value names a breakdown in the data (by_city, quarters, la_quarters, la_months).text
labelThe bar or point: a city, a quarter, a month (YYYY-MM), a date or a meeting; empty for a total.text
dateThe meeting's date, where the row is one meeting.date (YYYY-MM-DD)
measureWhat value counts: meetings (meetings where it came up), rats_meetings or pothole_meetings, hours, minutes, slot_minutes, clock_minutes (adjournment, minutes after midnight), or a total's own name.text
valueThe number, before rounding.as measure says
ofThe meetings a meeting count is out of; empty where the value isn't a share of meetings.count
sharevalue divided by of, as the chart draws it.0 to 1of
windowThe meetings counted: that city's own dates for a city row, else the span across the cities.text

City signatures · signatures.csv

Download signatures.csv (5 rows)

One row: One city's signature: the topic its city hall brings up that the other four don't, as its hub and the front page draw it. A signature shows only when its source is a checked finding or story and the city's 90% range clears every other city's; a city with none has no row.

ColumnWhat it holdsUnitsOut of
cityThe city.text
topicThe topic.text
source_idThe finding (/findings#<id>) or story it comes from.id
page_urlWhere the source and its chart are.URL
meetingsThis city's meetings where the topic came up.countof
ofThis city's meetings we transcribed in the window.count
othersThe other four cities' meetings where it came up.countothers_of
others_ofThe other four cities' meetings we transcribed.count
check_correctSpot-checked mentions that were about the topic.countcheck_n
check_nMentions read in context, picked at random.count
windowThe span of the five cities' meetings counted; empty when the source gives none (the page then prints the data date).text
Cite this page

Hamlet, “Data & downloads: Oakland.” https://cities.myhamlet.com/oakland/data. Data as of Oct 9, 2026 (version 2ea162c); meetings Oct 24, 2025 – Oct 8, 2026.