The gh api command is the Swiss Army knife of GitHub CLI. It makes authenticated HTTP requests to the GitHub API — both REST (v3) and GraphQL (v4) — directly from your terminal.
Why Use gh api?
- You get automatic authentication — no need to pass tokens manually
- Placeholders like
{owner}and{repo}are resolved from the current repo - Built-in pagination, caching, and output formatting
- Access any GitHub API endpoint, even ones that
ghdoesn't have a dedicated command for
Basic REST Requests
# Get the current user
gh api user
# Get a repository
gh api repos/cli/cli
# Placeholders — resolved from the current repo's git remote
gh api repos/{owner}/{repo}
gh api repos/{owner}/{repo}/issues
# Specify a different repo
gh api repos/facebook/react/releasesHTTP Methods
# GET (default)
gh api repos/{owner}/{repo}
# POST
gh api repos/{owner}/{repo}/issues -f title="Bug" -f body="Details..."
# PATCH
gh api repos/{owner}/{repo}/issues/42 -f state=closed
# PUT
gh api repos/{owner}/{repo}/topics -f names[]="cli" -f names[]="golang"
# DELETE
gh api repos/{owner}/{repo}/issues/42/lock -X DELETE
# Explicit method
gh api repos/{owner}/{repo} -X PATCH -f description="Updated"Passing Parameters
Raw Fields (-f / --raw-field)
All values are treated as strings:
gh api repos/{owner}/{repo}/issues -f title="Bug report" -f body="It crashes"Typed Fields (-F / --field)
Values are auto-converted to the correct JSON type (boolean, integer, null):
gh api repos/{owner}/{repo}/issues -F title="Bug" -F labels[]="bug" -F milestone=3
gh api repos/{owner}/{repo}/issues -F draft=true -F assignees[]=octocatNested Parameters
# Nested objects: key[subkey]=value
gh api repos/{owner}/{repo}/rulesets -F rules[0][type]="commit_message_pattern"
# Arrays: key[]=value
gh api repos/{owner}/{repo}/topics -f names[]="cli" -f names[]="go"
# Empty array
gh api repos/{owner}/{repo}/topics -f names[]=""Reading from Files
# Request body from a file
gh api repos/{owner}/{repo}/rulesets --input ruleset.json
# From stdin
cat payload.json | gh api repos/{owner}/{repo}/rulesets --input -
# Field value from a file
gh api repos/{owner}/{repo}/issues -f body=@issue-body.mdGraphQL Queries
# Simple query
gh api graphql -f query='
query {
viewer {
login
name
}
}
'
# With variables
gh api graphql -f query='
query($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
stargazerCount
description
}
}
' -f owner=cli -f name=cli
# From a file
gh api graphql --input query.graphqlPagination
REST Pagination
# Automatically fetch all pages
gh api repos/{owner}/{repo}/issues --paginate
# Combine paginated results into one array
gh api repos/{owner}/{repo}/issues --paginate --slurpGraphQL Pagination
For GraphQL, your query must:
- Accept a
$endCursor: Stringvariable - Fetch
pageInfo { hasNextPage, endCursor }
gh api graphql --paginate -f query='
query($endCursor: String) {
viewer {
repositories(first: 100, after: $endCursor) {
nodes { nameWithOwner }
pageInfo { hasNextPage, endCursor }
}
}
}
'Output Formatting
JSON Filtering with --jq
# Extract specific fields
gh api repos/{owner}/{repo}/issues --jq '.[].title'
# Filter by condition
gh api repos/{owner}/{repo}/issues --jq '[.[] | select(.labels | length > 0)]'
# Format as tab-separated values
gh api repos/{owner}/{repo}/issues --jq '.[] | [.number, .title] | @tsv'Go Templates with --template
gh api repos/{owner}/{repo}/issues --template '
{{range .}}#{{.number}} {{.title}}
{{end}}'Include HTTP Headers
# Show status line and headers
gh api repos/{owner}/{repo} --include
# Full request and response
gh api repos/{owner}/{repo} --verboseSilent Mode
# Suppress response body (useful for write operations)
gh api repos/{owner}/{repo}/issues/42 -f state=closed --silentCaching
# Cache the response for 1 hour
gh api repos/{owner}/{repo} --cache 1h
# Cache for 5 minutes
gh api repos/{owner}/{repo}/issues --cache 5mCustom Headers
gh api repos/{owner}/{repo} -H "Accept: application/vnd.github.v3+json"
gh api repos/{owner}/{repo} -H "X-GitHub-Api-Version: 2022-11-28"API Previews
gh api repos/{owner}/{repo}/topics -p mercyReal-World Examples
Star a Repository
gh api user/starred/cli/cli -X PUTCreate a Repository Dispatch Event
gh api repos/{owner}/{repo}/dispatches -f event_type="deploy" -f client_payload[environment]="production"Get Rate Limit Status
gh api rate_limit --jq '.resources.core'List All Organization Members
gh api orgs/my-org/members --paginate --jq '.[].login'Delete a Repository (not available as a gh repo subcommand)
gh api repos/owner/repo -X DELETEExercises
- Get your user info:
gh api user --jq '.login' - List issues with pagination:
gh api repos/cli/cli/issues --paginate --jq '.[].title' | head -20 - Make a GraphQL query for star count:
gh api graphql -f query='{ repository(owner:"cli", name:"cli") { stargazerCount } }' - Check your rate limit:
gh api rate_limit --jq '.resources.core'