The bridge from GitHub user workflows to programmable developer automation.
Everything in the previous three clusters is available over HTTP. Repositories, pull requests, reviews, Issues, releases, rulesets, checks — all of it is readable and writable by a program.
This cluster is where GitHub stops being a product you use and becomes infrastructure you build on.
Start with Lesson 1Two APIs, not one
Section titled “Two APIs, not one”GitHub exposes REST and GraphQL, and they are genuinely different systems rather than two syntaxes for the same thing. They have different endpoints, different authentication scopes in some cases, different rate-limit accounting, and different coverage — a few features exist in only one.
Neither is the successor to the other. Choosing between them is a per-task decision, covered in both API lessons and summarised here:
| REST | GraphQL | |
|---|---|---|
| Shape | One endpoint per resource | One endpoint, queries describe the shape |
| Fetching related data | Multiple requests | One request |
| Over-fetching | Common — you get the whole object | You request exactly what you need |
| Rate limiting | Per request | Per query complexity |
| Discoverability | Documented endpoints, easy to curl | Introspectable schema |
| Best for | Simple known operations, scripting | Related data, avoiding N+1 requests |
Claims that GraphQL is always more efficient or REST always simpler are both wrong. A single repository lookup is trivial in REST and needlessly ceremonious in GraphQL. Fetching a hundred pull requests with their authors, reviews and labels is one GraphQL query and several hundred REST requests.
The authentication decision
Section titled “The authentication decision”More engineering time is lost to choosing the wrong credential than to any other part of GitHub automation, so this cluster treats it as a first-class subject rather than a prerequisite.
| Scenario | Likely pattern |
|---|---|
| Personal CLI use | gh auth |
| Short personal script | Fine-grained personal access token |
| Organisation automation | GitHub App — usually preferable |
| User-authorised application | App or OAuth model |
| GitHub Actions workflow | Workflow token, or an App for cross-repository work |
| Public read-only query | Authentication may not be required |
That table is a starting point, not a rule. The reasoning behind it — least privilege, expiry, ownership, revocability — is in API Authentication, and the reason organisation automation should usually not use somebody’s personal token is in GitHub Apps.
What this cluster covers
Section titled “What this cluster covers”The two APIs. REST and GraphQL in depth — requests, authentication, versioning, pagination, rate limits, error handling, and when each is the right choice.
Credentials. The authentication decision framework, fine-grained tokens in detail, and GitHub Apps as the identity model for anything organisational.
Events. Webhooks — being told when something changes rather than asking repeatedly. This is the rung of the automation ladder most teams never reach, and it is the one that removes polling entirely.
Applied automation. Repositories, pull requests and Issues, then a small maintainable Python client that pulls the whole cluster together.
Reading the documentation
Section titled “Reading the documentation”GitHub’s API reference is large and the parts that matter are not always obvious. Three habits make it usable.
Read the permissions line. Every REST endpoint states which fine-grained permission it requires. That line is the fastest way to work out what a token needs, and it removes the usual approach of granting broadly and hoping.
Check both APIs. Coverage differs in both directions. Before concluding something is impossible, check whether the other API has it — Discussions are largely GraphQL-only, and some administrative endpoints are REST-only.
Watch the examples’ identity. Some endpoints behave differently depending on whether the caller is a user, an App installation, or the Actions token. The documentation says which are supported, and a 403 on an endpoint you believe you can reach is often an identity mismatch rather than a missing permission.
Errors are the interface
Section titled “Errors are the interface”Most of the difficulty in API work is not the successful path.
| Status | What it usually means here |
|---|---|
401 | The credential is missing, malformed, expired or revoked |
403 | Insufficient permission — or a rate limit; check the headers |
404 | Missing, or present and invisible to your token |
409 | A state conflict — an empty repository, or a merge race |
422 | Valid JSON, invalid content; the body names the field |
5xx | GitHub’s problem; retry with backoff |
Two of those are ambiguous by design and worth internalising now, because they cause more wasted debugging than anything else in this cluster.
404 is a privacy feature. GitHub returns “not found” rather than “forbidden” for private resources your token cannot see, so the API does not disclose which private repositories exist. While developing against a narrowly-scoped token, “not found” almost always means “not permitted”.
403 is overloaded. It covers genuine permission failures and some rate-limit rejections. Check
x-ratelimit-remaining before concluding your token is wrong.
Only 4xx responses other than 403 and 429 are worth failing fast on. Rate limits and 5xx should
back off and retry; everything else will fail identically however many times you try.
Prerequisites
Section titled “Prerequisites”| You should be able to | Covered in |
|---|---|
| Explain HTTP methods, status codes and headers | — |
| Read and write JSON | — |
Use gh api for one-off calls | gh api |
| Describe what a pull request stores | Pull Requests Explained |
| Write a script with error handling | GitHub CLI Scripting |
The Python lesson assumes basic Python. Everything else is language-agnostic and demonstrated with
curl and gh api.
Identity determines almost everything
Section titled “Identity determines almost everything”A recurring source of confusion is that the same request can succeed or fail depending purely on who is asking — and “who” has more possible answers than people expect.
| Caller | Sees | Rate limit | Acts as |
|---|---|---|---|
| Nobody | Public data | 60/hour | — |
| A user token | What that user can reach | 5,000/hour | The person |
| An App installation | Where the App is installed | 5,000+, scaling | The App |
| An App user token | Intersection of App and user | The user’s | The person, via the App |
| The Actions token | Its own repository | 1,000/hour per repository | The workflow |
The intersection row is worth dwelling on. An App with Issues write, used by someone with read-only access to a repository, cannot write there. That property is what makes Apps safe to install in organisations: the App cannot escalate a user beyond what they already have.
The consequence for debugging: before investigating a permission problem, establish which of these
five you are. gh api user tells you for a token; an App installation token has no user at all, and
calling /user with one returns an error that looks alarming and is simply the wrong endpoint for
that identity.
A note on API stability
Section titled “A note on API stability”REST endpoints and GraphQL fields are removed only after a deprecation period, announced through response headers and schema metadata rather than only in release notes. Watching for them is cheap and turns a future outage into scheduled work — the REST and GraphQL lessons each cover how.
The learning path
Section titled “The learning path”- Lesson 1: 01. GitHub REST APIGitHub REST API from first request to production script: authentication, API versioning, pagination, rate limits and error handling — with curl and gh api examples that run.
- Lesson 2: 02. GitHub GraphQL APIQuery exactly the data you need in one request. Learn the schema, nodes and edges, cursor pagination, mutations, node IDs, rate-limit cost and when REST is the better choice.
- Lesson 3: 03. API AuthenticationFine-grained tokens, classic PATs, GitHub App tokens, OAuth and the Actions token — which credential for which job, with a decision framework and the trade-offs of each.
- Lesson 4: 04. Fine-Grained PATsResource owner, repository selection, per-permission grants, expiry and organisation approval — how fine-grained PATs work and when a GitHub App is the better answer.
- Lesson 5: 05. GitHub AppsA GitHub App is an integration identity with explicit permissions and per-installation access. JWTs, installation tokens, webhooks, and when an App beats a token.
- Lesson 6: 06. GitHub WebhooksWebhooks push events to your system instead of you polling. Learn payloads, signature verification, retries and redelivery, idempotency and safe local development.
- Lesson 7: 07. Repository AutomationCreate and configure repositories, manage branches, labels, collaborators and releases through the API — with pagination, idempotency, dry-run and safe destructive operations.
- Lesson 8: 08. Pull Request AutomationAutomate pull requests through the GitHub API: list, read changed files, request reviewers, check status and merge safely — including the calls that stop a bot merging a red build.
- Lesson 9: 09. Issue AutomationList, create, label, assign and close Issues through the API — with search, pagination, triage patterns, rate-limit awareness and the pull-request overlap that skews counts.
- Lesson 10: 10. Python + GitHub APIBuild a maintainable Python client for GitHub — sessions, timeouts, retries, pagination, rate limits and error handling — organised into modules you can actually keep.
Where this sits on the ladder
Section titled “Where this sits on the ladder”A vertical progression: manual web interface, GitHub CLI, Bash automation, REST and GraphQL APIs, GitHub Apps with webhooks, and production integrations. The last three are the subject of this cluster.
The step that changes most is the last but one. Scripts ask GitHub what happened; webhooks mean GitHub tells you. That inversion removes polling, removes latency, and removes the rate-limit budget spent on asking whether anything changed — which is usually most of it.
Three principles this cluster returns to
Section titled “Three principles this cluster returns to”Least privilege. Every credential should be able to do the minimum the task requires, on the smallest set of repositories, for the shortest useful time. Broad tokens are convenient in development and are the reason incidents become large.
Handle pagination. The API returns pages. Automation that ignores this works during testing with twenty objects and silently misses data in production with four hundred. It is the most common correctness bug in GitHub automation.
Prefer events to polling. Asking every minute whether a pull request merged is a webhook problem being solved with a rate-limit budget. It is slower, more expensive, and less reliable than being told.
Then what?
Section titled “Then what?”This is the final cluster of GitHub Engineering. What follows it — GitHub Actions, security, and AI-assisted engineering — builds directly on it: workflows authenticate the way this cluster describes, security tooling consumes these endpoints, and integrations are Apps.
For now, the practical endpoint is that you should be able to take any operation from the previous three clusters and perform it from code.
Begin: GitHub REST API