You might have heard of the GitHub CLI and all of the awesome things you can do with it. However, one of its hidden superpowers is the ability to execute complex queries and mutations through GitHub’s GraphQL API. This post will walk you through what GitHub’s GraphQL API endpoint is and how to query it with the GitHub CLI. What is GraphQL? Let’s start with the basics: GraphQL is a query language for APIs and a runtime for executing those queries against your data. Unlike traditional REST APIs that provide fixed data structures from predefined endpoints, GraphQL allows clients to request exactly the data they need in a single request. This single-request approach reduces network overhead, speeds up application performance, and simplifies client-side logic by eliminating the need to reconcile multiple API responses—a capability that has been openly available since the specification was open sourced in 2015. GraphQL operations come in two primary types: queries and mutations. Queries are read-only operations that retrieve data without making any changes—similar to GET requests in REST. Mutations, on the other hand, are used to modify server-side data (create, update, or delete)—comparable to POST, PATCH, PUT, and DELETE in REST APIs. This clear separation between reading and writing operations makes GraphQL interactions predictable while maintaining the flexibility to precisely specify what data should be returned after a change is made. How is GraphQL used at GitHub? GitHub implemented GraphQL in 2016 to address limitations of RESTful APIs. This adoption has significantly enhanced the developer experience when working with GitHub data. With the GraphQL endpoint, you can retrieve a repository’s issues, its labels, assignees, and comments with a single GraphQL query. Using our REST APIs, this would have otherwise taken several sets of nested calls. Some GitHub data and operations are only accessible through the GraphQL API (such as discussions, projects, and some enterprise settings), others exclusively through REST APIs (such as querying actions workflows, runners, or logs), and some using either endpoint (such as repositories, issues, pull requests, and user information). GitHub’s GraphQL endpoint is accessible at api.github.com/graphql and you can explore the full schema in our GraphQL documentation or through the interactive GraphQL Explorer. A key consideration when choosing between the REST API and the GraphQL API is how the rate limits are calculated. As a quick summary for how this is implemented: REST API: Limited by number of requests (typically 5,000 requests per hour for authenticated users and up to 15,000 for GitHub Apps installed in an Enterprise) GraphQL API: Limited by “points” (typically 5,000 points per hour for authenticated users but can go up to 10,000-12,500 points per hour for GitHub Apps) Each GraphQL query costs at least one point, but the cost increases based on the complexity of your query (number of nodes requested, connections traversed, etc.). The GraphQL API provides a rateLimit field you can include in your queries to check your current limit status. For scenarios where you need to fetch related data that would otherwise require multiple REST calls, GraphQL is often more rate limit friendly because: One complex GraphQL query might cost 5-10 points but replace 5-10 separate REST API calls. You avoid “over-fetching” data you don’t need, which indirectly helps with rate limits. The GraphQL API allows for more granular field selection, potentially reducing the complexity and point cost. However, poorly optimized GraphQL queries that request large amounts of nested data could potentially use up your rate limit faster than equivalent REST requests—and quickly run into secondary rate limit issues. A quick rule of thumb on deciding between which to use: For querying relational objects, such as GitHub Projects and their issues, GraphQL is often more effective, especially if it’s a discrete number of items. For bulk data of one type or single data points, such as pulling in a list of repository names in an organization, the REST API is often preferred. Sometimes there isn’t a right or wrong answer; so as long as the object exists, try one out! Why use GitHub CLI for GraphQL? While many developers start with GitHub’s GraphQL Explorer on the web, curl, or other API querying tools, there’s a more streamlined approach: using built-in GraphQL support in the GitHub CLI. Before diving into the how-to, let’s understand why GitHub CLI is often my go-to tool for GraphQL queries and mutations: Authentication is handled automatically: No need to manage personal access tokens manually. Streamlined syntax: Simpler than crafting curl commands. Local development friendly: Run queries and mutations right from your terminal. JSON processing: Built-in options for filtering and formatting results. Pagination support: Ability to work with cursor-based pagination in GraphQL responses. Consistent experience: Same tool you’re likely using for other GitHub tasks. How to get started with gh api graphql First, ensure you have GitHub CLI installed and authenticated with gh auth login. The basic syntax for making a GraphQL query with gh api graphql is: gh api graphql -H X-Github-Next-Global-ID:1 -f query=’ query { viewer { login name bio } } ‘ This simple query returns your GitHub username, the name you have defined in your profile, and your bio. The -f flag defines form variables, with query= being the GraphQL query itself. Here’s our example output: { “data”: { “viewer”: { “login”: “joshjohanning”, “name”: “Josh Johanning”, “bio”: “DevOps Architect | GitHub” } } } Running queries and mutations Basic query example Let’s try something more practical—fetching information about a repository. To get started, we’ll use the following query: gh api graphql -H X-Github-Next-Global-ID:1 -f query=’ query($owner:String!, $repo:String!) { repository(owner:$owner, name:$repo) { name description id stargazerCount forkCount issues(states:OPEN) { totalCount } } } ‘ -F owner=octocat -F repo=Hello-World The -F flag sets variable values that are referenced in the query with $variable. Here’s our example output: { “data”: { “repository”: { “name”: “Hello-World”, “description”: “My first repository on GitHub!”, “id”: “R_kgDOABPHjQ”, “stargazerCount”: 2894, “forkCount”: 2843, “issues”: { “totalCount”: 1055 } } } } 💡 Tip: The -H X-Github-Next-Global-ID:1 parameter sets an HTTP header that instructs GitHub’s GraphQL