GraphQL
POST https://www.chicagopolitics.org/api/graphql with {"query": "...", "variables": {...}}. One typed graph of everything: ask for exactly the fields you need, across related records, in one request. This is usually the best fit for AI agents. The schema needs no key, and introspection works.
Your first query
curl https://www.chicagopolitics.org/api/graphql \
-H "Authorization: Bearer $CHICAGO_POLITICS_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ ward(number: 4) { member { name } } }"}'
{"data":{"ward":{"member":{"name":"Lamont J. Robinson"}}}}
That is 58 bytes, against about 4.8 KB for the full member record.
Related records in one request
A ward's member, their latest no votes, and the legislation and meeting behind each:
{
ward(number: 15) {
member {
name
votes(vote: NAY, first: 5) {
totalCount
nodes {
rollCall {
title date tally { yea nay }
legislation { record aiSummary { summary } }
meeting { body start }
}
}
}
}
}
}
Reference
- Root fields:
member,members,ward,wardAt(latitude, longitude),committee,committees,legislation(id or record),searchLegislation,rollCall,rollCalls,meeting,meetings,insights,money,donations,lobbyistContributions,lobbyistGifts,searchDocuments(semantic),answer(AI, cited),me; mutationcontributeData. Members also havemoney,donations, andspending. - Lists page with
first(max 200) andafter(frompageInfo.endCursor). Every object has aurlto cite. - One query counts as one request;
answeralso uses an AI call. Limits per query: depth 10, 250 fields, oneanswer, threesearchDocuments. - Fields are added without breaking existing queries; anything retired is marked
@deprecatedfirst.