PrimeGov public meetings

Public data

Ready to useNo account needed

PrimeGov public meetings data, published as PrimeGov public meetings publishes it. Ingest delivers this data to a data warehouse you own as 4 tables, and updates it on the schedule you choose. There is no code to write and nothing to install.

What you get

TableEach row is
meeting_document_text
meeting_document_text
The full text of each meeting's minutes and final actions, read from their PDFs: one row per document, with `text`, `pages` and `document_bytes`. `_ingest_parent_key` is the document's `template_id` in `meeting_documents`, whose `template_name` says which of the two it is. Cambridge's City Council minutes are a verbatim transcript, each speaker named in capitals before their words; its final actions list every item the council took up, with each vote's result and the councillors voting yes and no. The pages of `text` are separated by a form feed, so page N is the N-th part when it is split on one. A document is read once, and again only when the city publishes it again (a new `publish_date`). One whose text cannot be read, such as a scan or a password-protected file, has a null `text` and an `unread_reason` saying why. A document the city takes down keeps its row here, so join to `meeting_documents` for the current list.
meeting_documents
meeting_documents
One row per document a meeting published: its `template_name` (Agenda, Packet, Minutes, Final Actions and their HTML versions), `compile_output_type` (1 a PDF, 3 HTML), `publish_date`, and `meeting_id`, which joins to `meetings`. `template_id` addresses the document and joins to `meeting_document_text`.
meeting_video_transcripts
meeting_video_transcripts
The transcript of each meeting's archived video, from Swagit: one row per video, with `text` and `document_bytes`. `_ingest_parent_key` is the meeting's `swagit_id` in `meetings`, `videos/` and a number. Swagit makes it by voice-to-text: in capitals, a timestamp every five minutes and no speaker names, and it says the transcript is unedited and not the official record, which the minutes are. A live event's page has no transcript and is not read. Each transcript is read again every 14 days, since a video's captions can change after its meeting. A video the portal lists and Swagit does not have lands with no `text` and an `unread_reason` saying so, and is asked for again every run. A transcript already here keeps its text if Swagit stops answering for it, and is asked for again every run until it does.
meetings
meetings
One row per meeting: its `title` (the body that met, such as Regular City Council Meeting or Planning Board Meeting), `date_time`, `video_url` and state. The documents it published are in `meeting_documents`, joined on `meeting_id`. Each year is read whole, from 2025 to the current year.

How it works

  1. Choose PrimeGov public meetings. The data is public, so there is nothing to sign in to.
  2. Pick where it goes. BigQuery, Snowflake, Databricks, Redshift and 11 more, in an account you own.
  3. Pick a schedule. Daily is the default, and weekly and monthly are there too.
  4. Ingest runs it from then on. If a run fails, your dashboard shows which table and why.

Questions

Do I need an account with PrimeGov public meetings?
No. The data is public, so there is nothing to sign up for and nothing to paste in.
Which warehouses can PrimeGov public meetings data go to?
Amazon S3, Google Cloud Storage, Azure Blob Storage, Apache Iceberg, Ingest Managed Lakehouse, MotherDuck, Postgres, Amazon Athena, Databricks, Redshift, BigQuery, ClickHouse, ObsessionDB, MySQL / generic SQL and Snowflake, in an account you own.
How fresh is the data?
As fresh as your schedule: daily by default, or weekly or monthly. Schedules as often as every 20 minutes are on the Enterprise plan.
Will running it again create duplicate rows?
No. Each row is stored once, by its key: when a run reads a row that is already there, it replaces that copy instead of adding a second one.
Do I need to write code?
No. Ingest builds, runs and maintains the connector. Someone with access to your warehouse connects it once, following a short guide.
For your data team: technical reference

Connector primegov, version 0.1.0, a REST source, status beta, authentication none.

Vendor documentation: https://cambridgema.primegov.com/public/portal

Configuration

KeyLabelTypeRequired
siteYour PrimeGov portalstringyes
video_siteYour Swagit video archivestringyes

Resources

ResourceStatusPlanWritePrimary keyOverrides
meeting_document_text
The full text of each meeting's minutes and final actions, read from their PDFs: one row per document, with `text`, `pages` and `document_bytes`. `_ingest_parent_key` is the document's `template_id` in `meeting_documents`, whose `template_name` says which of the two it is. Cambridge's City Council minutes are a verbatim transcript, each speaker named in capitals before their words; its final actions list every item the council took up, with each vote's result and the councillors voting yes and no. The pages of `text` are separated by a form feed, so page N is the N-th part when it is split on one. A document is read once, and again only when the city publishes it again (a new `publish_date`). One whose text cannot be read, such as a scan or a password-protected file, has a null `text` and an `unread_reason` saying why. A document the city takes down keeps its row here, so join to `meeting_documents` for the current list.
betaparent_childmerge_ingest_parent_key-
meeting_documents
One row per document a meeting published: its `template_name` (Agenda, Packet, Minutes, Final Actions and their HTML versions), `compile_output_type` (1 a PDF, 3 HTML), `publish_date`, and `meeting_id`, which joins to `meetings`. `template_id` addresses the document and joins to `meeting_document_text`.
betafullreplaceid-
meeting_video_transcripts
The transcript of each meeting's archived video, from Swagit: one row per video, with `text` and `document_bytes`. `_ingest_parent_key` is the meeting's `swagit_id` in `meetings`, `videos/` and a number. Swagit makes it by voice-to-text: in capitals, a timestamp every five minutes and no speaker names, and it says the transcript is unedited and not the official record, which the minutes are. A live event's page has no transcript and is not read. Each transcript is read again every 14 days, since a video's captions can change after its meeting. A video the portal lists and Swagit does not have lands with no `text` and an `unread_reason` saying so, and is asked for again every run. A transcript already here keeps its text if Swagit stops answering for it, and is asked for again every run until it does.
betaparent_childmerge_ingest_parent_key-
meetings
One row per meeting: its `title` (the body that met, such as Regular City Council Meeting or Planning Board Meeting), `date_time`, `video_url` and state. The documents it published are in `meeting_documents`, joined on `meeting_id`. Each year is read whole, from 2025 to the current year.
betafullreplaceid-

Setting up the destination is its own short guide, one per warehouse or lake: Amazon S3, Google Cloud Storage, Azure Blob Storage, Apache Iceberg, Ingest Managed Lakehouse, MotherDuck, Postgres, Amazon Athena, Databricks, Redshift, BigQuery, ClickHouse, ObsessionDB, MySQL / generic SQL, Snowflake.

Other sources Ingest connects for government teams: Abilene TX 311, Albany NY 311, Ann Arbor MI 311, Anne Arundel County MD 311, Auburn WA 311, Aurora IL 311.

Get PrimeGov public meetings data into your warehouse

Last updated .