| 1 | --- |
| 2 | title: g1t API reference |
| 3 | description: The REST API at api.g1t.sh, its authentication, errors and conventions, and a page for every endpoint. |
| 4 | --- |
| 5 | |
| 6 | The REST API lives at `https://api.g1t.sh`. It exposes the same operations |
| 7 | as the [MCP server](/reference/mcp/): every endpoint names the MCP tool and |
| 8 | action that do the same thing, with the same inputs. |
| 9 | |
| 10 | This page covers what every endpoint shares. The pages under each resource |
| 11 | in the sidebar document one endpoint each: its parameters, an example |
| 12 | request and response, and its errors. The machine-readable description is |
| 13 | at [api.g1t.sh/openapi.json](https://api.g1t.sh/openapi.json), and the |
| 14 | [explorer](/api/reference/) lets you call the API from the browser. |
| 15 | |
| 16 | ## Start at the root |
| 17 | |
| 18 | The API is public. Anything you could see on the site without signing in, |
| 19 | you can read without a token. `GET https://api.g1t.sh/` returns where |
| 20 | everything is, as URL templates: |
| 21 | |
| 22 | ```sh |
| 23 | curl https://api.g1t.sh/ |
| 24 | ``` |
| 25 | |
| 26 | ```json |
| 27 | { |
| 28 | "documentation_url": "https://docs.g1t.sh/reference/api/", |
| 29 | "openapi_url": "https://api.g1t.sh/openapi.json", |
| 30 | "mcp_url": "https://mcp.g1t.sh", |
| 31 | "current_user_url": "https://api.g1t.sh/user", |
| 32 | "repository_url": "https://api.g1t.sh/repos/{owner}/{name}", |
| 33 | "work_url": "https://api.g1t.sh/workspaces/{workspace}/work{?state,label,repo}", |
| 34 | "pulls_url": "https://api.g1t.sh/repos/{owner}/{name}/pulls{?state}" |
| 35 | } |
| 36 | ``` |
| 37 | |
| 38 | The response has more entries than shown here. |
| 39 | |
| 40 | ## Versioning and deprecation |
| 41 | |
| 42 | The [g1t API versioning and deprecation policy](/reference/versioning/) has |
| 43 | a permanent address for integrations and migration notices. |
| 44 | |
| 45 | g1t uses unprefixed URLs, such as `https://api.g1t.sh/repos`, like GitHub. |
| 46 | The optional `X-G1t-Api-Version: 1` request header selects the current REST |
| 47 | contract. Omitting it selects version 1 too. REST responses include |
| 48 | `X-G1t-Api-Version: 1`; unsupported values are rejected with `422` before |
| 49 | an operation runs. `/v1/` remains a compatibility alias for existing clients, |
| 50 | not the preferred API base URL. MCP negotiates its own protocol version. |
| 51 | |
| 52 | New optional fields and endpoints may be added within a version. Clients |
| 53 | should ignore fields they do not recognize. Breaking contract changes need |
| 54 | a new version value and a migration guide. Before retiring a version or |
| 55 | endpoint, g1t will announce its replacement and retirement date in these |
| 56 | docs and on affected responses: `Deprecation` uses an RFC 9745 Structured |
| 57 | Field date, `Sunset` uses an RFC 8594 HTTP date, and a `Link` with |
| 58 | `rel="deprecation"` points to the migration guide. No version is currently |
| 59 | deprecated and no retirement date is set; those headers are absent until |
| 60 | there is an announced deprecation. A fixed minimum notice period has not |
| 61 | been established. |
| 62 | |
| 63 | ## Authentication |
| 64 | |
| 65 | A token is needed to change anything, and to see what is private. Send an |
| 66 | [access token](https://g1t.sh/settings/tokens) as a bearer token: |
| 67 | |
| 68 | ```sh |
| 69 | curl https://api.g1t.sh/user \ |
| 70 | -H "Authorization: Bearer $G1T_TOKEN" |
| 71 | ``` |
| 72 | |
| 73 | `Authorization: token $G1T_TOKEN`, the other form GitHub takes, works the |
| 74 | same, so Octokit and the actions built on it, such as `actions/checkout` |
| 75 | and `actions/github-script`, are signed in with the token they are given. |
| 76 | |
| 77 | For CI and other automation that works for a team rather than for you, use |
| 78 | one of the workspace's own |
| 79 | [workspace access tokens](/guides/workspaces/#workspace-access-tokens): |
| 80 | it acts as the workspace and keeps working when you leave. |
| 81 | |
| 82 | Public data can be read without a token. A token that is not valid is |
| 83 | rejected with `401` rather than treated as anonymous. Each endpoint's page |
| 84 | says whether it needs a token. |
| 85 | |
| 86 | A [workspace's own token](/guides/workspaces/#workspace-access-tokens) acts |
| 87 | as the workspace. The token g1t works with can use only the |
| 88 | operations its task needs, in its own repository. |
| 89 | |
| 90 | ### Scopes |
| 91 | |
| 92 | Each endpoint needs one [scope](/guides/authentication/#scopes), such as |
| 93 | `work:read` to read a work item or `work:write` to open one. Its page |
| 94 | says which, and the [OpenAPI document](https://api.g1t.sh/openapi.json) |
| 95 | gives it as `x-scope` on each operation, beside `x-mcp-tool` and |
| 96 | `x-mcp-action`, the MCP tool and action that do the same: |
| 97 | |
| 98 | ```json |
| 99 | { |
| 100 | "operationId": "get_work_item", |
| 101 | "x-operation": "get_work_item", |
| 102 | "x-mcp-tool": "work_item", |
| 103 | "x-mcp-action": "get", |
| 104 | "x-scope": "work:read" |
| 105 | } |
| 106 | ``` |
| 107 | |
| 108 | `x-scope` is `null` for `GET /user`, which any token may use. A token |
| 109 | needs the scope, and whoever it acts as needs a role that allows the call. |
| 110 | A token reaches every workspace and repository whoever it acts as can. |
| 111 | |
| 112 | ## Signing in from a tool |
| 113 | |
| 114 | A tool gets a token by having a person approve a short code in their |
| 115 | browser: [start signing in](/reference/api/accounts/device-code/), then |
| 116 | [finish signing in](/reference/api/accounts/device-token/). See |
| 117 | [signing in from a tool](/guides/authentication/#signing-in-from-a-tool). |
| 118 | |
| 119 | Applications that can open a browser use OAuth instead. See |
| 120 | [signing in with OAuth](/guides/authentication/#signing-in-with-oauth). |
| 121 | |
| 122 | | Method | Path | | |
| 123 | | --- | --- | --- | |
| 124 | | `GET` | `/.well-known/oauth-authorization-server` | Where the endpoints are. | |
| 125 | | `POST` | `/oauth/register` | Register a client. Body: `client_name`, `redirect_uris`. | |
| 126 | | `POST` | `/oauth/token` | Exchange a code, or refresh. Form-encoded or JSON. | |
| 127 | |
| 128 | Accounts are created in a browser only. There is no registration endpoint |
| 129 | for accounts. |
| 130 | |
| 131 | ## Requests and responses |
| 132 | |
| 133 | Request bodies are JSON. |
| 134 | |
| 135 | Every name in a body is `snake_case`, both ways: responses, errors, MCP |
| 136 | results and [webhook](/guides/webhooks/) payloads. Request bodies take the |
| 137 | same names as the MCP tools, and also accept the `camelCase` spelling: |
| 138 | |
| 139 | ```sh |
| 140 | # Both require pull requests to be up to date before they merge. |
| 141 | curl -X PATCH https://api.g1t.sh/repos/flagon-io/hello/settings \ |
| 142 | -H "Authorization: Bearer $G1T_TOKEN" -d '{"require_up_to_date": true}' |
| 143 | curl -X PATCH https://api.g1t.sh/repos/flagon-io/hello/settings \ |
| 144 | -H "Authorization: Bearer $G1T_TOKEN" -d '{"requireUpToDate": true}' |
| 145 | ``` |
| 146 | |
| 147 | When a body gives a field both ways, the `snake_case` one is used. |
| 148 | |
| 149 | Names you chose are never changed: a workflow's `inputs`, the names of |
| 150 | secrets and variables, an environment's `env`, a job's `outputs` and |
| 151 | `matrix`, labels and headers come back exactly as they were written. |
| 152 | |
| 153 | Every person in a response, such as a work item's `author`, a workspace's |
| 154 | members or whoever `whoami` is, has two usernames: |
| 155 | |
| 156 | - `username` is lowercased. It is what an account is found, linked and |
| 157 | mentioned by, and it never changes case, so match on it. |
| 158 | - `display_username` is the username as its owner wrote it, such as |
| 159 | `Ana`. It is the same as `username` when they chose no case. Show it. |
| 160 | |
| 161 | ```json |
| 162 | { "id": "usr_01kkntcg1eeb98j62xjm7eh09p", "username": "ana", "display_username": "Ana" } |
| 163 | ``` |
| 164 | |
| 165 | Requests take a username in any case: `Ana` and `ana` are the same person. |
| 166 | |
| 167 | A successful request answers `200` with the result as the body: an object, |
| 168 | a list, or `true` for a deletion. There is no envelope around it. |
| 169 | |
| 170 | In paths, `{owner}` is the workspace that owns the repository and `{name}` |
| 171 | is the repository's name; `{workspace}` is a workspace's slug. Work items |
| 172 | live in a workspace, at `/workspaces/{workspace}/work/{number}`, and pull |
| 173 | requests in a repository, at `/repos/{owner}/{name}/pulls/{number}`. The |
| 174 | two share one sequence of numbers per workspace, so a new number names |
| 175 | exactly one of them in it. Pull requests opened before work items keep the |
| 176 | numbers they had. See [work items](/guides/work-items/). |
| 177 | |
| 178 | ## Errors |
| 179 | |
| 180 | Errors are JSON with a stable `code` and a human-readable `message`. |
| 181 | |
| 182 | ```json |
| 183 | { "error": { "code": "not_found", "message": "Repository not found." } } |
| 184 | ``` |
| 185 | |
| 186 | | Status | Code | Meaning | |
| 187 | | --- | --- | --- | |
| 188 | | 401 | `unauthenticated` | A token is required, or the one sent is not valid. | |
| 189 | | 402 | `payment_required` | The workspace's plan or limits do not allow this: for example, a free workspace inviting someone, or making a repository private, or moving a private one in, without room in its free private storage. See [usage and billing](/guides/usage-and-billing/#when-work-is-stopped). | |
| 190 | | 403 | `forbidden` | You are signed in but not allowed to do this: your role is not enough, or the token lacks a scope, which `needed_scope` names. | |
| 191 | | 404 | `not_found` | It does not exist, or you cannot see it. A path that is not an endpoint answers this too. | |
| 192 | | 409 | `conflict` | The request conflicts with the current state. | |
| 193 | | 422 | `invalid` | The input is not valid. | |
| 194 | | 429 | `rate_limited` | Too many requests in the last minute. Wait the seconds `Retry-After` says. See [rate limits](#rate-limits). | |
| 195 | |
| 196 | Branch on `code`, not on `message`: messages are written for people and |
| 197 | may change. |
| 198 | |
| 199 | When an access token lacks the scope a call needs, the `403` also names |
| 200 | that scope in `needed_scope`: |
| 201 | |
| 202 | ```json |
| 203 | { |
| 204 | "error": { |
| 205 | "code": "forbidden", |
| 206 | "message": "This access token needs the work:write scope to use open_work_item.", |
| 207 | "needed_scope": "work:write" |
| 208 | } |
| 209 | } |
| 210 | ``` |
| 211 | |
| 212 | Give the token that permission on its page under |
| 213 | [Settings → Access tokens](https://g1t.sh/settings/tokens), or use another |
| 214 | token. A `403` for any other reason has no `needed_scope`. |
| 215 | |
| 216 | ## Rate limits |
| 217 | |
| 218 | Each token may make 1,000 requests a minute. Requests without a token are |
| 219 | limited to 60 a minute for each IP address. Past either, the API answers |
| 220 | `429` with `rate_limited` and a `Retry-After` header saying how many |
| 221 | seconds to wait: |
| 222 | |
| 223 | ```json |
| 224 | { "error": { "code": "rate_limited", "message": "Too many requests with this token. Wait a minute and try again: https://docs.g1t.sh/reference/rate-limits/" } } |
| 225 | ``` |
| 226 | |
| 227 | Every limit, and how to stay under them, is on [rate limits](/reference/rate-limits/). |
| 228 | |
| 229 | ## Lists |
| 230 | |
| 231 | Lists come newest first, unless an endpoint says otherwise. Most return |
| 232 | everything up to a limit; the few that grow without bound take a cursor: |
| 233 | |
| 234 | | Endpoint | Limit | Next page | |
| 235 | | --- | --- | --- | |
| 236 | | [List repositories](/reference/api/repositories/list-repos/) | 50 | None | |
| 237 | | [List work items](/reference/api/work-items/list-work-items/) | 100 | None | |
| 238 | | [List pull requests](/reference/api/pull-requests/list-pull-requests/) | 100 | None | |
| 239 | | [List repository events](/reference/api/repositories/list-events/) | 50 | `before`: the id of the last event you have | |
| 240 | | [List workflow runs](/reference/api/actions/list-workflow-runs/) | `per_page`, at most 100 and 50 if not given | None | |
| 241 | | [List webhook deliveries](/reference/api/webhooks/list-webhook-deliveries/) | 50 | None | |
| 242 | | [List notifications](/reference/api/notifications/list-notifications/) | `per_page`, at most 100 and 30 if not given | `cursor`: the `next` of the page before | |
| 243 | | [Read a session](/reference/api/sessions/read-session/) | None | `after`: the last `seq` you have | |
| 244 | | [Get a job's log](/reference/api/actions/get-job-logs/) | 500 chunks | `after`: the last `seq` you have | |
| 245 | |
| 246 | ## Identifiers and times |
| 247 | |
| 248 | Work items are addressed by workspace and number, pull requests by |
| 249 | repository and number. Other ids |
| 250 | are [TypeIDs](https://github.com/jetify-com/typeid): a prefix naming the |
| 251 | kind of thing, then a UUIDv7 in base32, for example |
| 252 | `pr_01jb2k7x9hfq0b3zj0f5s2m8ra`. They sort by creation time. |
| 253 | |
| 254 | Times are RFC 3339 in UTC, with milliseconds, such as |
| 255 | `2026-10-01T18:04:11.482Z`. |
| 256 | |
| 257 | ## Resources |
| 258 | |
| 259 | | Resource | | |
| 260 | | --- | --- | |
| 261 | | [Accounts](/reference/api/accounts/whoami/) | Signing in from a tool, and who a token acts as. Accounts are made and [deleted](/guides/authentication/#deleting-your-account) only in a browser: there is no route for either. | |
| 262 | | [Workspaces](/reference/api/workspaces/create-workspace/) | Creating a workspace. | |
| 263 | | [Notifications](/reference/api/notifications/list-notifications/) | Your notifications: their threads, why you were told of each, marking them read, done, saved or snoozed, and what you subscribe to and watch. See [notifications](/guides/notifications/). | |
| 264 | | [Billing](/reference/api/billing/get-usage/) | A workspace's usage by product, project and day, its budget and its invoices. See [usage and billing](/guides/usage-and-billing/). | |
| 265 | | [Invites](/reference/api/invites/list-invites/) | Inviting a friend to g1t by email, inviting people into a workspace by username or email, and answering the invitations sent to you. Anyone can sign up without an invite. See [invite a friend](/guides/authentication/#invite-a-friend). | |
| 266 | | [Repositories](/reference/api/repositories/list-repos/) | A repository, how it handles pull requests, and its timeline. | |
| 267 | | [Access](/reference/api/access/list-collaborators/) | Who has which role on a repository, invitations, outside collaborators, and a workspace's base permission. | |
| 268 | | [Secret scanning](/reference/api/secret-scanning/list-secret-scanning-alerts/) | Secrets found in pushes and history, where each one is, bypassing push protection and reviewing bypass requests, validity checks, and custom patterns. See [secret protection](/guides/security/secret-protection/). | |
| 269 | | [Code scanning](/reference/api/code-scanning/list-code-scanning-alerts/) | SARIF uploads, and the alerts and analyses they make. See [code scanning](/guides/security/code-scanning/). | |
| 270 | | [Supply chain](/reference/api/supply-chain/list-vulnerability-alerts/) | Vulnerability alerts, the dependency graph, its SPDX SBOM, and comparing dependencies. See [supply chain](/guides/security/supply-chain/). | |
| 271 | | [Security settings](/reference/api/security-settings/get-security-settings/) | When pull request checks fail, dependency review's policy, delegated bypass, validity checks and a workspace's overview. | |
| 272 | | [Work items](/reference/api/work-items/list-work-items/) | What should change, in a workspace: the repositories each links, labels and comments, claims and hand-offs. See [work items](/guides/work-items/). | |
| 273 | | [Pull requests](/reference/api/pull-requests/list-pull-requests/) | Proposed changes: reviews, merging and the merge queue. | |
| 274 | | [Sessions](/reference/api/sessions/read-session/) | The record of how a pull request was made, written by the coding agent that made it. See [sessions and why-blame](/guides/why-blame/). | |
| 275 | | [Actions](/reference/api/actions/list-workflows/) | Workflows, their runs and their logs. | |
| 276 | | [Run protection](/reference/api/run-protection/update-environment/) | Environments' protection rules and the reviews of the jobs they hold, approving a pull request's run from outside, a job token's default permissions, and repository dispatch. See [GitHub Actions](/guides/actions/#environments). | |
| 277 | | [Secrets and variables](/reference/api/secrets-and-variables/list-actions-secrets/) | Values workflows and deployments read. | |
| 278 | | [Webhooks](/reference/api/webhooks/list-webhooks/) | Events sent to your own address. | |
| 279 | | [Integrations](/reference/api/integrations/list-integrations/) | Alert sources and trackers. | |