Querying the GraphQL API

The GraphQL API is one unversioned endpoint, POST https://api.github.com/graphql 29 ; fields are deprecated on an announced schedule instead. A query names exactly the fields it needs across related objects, replacing several REST calls:

BookNest's issues, latest pull requests and tags in one GraphQL queryShell
gh api graphql -f query='query {
  repository(owner: "binarybehemoth", name: "booknest") {
    issues(states: OPEN) { totalCount }
    pullRequests(last: 3, states: MERGED) { nodes { number title } }
    refs(refPrefix: "refs/tags/") { totalCount }
  }
  rateLimit { cost remaining }
}' --jq '.data'
Output
{"rateLimit":{"cost":1,"remaining":4993},"repository":{"issues":{"totalCount":3},
"pullRequests":{"nodes":[{"number":28,"title":"Audit the workflows with zizmor"},{"number":29,
"title":"Keep the audit workflow's lines short"},{"number":31,
"title":"Add a webhook receiver and a dev container"}]},"refs":{"totalCount":4}}}

GraphQL is limited by points, 5,000 an hour, with a query's cost derived from how many nodes it could return; rateLimit reports it. Lists page with cursors (pageInfo { endCursor } passed back as after:), which gh 29 api graphql --paginate follows when the query declares $endCursor. Mutations change data, such as resolveReviewThread for the threads of Code Scanning and SARIF. Use GraphQL for reads that span objects, REST for simple resources and REST-only endpoints.