# REST API

Everything the web pages and the CLI do with repositories, pull requests, sandboxes, live branches and Actions, as JSON under `https://rebasely.com/api/v1`.

## Authentication

Send an access token in `Authorization: Bearer <token>`. Personal tokens start with `dgp_`, agent tokens with `dga_`. A token works within its scopes, its organization (or, for a token of all your organizations, wherever you are a member, with your role there) and the repositories it is limited to; [Access tokens](https://rebasely.com/docs/tokens) lists the scopes.

curl:

```sh
curl -fsS -H "Authorization: Bearer $REBASELY_TOKEN" https://rebasely.com/api/v1/user
```

JavaScript:

```js
const res = await fetch("https://rebasely.com/api/v1/repos/acme/app/pulls?state=open", {
  headers: { authorization: `Bearer ${process.env.REBASELY_TOKEN}` },
});
const { pulls } = await res.json();
```

## Errors

Errors are JSON with a code and a sentence: `{"error": "forbidden", "message": "...", "reason": "missing_scope"}`.

| Status | error | When |
| --- | --- | --- |
| 401 | `unauthorized` | No token, or one that is malformed, unknown, expired or revoked. |
| 403 | `forbidden` | You can read the repository but the token lacks the scope or the role; `reason` says which. |
| 403 | `approval_required` | Only an owner may do this: the answer includes the [approval](https://rebasely.com/docs/agents#approvals) to start. |
| 404 | `not_found` | The repository, pull request or sandbox does not exist, or the token cannot see it: the two answers are the same. |
| 409, 422 | various | A conflict, or a request the server understood but cannot do (a merge that conflicts, a name that is taken). |
| 429 | `rate_limited` | Too many requests; wait for `Retry-After` seconds. |

## Rate limits

1,200 requests a minute per token (or per signed-in person), and 600 a minute per agent across all its tokens. Lists page with `?limit=` (1 to 100, 25 by default) and a cursor: `?cursor=` for Actions runs, `?before=` for pull requests.

## You and your token

| Request | What it does | Scope |
| --- | --- | --- |
| `GET /user` | Who the token belongs to: the account, organizations, scopes and expiry | `any` |
| `DELETE /tokens/current` | The token revokes itself | `any` |

## Repositories

| Request | What it does | Scope |
| --- | --- | --- |
| `GET /repos/:org/:repo` | The repository: visibility, default branch, description | `repo:read` |
| `POST /orgs/:org/repos` | Create a private repository: {name, description?, default\_branch?, init?: {readme: true}} | `repo:create` |
| `POST /repos/:org/:repo/visibility` | {visibility}: private at once for an owner; public asks an owner to approve | `repo:write` |

## Pull requests

Under `/repos/:org/:repo`. [Pull requests](https://rebasely.com/docs/pull-requests#api) has the bodies.

| Request | What it does | Scope |
| --- | --- | --- |
| `GET /pulls` | List: ?state=open\|closed\|merged\|all, ?q=, ?author=me | `repo:read` |
| `POST /pulls` | Open one: {title, head, base?, body?, draft?, reviewers?} | `repo:write` |
| `GET, PATCH /pulls/:n` | One pull request with its merge box; edit, close or reopen it | `repo:read, repo:write` |
| `GET /pulls/:n/commits, /files, /diff, /architecture` | Its commits, files, unified diff, and what it changes in the architecture | `repo:read` |
| `GET, POST /pulls/:n/comments` | Comments; a new one, on a line or as a reply | `repo:read, repo:write` |
| `GET, POST /pulls/:n/reviews` | Reviews; submit one: {event: approve\|request\_changes\|comment, body?, comments?} | `repo:read, repo:write` |
| `POST /pulls/:n/reviewers` | Ask for reviews: {add?, remove?} | `repo:write` |
| `POST /pulls/:n/merge` | Merge: {method?: merge\|squash\|rebase\|ff, expect\_head?, delete\_branch?} | `repo:write` |

## Sandboxes

| Request | What it does | Scope |
| --- | --- | --- |
| `GET, POST /repos/:org/:repo/sandboxes` | List; create one: {from?, name?, ttl\_s?, live?} | `repo:write` or `sandbox:write` |
| `GET, DELETE .../sandboxes/:owner/:name` | Read or delete one | `repo:write` or `sandbox:write` |
| `POST .../sandboxes/:owner/:name/merge` | Merge: {into?, mode?: ff\|merge\|squash, expect?, message?} | `repo:write` or `sandbox:write` |
| `POST .../sandboxes/:owner/:name/checks` | Run its on: sandbox workflows | `repo:write` or `sandbox:write` |

## Live branches

| Request | What it does | Scope |
| --- | --- | --- |
| `GET, POST, DELETE /repos/:org/:repo/live` | Live branches; turn live on ({ref}) or off (?ref=) | `live:read, live:write` |
| `GET .../live/files, .../live/tree` | A file with its version; a directory | `live:read` |
| `POST .../live/ops?ref=` | Edits: {session, ops}, at most 100 | `live:write` |
| `GET .../live/events` | Changes as server-sent events, resumable with Last-Event-ID | `live:read` |
| `POST .../live/locks, .../live/presence, .../live/checkpoint` | Soft locks, presence, a checkpoint now | `live:write` |

## Actions

| Request | What it does | Scope |
| --- | --- | --- |
| `GET /repos/:org/:repo/actions/runs` | Runs: ?workflow, ?branch, ?status, ?sha, ?limit, ?cursor | `actions:read` |
| `GET .../actions/runs/:id` | One run with its jobs | `actions:read` |
| `POST .../actions/runs/:id/cancel` | Cancel a run | `actions:write` |
| `POST .../actions/workflows/:file/dispatches` | Start a manual run: {ref, inputs} | `actions:write` |
| `GET .../commits/:sha/statuses` | A commit's statuses | `repo:read` |
| `POST .../statuses/:sha` | Post a status: {state, context, description?, target\_url?} | `statuses:write` |

## Approvals

| Request | What it does | Scope |
| --- | --- | --- |
| `POST /approvals` | Ask an owner: {kind: repo\_visibility \| agent\_create, ...} | `any token` |
| `GET /approvals/:id` | The request's state | `the token that asked` |
| `POST /approvals/:id/poll` | Poll every 5 seconds; an approved new agent's token comes back once | `the token that asked` |

> **Note:** Managing agents (`/orgs/:org/agents`) works with a signed-in owner's session only, never with a token: no token can create another.

---

Source: https://rebasely.com/docs/api
