Municipal Legislation API
Ten endpoints for municipal legislative data from any Legistar-powered US city or county -- legislation, meetings, officials, staff details, committees, attachments, sponsors, legislative history and agenda items. One API key replaces navigating per-city Legistar portals and parsing OData. No competitor in the unified-API space sells normalized Legistar data.
Bootstrap plan and above. 1 credit per request.
{ "data": { "results": [ { "id": 2851, "file": "Res 31609", "title": "A RESOLUTION declaring the City Council's intent to consider strategies to increase the availability of affordable housing in The City of Seattle.", "typeId": 52, "typeName": "Resolution (Res)", "statusId": 95, "statusName": "Adopted", "bodyId": 169, "bodyName": "City Clerk", "introDate": "2015-08-12T00:00:00", "agendaDate": "2015-09-28T00:00:00", "passedDate": "2015-09-28T00:00:00", "requester": "Legislative Department", "version": "1", "text2": "[email protected]", "lastModifiedUtc": "2021-09-29T16:12:11.987" } ], "count": 1, "page": 1, "per_page": 20, "has_more": false }, "response_time": 842, "credits_used": 1, "credits_remaining": 4999}A real captured response from the matters endpoint. Requires Bootstrap plan or above.
What is the Scavio Legistar API?
The Scavio Legistar API is a REST API that normalizes public legislative data from 1,800+ US municipalities behind one key and one JSON shape. You POST a city slug and your query to one of ten endpoints and get back legislation, meetings, officials, staff contact details with committee roles, attachments, sponsors, legislative history, agenda items, or agency validation -- all as clean camelCase JSON instead of raw OData. Invalid agency IDs return actionable error messages instead of opaque upstream failures.
- 1,800+
- US municipalities, one API key
- 10
- endpoints, all 1 credit per call
- 0
- competitors selling normalized Legistar data
Start with these four
They cover most of what people build with municipal legislative data. All ten endpoints are in the table below.
Legislation search
POST /api/v1/legistar/mattersSearch ordinances, resolutions and motions across 1,800+ municipalities by keyword, type, status and date -- with pagination and normalized camelCase JSON instead of raw OData.
Meeting calendar
POST /api/v1/legistar/eventsCouncil meetings, public hearings and committee sessions by body and date range -- location, media links, agenda status and linked legislation in one call.
Staff details
POST /api/v1/legistar/staff-detailsFull contact info, title, every committee membership, role and term dates for any official -- a composite endpoint that joins two Legistar tables in one call.
Officials directory
POST /api/v1/legistar/personsElected officials and staff for any municipality: name, contact details and active status, without navigating per-city Legistar portals.
All 10 Legistar endpoints
Every route is a POST, returns JSON, and takes the same API key. Each call costs 1 credit. Requires Bootstrap plan or above.
| Endpoint | Returns | Credits |
|---|---|---|
Matters/api/v1/legistar/matters | Legislation search: ordinances, resolutions, motions by keyword, type, status, date with pagination | 1 |
Events/api/v1/legistar/events | Council meetings, hearings, committee sessions by body, date range with location, media links, agenda status | 1 |
Persons/api/v1/legistar/persons | Elected officials and staff: name, contact, active status for any municipality | 1 |
Bodies/api/v1/legistar/bodies | Committees, councils, boards: type, member count, active status, contact | 1 |
Staff details/api/v1/legistar/staff-details | Composite: single official's contact info (address, phone, email, website) plus all committee roles and term dates in one call | 1 |
Matter attachments/api/v1/legistar/matter/attachments | Documents attached to legislation: fiscal notes, signed ordinances, supporting materials with download links | 1 |
Matter sponsors/api/v1/legistar/matter/sponsors | Authors and co-sponsors of a piece of legislation | 1 |
Matter history/api/v1/legistar/matter/history | Legislative action trail: committee referrals, votes, council passage, mayoral signature with mover/seconder | 1 |
Event items/api/v1/legistar/event/items | Meeting agenda: items, actions, motions, linked legislation per event | 1 |
Validate/api/v1/legistar/validate | Verify an agency ID: probes the upstream Legistar instance and confirms whether the municipality exists | 1 |
Bootstrap plan includes 25,000 credits per month -- enough for heavy multi-city legislative monitoring. See plans
Search municipal legislation in one call
POST a city slug and a keyword and get back structured legislation data -- file numbers, statuses, dates, bodies and sponsors as normalized JSON. The response on the right is a real capture.
from scavio import ScavioClient
client = ScavioClient(api_key="sk_live_your_key")
matters = client.legistar.matters(
client="seattle",
keyword="affordable housing",
)["data"]
for m in matters["results"]:
print(m["file"], m["statusName"])
print(m["title"][:80]){
"data": {
"results": [
{
"id": 2851,
"file": "Res 31609",
"title": "A RESOLUTION declaring the City Council's intent to consider strategies to increase the availability of affordable housing in The City of Seattle.",
"typeId": 52,
"typeName": "Resolution (Res)",
"statusId": 95,
"statusName": "Adopted",
"bodyId": 169,
"bodyName": "City Clerk",
"introDate": "2015-08-12T00:00:00",
"agendaDate": "2015-09-28T00:00:00",
"passedDate": "2015-09-28T00:00:00",
"requester": "Legislative Department",
"version": "1",
"text2": "[email protected]",
"lastModifiedUtc": "2021-09-29T16:12:11.987"
}
],
"count": 1,
"page": 1,
"per_page": 20,
"has_more": false
},
"response_time": 842,
"credits_used": 1,
"credits_remaining": 4999
}Why not the Legistar OData API directly?
It is free and public -- but building on it means managing per-city base URLs, OData query syntax, PascalCase fields, and opaque errors across 1,800+ instances.
Legistar OData API
- Different base URL per municipality -- manage hundreds of API roots
- OData query syntax with $filter, $orderby, $top instead of simple JSON POST
- PascalCase field names with inconsistent null handling across cities
- Opaque 500 errors for invalid agency IDs -- no indication what went wrong
- No unified authentication, credits tracking, or usage dashboard
- Getting staff details requires two separate API calls and manual merging
Scavio Legistar API
- One base URL, one API key -- pass the city slug as a parameter
- Simple JSON POST, clean camelCase response, consistent envelope
- Normalized field names and empty-value stripping across all municipalities
- Invalid agency IDs return actionable 400 errors with lookup instructions
- Usage tracking with credits_used and credits_remaining on every response
- Staff details composites Person + Office Records into one call
The upstream Legistar data is public record. Scavio normalizes and unifies access but does not add or modify the underlying legislative data.
What developers build with it
Civic tech applications
Build apps that let residents track what their city council is doing -- search legislation by keyword, follow meeting agendas, and surface votes on issues they care about. One API key covers every Legistar-powered municipality, so a single integration scales across the US.
matters + events + event/itemsGovernment transparency tools
Pull structured data on elected officials, their committee assignments, contact details, and the legislation they sponsor. Cross-reference sponsors with voting records and meeting attendance to build accountability dashboards that update automatically.
staff-details + matter/sponsors + bodiesLegislative tracking and alerts
Monitor specific keywords, legislation types or committees across multiple cities. Poll the matters and events endpoints on a schedule, diff against what you have seen before, and alert stakeholders when new ordinances are introduced or hearings are scheduled.
matters + eventsUrban planning and real estate
Search for zoning amendments, land use resolutions and housing policy across dozens of cities at once. Pull the full attachment set -- fiscal impact notes, signed ordinances, supporting documents -- for any piece of legislation without navigating individual council portals.
matters + matter/attachments + matter/historyPublic affairs and lobbying
Track ordinances and committee hearings across multiple jurisdictions for clients. Get official rosters with contact details, monitor legislation sponsors, and follow the full action trail from introduction through committee to council vote.
matters + staff-details + matter/historyMedia and journalism
Reporters covering local government can search legislation by keyword, pull upcoming meeting agendas with linked motions, and identify which officials sponsor which bills -- across every city a newsroom covers, from one API.
matters + event/items + staff-detailsHow to get municipal legislative data as JSON
- 1
Get an API key
Sign up for a Scavio account on the Bootstrap plan or above and copy your key from the dashboard. Legistar endpoints require Bootstrap -- PAYG and Project plans do not include them.
- 2
Find the agency ID
Visit the municipality's Legistar page and use the subdomain from the URL as the agency ID -- for example, seattle.legistar.com becomes "seattle", austintexas.legistar.com becomes "austintexas". Use the /validate endpoint to confirm the ID is correct.
- 3
POST to a Legistar endpoint
Send {"client": "seattle", "keyword": "affordable housing"} to https://api.scavio.dev/api/v1/legistar/matters with an Authorization: Bearer header. All ten endpoints use the same pattern: POST with JSON body, get back normalized JSON.
- 4
Read the JSON
The response wraps the data under a data key and adds credits_used and credits_remaining. Legislation results include page, per_page and has_more for pagination. All field names are normalized camelCase, regardless of the underlying Legistar OData format.
Legistar API FAQ
What is Legistar?
+
Legistar is a legislative management system built by Granicus. It is used by over 1,800 US municipalities to manage legislation, meeting agendas, votes, and elected official records. Each city runs its own Legistar instance with its own OData API, which means querying multiple cities requires managing multiple base URLs and inconsistent field formats.
What does the Scavio Legistar API do?
+
It normalizes municipal Legistar instances behind one REST API and one API key. You POST a municipality slug and your query parameters, and get back clean camelCase JSON instead of raw OData with PascalCase fields and inconsistent nulls. Ten endpoints cover legislation search, meetings, officials, committees, staff details, attachments, sponsors, legislative history, agenda items, and agency validation.
Which cities and municipalities are supported?
+
Any municipality that runs a public Legistar instance, which covers 1,800+ US cities, counties and special districts. The agency ID is the subdomain from the city's Legistar URL -- for example, seattle.legistar.com uses 'seattle'. Use the /validate endpoint to confirm any agency ID.
Which plan do I need?
+
Legistar endpoints require the Bootstrap plan ($100/month) or above. They are not available on PAYG or Project plans. This is because the upstream data is free public-record information, but the normalization and unified access justify a higher-tier plan.
How much does a Legistar request cost?
+
Every Legistar endpoint costs 1 credit per successful call, regardless of which endpoint you use or how many results come back. The Bootstrap plan includes 25,000 credits per month.
How do I find the right agency ID for a city?
+
Visit the municipality's Legistar page (search for '[city name] legistar') and look at the URL. The subdomain is the agency ID: seattle.legistar.com is 'seattle', austintexas.legistar.com is 'austintexas', cityofdallas.legistar.com is 'cityofdallas'. If you are unsure, send the ID to the /validate endpoint to confirm it.
How do I search for specific legislation?
+
POST to /api/v1/legistar/matters with the client (municipality slug) and a keyword. You can also filter by legislation type, status, date range, and body. The response returns matching matters with their file number, title, type, status, dates, and the body that introduced them.
What is the difference between the Legistar OData API and Scavio?
+
The raw Legistar API is OData-flavored, uses PascalCase field names, returns inconsistent null handling, and requires a different base URL per municipality. Scavio normalizes everything into clean camelCase JSON, handles the per-city routing behind one base URL, detects invalid agency IDs with actionable error messages, and returns a consistent response envelope with credits tracking. You never touch OData query syntax.
Can I get official contact details and committee roles?
+
Yes. The /staff-details endpoint is a composite that returns a single official's full contact info (address, phone, email, website) plus all their committee memberships with roles, titles and term dates -- two Legistar API calls merged into one response. Use /persons with active_only to find officials first.
Is the data real-time?
+
Scavio queries the upstream Legistar instances directly, so the data is as current as each municipality's Legistar system. Most cities update their Legistar data within hours of official action, though the exact lag depends on the municipality's own publishing workflow.
Can I get meeting agendas and linked legislation?
+
Yes. The /events endpoint returns meetings with their date, location, body, media links, and agenda status. The /event/items endpoint returns the individual agenda items for a specific event, including actions taken, motions, and linked legislation.
What are rate limits for Legistar endpoints?
+
Rate limits follow your plan tier -- Bootstrap allows 10 concurrent requests. The upstream Legistar instances are public and free, so the binding constraint is always your Scavio plan concurrency, never the data source.
Can I get attachments and documents?
+
Yes. The /matter/attachments endpoint returns all documents attached to a piece of legislation -- fiscal impact notes, signed ordinances, amendments, supporting materials -- with download links to the original files hosted on the municipality's Legistar instance.
What happens if I use a wrong agency ID?
+
The API returns a 400 error with an actionable message explaining that the agency ID was not found and instructions on how to find the correct one from the municipality's Legistar URL. Use the /validate endpoint to check an ID before making data calls.
Explore more of Scavio
SEC EDGAR API
Company filings, financials and insider transactions from EDGAR.
Companies House API
UK company records, officers and filing history.
Google Search API
Web, news, image and video search results as JSON.
Google News API
News articles by keyword, topic and region.
Pricing
Credit packs and plans, with no per-platform surcharge.
MCP server
Every platform as a callable tool for your agents.
Start pulling municipal legislative data today
Bootstrap plan and above. One API key covers 1,800+ US municipalities -- legislation, meetings, officials, staff details, committees and votes as normalized JSON.