Skip to main content

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.

tip

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

TypeallXxx queryDescription
LegislatorallLegislatorsEvery person who has served in Congress
LegislatorTermallLegislatorTermsIndividual terms of service per chamber/state
VoteallVotesRoll call vote events (House and Senate)
VotePositionallVotePositionsIndividual member Yea/Nay positions per vote
BillallBillsLegislation referenced by roll call votes
CommitteeallCommitteesHouse, Senate, and Joint committees
BillCosponsorallBillCosponsorsCosponsor records for bills
BillCommitteeallBillCommitteesCommittee referrals for bills
CommitteeMembershipallCommitteeMembershipsCurrent 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 }
}
}
}
}

note

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.