# REST API

The GitCafe REST API lives at `https://git.cafe/api`. Everything you can do in
the browser goes through it, and most of it is open to your own tools.

## Find the endpoints

The [API reference](https://git.cafe/api/openapi) lists every operation with its parameters and
response schemas. It is generated from the API itself, so it always matches
the server you are using. The same description is available as
[OpenAPI 3.1 JSON](https://git.cafe/api/openapi/json) for code generators, and as
[Markdown](https://git.cafe/api/openapi.md).

## Authenticate

Send a credential as a bearer token:

```sh
curl -H "Authorization: Bearer $GITCAFE_TOKEN" https://git.cafe/api/auth/principal
```

- **Personal access token**: for scripts and CI. Create one in
  [Settings → Tokens](https://git.cafe/docs/account/personal-access-tokens.md) with only the
  permissions you need.
- **OAuth**: for applications acting for other users; see
  [connect an API client](https://git.cafe/docs/account/mcp-connections.md#connect-an-api-client).
- **The CLI**: `cafe api <path>` sends an authenticated request using your
  `cafe` login, for example `cafe api "/repos/{owner}/{repo}"` inside a clone.

Requests without a credential can read public data, with a lower
[rate limit](https://git.cafe/docs/reference/rate-limits.md).

## Work with versions

Most resources carry a `version` number. When you change a resource, send the
version you read as `expectedVersion`. If someone changed it in the meantime,
the API answers `409 Conflict`: read the resource again, check the new values,
and retry with the new version. This stops you from overwriting changes you
have not seen.

## Retry safely

Operations that start work, such as merging, landing a stack, deleting a
branch or syncing a mirror, take a `requestId` that you choose (a UUID is a
good choice). If the response is lost, send the same request with the same
`requestId` again: you get the original result instead of a second operation.
Use a new `requestId` only when you mean to do something new.

Many such operations answer `202 Accepted` with an operation you can poll.
Accepted means the work is queued, not finished; read the operation until it
reports a final state.

## Page through lists

List responses return `items` and a `next` cursor. Pass `next` as the `after`
parameter to get the following page, and stop when `next` is `null`.
`cafe api --paginate` follows the cursors for you.

## Errors

Errors use `application/problem+json` with a `type`, `title`, `status` and
`detail`, and often a machine-readable `code`. A private repository you cannot
see answers `404`, the same as one that does not exist.
