City Council & County Agenda Search avatar

City Council & County Agenda Search

Pricing

Pay per event

Go to Apify Store
City Council & County Agenda Search

City Council & County Agenda Search

Search upcoming and recent city council, county board and commission agendas for keywords or topic presets (data centers, short-term rentals, battery storage, rezoning…). Official public Legistar API, no scraping, no proxies.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Civic Data Tools

Civic Data Tools

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

8 days ago

Last modified

Share

Search public city council, county board, and commission agendas for keywords or topic presets (data centers, short-term rentals, battery storage, rezoning, RFPs…). You get one clean record per matching agenda item, with the meeting date, body, snippet, and links to the official meeting page / agenda file.

It ships two ways from the same core (src/lib.js):

InterfaceEntryUse
Apify Actor (pay-per-event)src/main.js, .actor/Apify Store, and AI agents through mcp.apify.com
MCP server (stdio)src/mcp-server.jsClaude Desktop, Cursor, and any MCP client
CLI demosrc/cli.jsLocal testing

Data sources and compliance

See sources.md for the per-city map.

SourceHow we read itScraping?
Legistar Web API (webapi.legistar.com)Official public JSONNo
CivicClerk ({host}.api.civicclerk.com)Official public OData Events + GetMeetingFileStream(…,plainText=true)No
Granicus ViewPublisher RSSOfficial agenda RSSNo (feed only)
Granicus AgendaViewer PDFPublic PDF bytes → pdf-parse (or pdftotext if installed)No HTML; official PDF
Granicus GeneratedAgendaViewer HTMLOnly if allowHtmlPublicAgenda=trueYes — labeled html-public-agenda

Honesty note: earlier versions of this actor said “no HTML scraping” because only Legistar was supported. V0.2 adds CivicClerk and Granicus. HTML parsing is off by default and gated by an input flag. Prefer JSON / ICS / RSS / official PDF text whenever a government publishes them.

Requests identify themselves with a User-Agent, run at low concurrency, and insert a short delay. Some Legistar clients need a published API token (TOKEN_REQUIRED); pass tokens: {"<slug>": "<token>"} if you have one.

Jurisdiction directory

data/jurisdictions.json holds Legistar cities/counties plus Tri-Valley CivicClerk and Granicus entries. Rebuild Legistar candidates with node scripts/build-directory.mjs. You can still search any other Legistar client with "legistar:<slug>", or any CivicClerk host with "civicclerk:<host>" (e.g. civicclerk:sanramonca).

Tri-Valley additions (2026-10-05): San Ramon, Pleasanton (CivicClerk); Dublin, Livermore, Danville (Granicus); Contra Costa County slug contra-costa; BART; MTC.

Bay Area + LA Legistar expansion (2026-10-05): Cupertino, Sunnyvale (sunnyvaleca), Emeryville, Hercules, Napa; Los Angeles County (lacounty), Manhattan Beach, Pomona, Redondo Beach (redondo); Fullerton, Newport Beach, Costa Mesa, Westminster (westminsterca). See sources.md.

Input (Actor and MCP)

{
"keywords": ["data center"],
"topics": ["data-centers"],
"jurisdictions": ["San Ramon, CA", "Dublin, CA", "legistar:seattle"],
"states": ["CA"],
"daysBack": 14, "daysAhead": 30,
"matchMode": "any",
"bodyFilter": "Planning",
"maxMeetingsPerJurisdiction": 40, "maxResults": 200,
"allowHtmlPublicAgenda": false
}

allowHtmlPublicAgenda: when true, parse public Granicus HTML agendas (Danville and similar). Matches include sourceMode: "html-public-agenda". Default false → RSS title/description only for HTML-only cities, with an HTML_GATED error explaining the gap.

Output

Same shape as before (demo/actor-sample-item.json), plus:

  • platform: legistar | civicclerk | granicus
  • sourceMode (Granicus): rss-only | pdf | html-public-agenda

Source problems never crash the run. They appear in OUTPUT.errors (UNRESOLVED_JURISDICTION, TOKEN_REQUIRED, SOURCE_ERROR, HTML_GATED, PDF_TOOL_MISSING).

Pay-per-event charging (Actor)

Unchanged pricing model (do not alter Store prices in this update):

  • agenda-item-match (primary): per matching item
  • meeting-scanned: per meeting whose agenda was fetched and searched
  • Keep apify-actor-start; remove apify-default-dataset-item in Console so items aren't double-charged

Run it

npm install
npm test # offline unit tests (mocked APIs)
LIVE=1 npm test # also live API + MCP round trip
npm run demo # CA data-center scan
npm run demo:trivalley # CivicClerk + Granicus smoke
npm start # Actor locally (INPUT.json in storage/)

MCP tools: search_meeting_agendas, list_jurisdictions, list_topic_presets.

Known limits

  • PDF full-text inside attached staff reports is not OCR'd beyond Granicus AgendaViewer PDFs and CivicClerk plainText streams.
  • School boards (BoardDocs) and some PrimeGov/eScribe cities remain out until a compliant public feed exists — see sources.md.
  • Legistar / CivicClerk / Granicus data quality varies; agendas can post late.

Same publisher (civic-data-tools) — useful together for agents monitoring local government:

ActorUse whenStore
Public Bid & RFP SearchOpen government bids/RFPs plus new federal contract awards (official APIs)public-bid-search
Multi-City Building PermitsNormalized building permits from large US city open-data portalsbuilding-permits

This Actor covers meeting agendas. Pair bid search when an agenda item mentions an RFP, and permits when land-use items move into construction.