# Changes

Generated from contract version `1.0.0` — the same document [`/v1/api/openapi.json`](/api/openapi/) serves.

## Prerequisites

- An API key in `x-api-key`, or a browser session cookie
- `X-Organization-Id` naming the workspace to act in, unless the session already has an active one
- The base URL for your deployment, `https://server.hlix.ai` by default

## Operations

| Method | Path | Operation |
| --- | --- | --- |
| `GET` | `/v1/api/projects/{id}/branches` | [List the branches of the project the Files surface can read](#list-the-branches-of-the-project-the-files-surface-can-read) |
| `GET` | `/v1/api/projects/{id}/changes` | [Get the project's changed files and checkpoint commits](#get-the-projects-changed-files-and-checkpoint-commits) |
| `GET` | `/v1/api/projects/{id}/changes/file` | [Get one changed file's unified diff](#get-one-changed-files-unified-diff) |
| `GET` | `/v1/api/projects/{id}/files` | [List every path in the project's head tree](#list-every-path-in-the-projects-head-tree) |
| `GET` | `/v1/api/projects/{id}/files/content` | [Get one file of the project's head tree](#get-one-file-of-the-projects-head-tree) |

## List the branches of the project the Files surface can read

`GET /v1/api/projects/{id}/branches` · operation ID `listProjectBranches`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `repo` | query | no | string | Which repository of a multi-repo project. Omitted, the primary one. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | ProjectBranches | The repository's default branch, the project's preview branch, then the integration branch of every cycle that dispatched work and each task's branch, newest first. Read from the project's own records, never from the repository host, so a listed branch may already be gone. Branches another project keeps in the same repository are never listed. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Browsing the repository is restricted to the agency. Every client-role collaborator is refused here, even one that may read the project's changes. |
| `404` | ApiError | No such project in this workspace, or the caller is a client collaborator with no grant on it. The project may also have no repository. |

## Get the project's changed files and checkpoint commits

`GET /v1/api/projects/{id}/changes` · operation ID `getProjectChanges`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `repo` | query | no | string | Which repository of a multi-repo project. Omitted, every repository (the primary one for a single-file read). |
| `since` | query | no | string | A 40-character commit sha to compare against instead of the default branch. |
| `ref` | query | no | string | Read this branch instead of the project's preview branch. Only a branch `GET /v1/api/projects/:id/branches` lists is accepted; any other name, another project's branch in a shared repository included, is a 404. Naming a branch is agency-only. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | ProjectChanges | What this project has changed, plus `inFlight` — one entry per RUNNING task whose coder's sandbox could be reached, carrying what that coder has written but not yet merged. A task whose box is gone or unreachable is omitted rather than reported as empty. In-flight untracked files carry `additions: null`. `source: "github"` and `source: "hlix-repos"` read committed source from the repository host while the Coding Workspace sleeps. These reads never wake or provision an environment. |
| `400` | ApiError | `since` is not a 40-character commit sha, or names no commit in this project's repository. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | With `ref`: Browsing the repository is restricted to the agency. Every client-role collaborator is refused here, even one that may read the project's changes. |
| `404` | ApiError | No such project in this workspace, or the caller is a client collaborator with no grant on it. The project may also have no connected repository. With `ref`: the project does not own that branch, or the repository no longer has it. |
| `502` | ApiError | The repository host answered neither the comparison nor the file. Nothing about the project changed; retrying is safe. |
| `504` | ApiError | The read did not finish within the request deadline (10 s). The project is unchanged; retrying is safe. |

## Get one changed file's unified diff

`GET /v1/api/projects/{id}/changes/file` · operation ID `getProjectChangeFile`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `path` | query | **yes** | string | The repository-relative file path. |
| `repo` | query | no | string | Which repository of a multi-repo project. Omitted, every repository (the primary one for a single-file read). |
| `since` | query | no | string | A 40-character commit sha to compare against instead of the default branch. |
| `taskId` | query | no | string | Read from this RUNNING task's own sandbox instead of the repository. |
| `ref` | query | no | string | Read this branch instead of the project's preview branch. Only a branch `GET /v1/api/projects/:id/branches` lists is accepted; any other name, another project's branch in a shared repository included, is a 404. Naming a branch is agency-only. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | ChangeFilePatch | One file's green/red hunks. `patch` is null for a binary file (there is no line diff to show) and also when the response byte budget dropped it — `binary` tells the two apart. `repo` narrows a multi-repo project and `since` must match the base the list was built with. `taskId` moves the whole read to that RUNNING task's own sandbox, against the commit its branch was cut from — a different machine and a different base from the project-level answer. |
| `400` | ApiError | `path` is missing or is not a repository-relative file path — it is absolute, or contains a `..` segment, a backslash, a NUL or an empty segment. `since` is not a 40-character commit sha, or names no commit in this project's repository. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such project, or that path is not in the project's change set. With `taskId`: no such task in this project, the task has no recorded branch point, or its sandbox could not be reached. With `ref`: the project does not own that branch, or the repository no longer has it. |
| `502` | ApiError | The repository host answered neither the comparison nor the file. Nothing about the project changed; retrying is safe. |
| `504` | ApiError | The read did not finish within the request deadline (10 s). The project is unchanged; retrying is safe. |

## List every path in the project's head tree

`GET /v1/api/projects/{id}/files` · operation ID `listProjectFiles`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `repo` | query | no | string | Which repository of a multi-repo project. Omitted, every repository (the primary one for a single-file read). |
| `ref` | query | no | string | Read this branch instead of the project's preview branch. Only a branch `GET /v1/api/projects/:id/branches` lists is accepted; any other name, another project's branch in a shared repository included, is a 404. Naming a branch is agency-only. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | TreeListing | Every file path in the head tree, sorted — one call, no lazy folders, because the file tree is built from the whole list. Only REGULAR files: a symlink and a submodule are excluded, and so is anything git ignores, the project's `.env` among them. `truncated: true` means the list was cut at the server's entry budget or the repository host's, so the tree shown is incomplete. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Browsing the repository is restricted to the agency. Every client-role collaborator is refused here, even one that may read the project's changes. |
| `404` | ApiError | No such project, or no such repository in it. With `ref`: the project does not own that branch, or the repository no longer has it. |
| `502` | ApiError | The repository host answered neither the comparison nor the file. Nothing about the project changed; retrying is safe. |
| `504` | ApiError | The read did not finish within the request deadline (10 s). The project is unchanged; retrying is safe. |

## Get one file of the project's head tree

`GET /v1/api/projects/{id}/files/content` · operation ID `getProjectFileContent`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `path` | query | **yes** | string | The repository-relative file path. |
| `repo` | query | no | string | Which repository of a multi-repo project. Omitted, every repository (the primary one for a single-file read). |
| `taskId` | query | no | string | Read from this RUNNING task's own sandbox instead of the repository. |
| `ref` | query | no | string | Read this branch instead of the project's preview branch. Only a branch `GET /v1/api/projects/:id/branches` lists is accepted; any other name, another project's branch in a shared repository included, is a 404. Naming a branch is agency-only. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | FileContent | The file as UTF-8 text. `binary: true` means a NUL byte was found and no text is served. `truncated: true` means the file is longer than the viewer budget, or too large to read at all — in which case `content` is null and `binary` is not a verdict. An empty file is served as `""`, never as truncated. |
| `400` | ApiError | `path` is missing or is not a repository-relative file path — it is absolute, or contains a `..` segment, a backslash, a NUL or an empty segment. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Browsing the repository is restricted to the agency. Every client-role collaborator is refused here, even one that may read the project's changes. |
| `404` | ApiError | No such project, or no such file. A path git ignores, and a path that is not a REGULAR file (a symlink or a submodule), are both treated as non-existent rather than as forbidden — a symlink's target is never read. With `ref`: the project does not own that branch, or the repository no longer has it. |
| `502` | ApiError | The repository host answered neither the comparison nor the file. Nothing about the project changed; retrying is safe. |
| `504` | ApiError | The read did not finish within the request deadline (10 s). The project is unchanged; retrying is safe. |

## If a request fails

These apply to every operation on this page.

- `400` — the body failed schema validation, or the request named no active organization. A `ValidationError` body carries the failing fields; an `ApiError` body carries only `error`.
- `401` — no valid session or API key.
- `403` — authenticated, but not a member of the named organization, or a client collaborator without the required access.
- `404` — no such resource **in this workspace**. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
- `409` — the expected revision or state is stale, or another operation currently owns the transition.
- `500` — the operation failed server-side. Retry only where an idempotency key makes that safe.

## Next steps

[API reference](/api/reference/)
  [API & OpenAPI](/api/openapi/)
  [TypeScript SDK](/sdk/typescript/)
  [CLI reference](/reference/cli/)