GraphQL API Reference
GovQL exposes all data through a PostGraphile-generated GraphQL API at https://api.govql.us/graphql.
PostGraphile reflects the PostgreSQL schema directly into GraphQL — tables become types, columns become fields, and foreign keys become nested resolvers. The schema below is the complete public API surface.
Try queries live in the built-in GraphiQL interface at api.govql.us/graphql.
Data model
Legislators ──< LegislatorTerms
Legislators ──< VotePositions >── Votes ──< VotePositions
Legislators ──< BillCosponsors >── Bills >── Votes
Bills ──< BillCommittees >── Committees ──< CommitteeMemberships >── Legislators
Available types
| Type | allXxx query | Description |
|---|---|---|
| Legislator | allLegislators | Every person who has served in Congress |
| LegislatorTerm | allLegislatorTerms | Individual terms of service per chamber/state |
| Vote | allVotes | Roll call vote events (House and Senate) |
| VotePosition | allVotePositions | Individual member Yea/Nay positions per vote |
| Bill | allBills | Legislation referenced by roll call votes |
| Committee | allCommittees | House, Senate, and Joint committees |
| BillCosponsor | allBillCosponsors | Cosponsor records for bills |
| BillCommittee | allBillCommittees | Committee referrals for bills |
| CommitteeMembership | allCommitteeMemberships | Current committee membership rosters |
Common patterns
Filtering
Every allXxx query accepts a filter argument with per-field conditions:
{
allVotes(
filter: {
chamber: { equalTo: "s" }
category: { equalTo: "nomination" }
congress: { greaterThanOrEqualTo: 117 }
}
) {
nodes { voteId votedAt question result }
}
}
String fields support equalTo, notEqualTo, includes, startsWith, and more.
Numeric fields support equalTo, lessThan, greaterThan, between, etc.
Pagination
All list queries use cursor-based pagination via first / after (forward) or last / before (backward):
{
allVotes(first: 20, after: "cursor-from-previous-page") {
pageInfo { hasNextPage endCursor }
nodes { voteId votedAt }
}
}
Ordering
Pass an orderBy enum value — field names are SCREAMING_SNAKE_CASE suffixed with _ASC or _DESC:
{
allLegislators(orderBy: LAST_NAME_ASC, first: 50) {
nodes { officialFull }
}
}
Nested relationships
Foreign keys are automatically resolved as nested fields — no manual joins required:
{
allVotePositions(
filter: { voteId: { equalTo: "s83-119.2025" } }
) {
nodes {
position
party
legislatorByBioguideId {
officialFull
}
voteByVoteId {
question
result
votedAt
}
}
}
}
Reverse relationships (one-to-many) return a connection with nodes:
{
allLegislators(
filter: { lastName: { equalTo: "Warren" } }
) {
nodes {
officialFull
legislatorTermsByBioguideId {
nodes { startDate endDate state termType party }
}
}
}
}
The per-type pages in this section are generated from db/schema.sql by scripts/generate-schema-docs.mjs. Re-run npm run generate-schema-docs after schema changes.