GH-API(1)

NAME
gh-api - Make an authenticated GitHub API request

SYNOPSIS
gh api <endpoint> [flags]

DESCRIPTION
Makes an authenticated HTTP request to the GitHub API and prints the response.

The endpoint argument should either be a path of a GitHub API v3 endpoint, or graphql to access the GitHub API v4.

Placeholder values {owner}, {repo}, and {branch} in the endpoint argument will get replaced with values from the repository of the current directory or the repository specified in the GH_REPO environment variable. Note that in some shells, for example PowerShell, you may need to enclose any value that contains {...} in quotes to prevent the shell from applying special meaning to curly braces.

The -p/--preview flag enables opting into previews, which are feature-flagged, experimental API endpoints or behaviors. The API expects opt-in via the Accept header with format application/vnd.github.<preview-name>-preview+json and this command facilitates that via --preview <preview-name>. To send a request for the corsair and scarlet witch previews, you could use -p corsair,scarlet-witch or --preview corsair --preview scarlet-witch.

The default HTTP request method is GET normally and POST if any parameters were added. Override the method with --method.

Pass one or more -f/--raw-field values in key=value format to add static string parameters to the request payload. To add non-string or placeholder-determined values, see -F/--field below. Note that adding request parameters will automatically switch the request method to POST. To send the parameters as a GET query string instead, use --method GET.

The -F/--field flag has magic type conversion based on the format of the value:

•   literal values true, false, null, and integer numbers get converted to appropriate JSON types;

•   placeholder values {owner}, {repo}, and {branch} get populated with values from the repository of the current directory;

•   if the value starts with @, the rest of the value is interpreted as a filename to read the value from. Pass - to read from standard input.

For GraphQL requests, all fields other than query and operationName are interpreted as GraphQL variables.

To pass nested parameters in the request payload, use key[subkey]=value syntax when declaring fields. To pass nested values as arrays, declare multiple fields with the syntax key[]=value1, key[]=value2. To pass an empty array, use key[] without a value.

To pass pre-constructed JSON or payloads in other formats, a request body may be read from file specified by --input. Use - to read from standard input. When passing the request body this way, any parameters specified via field flags are added to the query string of the endpoint URL.

In --paginate mode, all pages of results will sequentially be requested until there are no more pages of results. For GraphQL requests, this requires that the original query accepts an $endCursor: String variable and that it fetches the pageInfo{ hasNextPage, endCursor } set of fields from a collection. Each page is a separate JSON array or object. Pass --slurp to wrap all pages of JSON arrays or objects into an outer JSON array.

OPTIONS

--cache <duration>
    Cache the response, e.g. "3600s", "60m", "1h"

-F, --field <key=value>
    Add a typed parameter in key=value format (use "@" or "@-" to read value from file or stdin)

-H, --header <key:value>
    Add a HTTP request header in key:value format

--hostname <string>
    The GitHub hostname for the request (default "github.com")

-i, --include
    Include HTTP response status line and headers in the output

--input <file>
    The file to use as body for the HTTP request (use "-" to read from standard input)

-q, --jq <string>
    Query to select values from the response using jq syntax

-X, --method <string> (default "GET")
    The HTTP method for the request

--paginate
    Make additional HTTP requests to fetch all pages of results

-p, --preview <strings>
    Opt into GitHub API previews (names should omit '-preview')

-f, --raw-field <key=value>
    Add a string parameter in key=value format

--silent
    Do not print the response body

--slurp
    Use with "--paginate" to return an array of all pages of either JSON arrays or objects

-t, --template <string>
    Format JSON output using a Go template; see "gh help formatting"

--verbose
    Include full HTTP request and response in the output

EXIT CODES
0: Successful execution

1: Error

2: Command canceled

4: Authentication required

NOTE: Specific commands may have additional exit codes. Refer to the command's help for more information.

EXAMPLE
    # List releases in the current repository
    $ gh api repos/{owner}/{repo}/releases
    # Post an issue comment
    $ gh api repos/{owner}/{repo}/issues/123/comments -f body='Hi from CLI'
    # Post nested parameter read from a file
    $ gh api gists -F 'files[myfile.txt][content]=@myfile.txt'
    # Add parameters to a GET request
    $ gh api -X GET search/issues -f q='repo:cli/cli is:open remote'
    # Use a JSON file as request body
    $ gh api repos/{owner}/{repo}/rulesets --input file.json
    # Set a custom HTTP header
    $ gh api -H 'Accept: application/vnd.github.v3.raw+json' ...
    # Opt into GitHub API previews
    $ gh api --preview baptiste,nebula ...
    # Print only specific fields from the response
    $ gh api repos/{owner}/{repo}/issues --jq '.[].title'
    # Use a template for the output
    $ gh api repos/{owner}/{repo}/issues --template \
      '{{range .}}{{.title}} ({{.labels | pluck "name" | join ", " | color "yellow"}}){{"\n"}}{{end}}'
    # Update allowed values of the "environment" custom property in a deeply nested array
    $ gh api -X PATCH /orgs/{org}/properties/schema \
       -F 'properties[][property_name]=environment' \
       -F 'properties[][default_value]=production' \
       -F 'properties[][allowed_values][]=staging' \
       -F 'properties[][allowed_values][]=production'
    # List releases with GraphQL
    $ gh api graphql -F owner='{owner}' -F name='{repo}' -f query='
      query($name: String!, $owner: String!) {
        repository(owner: $owner, name: $name) {
          releases(last: 3) {
            nodes { tagName }
          }
        }
      }
    '
    # List all repositories for a user
    $ gh api graphql --paginate -f query='
      query($endCursor: String) {
        viewer {
          repositories(first: 100, after: $endCursor) {
            nodes { nameWithOwner }
            pageInfo {
              hasNextPage
              endCursor
            }
          }
        }
      }
    '
    # Get the percentage of forks for the current user
    $ gh api graphql --paginate --slurp -f query='
      query($endCursor: String) {
        viewer {
          repositories(first: 100, after: $endCursor) {
            nodes { isFork }
            pageInfo {
              hasNextPage
              endCursor
            }
          }
        }
      }
    ' | jq 'def count(e): reduce e as $_ (0;.+1);
    [.[].data.viewer.repositories.nodes[]] as $r | count(select($r[].isFork))/count($r[])'

SEE ALSO
gh(1)