Authenticating to the REST API

The REST API lives at https://api.github.com 29 . Public data can be read anonymously (60 requests an hour per IP); anything else takes a token in the Authorization: Bearer header. That token can be a fine-grained or classic personal access token, an OAuth app's user token, a GitHub 29 App's installation token, or a workflow's GITHUB_TOKEN. With plain curl 3,008 , and the token in an environment variable so it never appears in the command:

An authenticated REST request with curlShell
curl -sS -D headers.txt -H "Authorization: Bearer $GH_TOKEN" \
  -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/binarybehemoth/booknest \
  | jq '{full_name, visibility, default_branch, open_issues_count}'
grep -iE '^(github-authentication|x-accepted-github|x-github-api|x-ratelimit)' headers.txt
Output
{
  "full_name": "binarybehemoth/booknest",
  "visibility": "public",
  "default_branch": "main",
  "open_issues_count": 3
}
github-authentication-token-expiration: 2026-12-24 08:09:11 UTC
x-accepted-github-permissions: metadata=read
x-github-api-version-selected: 2022-11-28
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4943
x-ratelimit-reset: 1790349701
x-ratelimit-used: 57
x-ratelimit-resource: core

The headers show the token's expiry, the permission the endpoint needed (metadata=read), the API version and the rate-limit budget. A missing or expired token gives 401; a token without the permission gives 403, as several endpoints did in Securing the Repository. gh 29 api adds headers, host and token for you and fills in {owner}/{repo} from the clone; elsewhere, pass GH_TOKEN in the environment, never on the command line.