Add your city's meetings to your website
Run a local news site, neighborhood association, library, Facebook group, or civic project? Add plain-English, always-current public-meeting updates for your community — free, under CC BY 4.0. A link back to the city's page is all we ask. Five ways, from zero-code to the full dataset:
Building an app, a newsroom tool, or a planning dashboard? Build on local government data without scraping thousands of meeting portals. Search or download structured meetings, agendas, decisions, vote tallies, source documents, and plain-English summaries from jurisdictions across the United States and Canada.
Free. No API key. Source-linked. CC BY 4.0. → full API & search reference · open dataset & schema · MCP server · every jurisdiction (JSON)
1. Embed a city — no code
Drop a single city's upcoming & recent meetings onto any page with an iframe. Every city page has an “🔗 Embed this city” box with this snippet pre-filled:
<iframe src="https://mytown.theboringparts.com/city/CITY-SLUG/embed/"
width="100%" height="600" loading="lazy"
style="border:1px solid #ddd;border-radius:8px"
title="City government meetings"></iframe>
<p>Local government meetings via <a href="https://mytown.theboringparts.com/city/CITY-SLUG/">MyTown</a></p>
Keep the credit line under the iframe — it's the CC BY attribution, and a plain text link (unlike the iframe) is what actually points search engines back to us.
Replace CITY-SLUG with your city's slug — it's the last part of its page URL
(e.g. /city/cityofpaloalto/). The widget is self-contained, mobile-responsive,
and follows the visitor's light/dark setting.
WordPress: paste the iframe into a “Custom HTML” block. Squarespace / Wix: use an Embed or Code block. You can point it at a city, a county, or a school board — whichever page's slug you use.
The city embed also carries its own “Email me new agendas” signup, so readers
can subscribe to that jurisdiction's alerts without leaving your page. Double opt-in: they get a
confirmation email, and every alert carries a one-click unsubscribe. The embed needs JavaScript, so
if you sandbox the iframe include allow-scripts allow-popups allow-forms.
2. Embed the keyword search — no code
Search every agenda, set of minutes and plain-English summary we hold, from a widget on your own page. Useful for a bill number, a vendor, a program name — anything that surfaces across many jurisdictions at once. Each result links to the jurisdiction's own source document first.
<iframe src="https://mytown.theboringparts.com/search/embed/"
width="100%" height="700" loading="lazy"
style="border:1px solid #ddd;border-radius:8px"
title="Search local government meetings"></iframe>
<p>Meeting search via <a href="https://mytown.theboringparts.com/">MyTown</a></p>
Scope and pre-fill it with URL parameters:
?q=SB+1882— run this query on load. Quote a phrase (?q=%22SB+1882%22) to require the exact wording.&state=TX— restrict to one state.&kind=school— restrict to school districts (alsocity,county).&limit=25— results per search, 1–50.&lock=1— hide the state / jurisdiction pickers so readers stay inside the scope you chose.
▶ Try it — Texas school districts that mention SB 1882.
The widget calls our search API directly from the reader's browser — no key, nothing to install. Broad one-word queries scan millions of pages and can take up to a minute; a quoted phrase or a state filter is much faster.
3. Per-city JSON API
To build your own display, fetch a city's meetings as JSON. CORS is open
(Access-Control-Allow-Origin: *), so you can call it straight from the browser.
Rebuilt hourly.
GET https://mytown.theboringparts.com/city/CITY-SLUG/meetings.json
▶ Try it — opens a live response. A shortened real example:
{
"city": "Palo Alto", "state": "California",
"page": "https://mytown.theboringparts.com/city/cityofpaloalto/",
"generated": "2026-07-17",
"upcoming": [
{ "date": "2026-07-21", "body": "City Council",
"headline": "Council to weigh $12M housing bond and downtown rezoning",
"summary": "The City Council will consider placing a $12 million affordable-housing bond ...",
"agenda_url": "https://paloalto.legistar.com/View.ashx?M=A&ID=...",
"minutes_url": null,
"source": "https://paloalto.legistar.com/Calendar.aspx" }
],
"recent": [ /* same shape, past meetings with decisions where available */ ],
"attribution": "MyTown / theboringparts.com",
"license": "CC BY 4.0"
}
Fetch it three ways — working data in under a minute:
# curl
curl -s https://mytown.theboringparts.com/city/cityofpaloalto/meetings.json
# Python
import requests
data = requests.get("https://mytown.theboringparts.com/city/cityofpaloalto/meetings.json").json()
for m in data["upcoming"]:
print(m["date"], m["body"], m["headline"])
# JavaScript (browser or Node 18+)
const data = await (await fetch("https://mytown.theboringparts.com/city/cityofpaloalto/meetings.json")).json();
data.upcoming.forEach(m => console.log(m.date, m.body, m.headline));
Response shape:
- city, state, page — the municipality and a link to its full page
- generated — build date (ISO)
- upcoming[], recent[] — meetings, each with
date,body(which board/commission),headline+summary(the plain-English brief),agenda_url,minutes_url, andsource(official portal link) - attribution, license — the credit line to show
Want the full picture for a city? city.json (same URL pattern, same open CORS)
is a superset of meetings.json — it carries the same meeting arrays plus
every data layer we show on the page:
GET https://mytown.theboringparts.com/city/CITY-SLUG/city.json
- demographics — population, income, median home value (Census / StatCan)
- home_value_trend — Zillow ZHVI: latest value, YoY & 5-yr change, monthly series
- federal_awards — USAspending grants/contracts to recipients in the city
- permits — recent building permits & business licenses from the city's own open-data feed
- campaign_finance — NetFile filing summary (full transactions in the dataset)
- decision_context — EPA-flagged facilities & nonprofits tied to specific agenda items
Any block with no data for that city is simply omitted, so check for a key
before using it. meetings.json stays a stable minimal subset — use it if all you
need is the meeting list.
4. RSS feed
Every city, county and board also publishes an RSS feed of its upcoming & recent meetings. Drop it into a news reader, a WordPress RSS block/widget, or an automation (IFTTT, Zapier) to post meeting updates to your site or group automatically.
https://mytown.theboringparts.com/city/CITY-SLUG/rss.xml
5. The whole dataset
Want the whole corpus — every city, meeting record, brief, decision and roundup we hold across the US and Canada? The entire database is one downloadable SQLite file, gaps and all. See the open dataset. The same docs live in the GitHub repo.
API stability
- Existing fields will not be removed without a version change; new fields may be added over time.
- Meeting and municipality IDs are permanent — safe to store as keys.
- Per-city JSON (
meetings.json,city.json) is rebuilt hourly; the full downloadable dataset is refreshed daily. - There is currently no authentication and no published rate limit. Please
cache responses and send a descriptive
User-Agentso we can identify high-volume applications. - Dates are ISO 8601 (
YYYY-MM-DD). Every source agenda PDF is permanently archived, so the primary document survives even if a city purges its portal. - Summaries and decisions are AI-generated from the linked primary source; treat that source as authoritative. See the dataset schema for field-level detail.
Attribution
Credit “MyTown / theboringparts.com” with a link. Summaries are AI-generated from official documents — always verify against the linked primary source before relying on a detail.