GH-API(1) GitHub CLI manual GH-API(1)

# [NAME](#NAME)

gh-api - Make an authenticated GitHub API request

# [SYNOPSIS](#SYNOPSIS)

**gh api &lt;endpoint&gt; \[flags]**

# [DESCRIPTION](#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.&lt;preview-name&gt;-preview+json** and this command facilitates that via **--preview &lt;preview-name&gt;**. 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](#OPTIONS)

[**--allow-escape-sequences**](#allow_escape_sequences)

Allow printing terminal escape sequences

[**--cache** **&lt;duration&gt;**](#cache)

Cache the response, e.g. "3600s", "60m", "1h"

[**-F**, **--field** **&lt;key=value&gt;**](#F)

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

[**-H**, **--header** **&lt;key:value&gt;**](#H)

Add a HTTP request header in key:value format

[**--hostname** **&lt;string&gt;**](#hostname)

The GitHub hostname for the request (default "github.com")

[**-i**, **--include**](#i)

Include HTTP response status line and headers in the output

[**--input** **&lt;file&gt;**](#input)

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

[**-q**, **--jq** **&lt;string&gt;**](#q)

Query to select values from the response using jq syntax

[**-X**, **--method** **&lt;string&gt; (default "GET")**](#X)

The HTTP method for the request

[**--paginate**](#paginate)

Make additional HTTP requests to fetch all pages of results

[**-p**, **--preview** **&lt;strings&gt;**](#p)

Opt into GitHub API previews (names should omit '-preview')

[**-f**, **--raw-field** **&lt;key=value&gt;**](#f)

Add a string parameter in key=value format

[**--silent**](#silent)

Do not print the response body

[**--slurp**](#slurp)

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

[**-t**, **--template** **&lt;string&gt;**](#t)

Format JSON output using a Go template; see "gh help formatting"

[**--verbose**](#verbose)

Include full HTTP request and response in the output

# [EXIT CODES](#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](#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](#SEE_ALSO)

[**gh(1)**](/man/os/gh/gh.1)

Oct 2026

---

Document: gh-api(1) from gh 2.103.3-r0 (Chainguard OS)
Source: https://github.com/cli/cli
