# Linear

See the [OpenAPI document](/openapi.json) for schemas and operation IDs.

## Prerequisites

- Protected operations require an API key in `x-api-key` or a browser session cookie; some actions require a verified user session
- Tenant-scoped operations use `X-Organization-Id`; browser sessions can use their active workspace. Discovery and personal-workspace bootstrap do not require an active workspace
- The base URL for your deployment, `https://server.hlix.ai` by default

## Operations

| Method | Path | Operation |
| --- | --- | --- |
| `GET` | `/v1/api/integrations/linear/{installId}/catalog` | [List accessible Linear teams, projects and labels](#list-accessible-linear-teams-projects-and-labels) |
| `GET` | `/v1/api/integrations/linear/bindings` | [List workspace Linear sources](#list-workspace-linear-sources) |
| `DELETE` | `/v1/api/integrations/linear/projects/{projectId}` | [Disconnect a source without changing existing cycles](#disconnect-a-source-without-changing-existing-cycles) |
| `GET` | `/v1/api/integrations/linear/projects/{projectId}` | [Read a project's Linear source](#read-a-projects-linear-source) |
| `PUT` | `/v1/api/integrations/linear/projects/{projectId}` | [Save source filters and automatic or manual start behavior](#save-source-filters-and-automatic-or-manual-start-behavior) |
| `GET` | `/v1/api/integrations/linear/projects/{projectId}/issues` | [List imported Linear issues and their work links](#list-imported-linear-issues-and-their-work-links) |
| `GET` | `/v1/api/integrations/linear/projects/{projectId}/issues/{issueId}` | [Read an imported issue with its full Linear context](#read-an-imported-issue-with-its-full-linear-context) |
| `POST` | `/v1/api/integrations/linear/projects/{projectId}/issues/{issueId}/start` | [Refresh an issue and send it to the project manager](#refresh-an-issue-and-send-it-to-the-project-manager) |
| `POST` | `/v1/api/integrations/linear/projects/{projectId}/sync` | [Import current matching open issues](#import-current-matching-open-issues) |

## List accessible Linear teams, projects and labels

`GET /v1/api/integrations/linear/{installId}/catalog` · operation ID `getLinearCatalog`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `installId` | path | **yes** | string |  |
| `teamId` | query | no | string | Team whose projects and labels to list |
| `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` | LinearCatalogResponse | Paginated provider catalog collected in full |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## List workspace Linear sources

`GET /v1/api/integrations/linear/bindings` · operation ID `listLinearBindings`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `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` | LinearBindingsResponse | Project sources |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## Disconnect a source without changing existing cycles

`DELETE /v1/api/integrations/linear/projects/{projectId}` · operation ID `deleteProjectLinearBinding`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `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` | LinearDeleteResponse | Disconnected |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## Read a project's Linear source

`GET /v1/api/integrations/linear/projects/{projectId}` · operation ID `getProjectLinearBinding`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `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` | LinearBindingResponse | Source or null |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## Save source filters and automatic or manual start behavior

`PUT /v1/api/integrations/linear/projects/{projectId}` · operation ID `saveProjectLinearBinding`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `LinearBindingInput` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `enabled` | boolean | **yes** |  |
| `installationId` | string | **yes** | min length 1 |
| `labelId` | string \| null | **yes** |  |
| `linearProjectId` | string \| null | **yes** |  |
| `mode` | `automatic` \| `manual` | no |  |
| `teamId` | string | **yes** | min length 1 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | LinearBindingResponse | Saved source; existing issues are imported explicitly |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## List imported Linear issues and their work links

`GET /v1/api/integrations/linear/projects/{projectId}/issues` · operation ID `listProjectLinearIssues`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |
| `X-Client-Portal` | header | no | string | The agency Workspace ID for a signed-in client's portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | LinearIssuesResponse | Imported issues |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## Read an imported issue with its full Linear context

`GET /v1/api/integrations/linear/projects/{projectId}/issues/{issueId}` · operation ID `getProjectLinearIssue`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `issueId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |
| `X-Client-Portal` | header | no | string | The agency Workspace ID for a signed-in client's portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | LinearIssueResponse | Issue, comments, attachments and related context |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## Refresh an issue and send it to the project manager

`POST /v1/api/integrations/linear/projects/{projectId}/issues/{issueId}/start` · operation ID `startProjectLinearIssue`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `issueId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |
| `X-Client-Portal` | header | no | string | The agency Workspace ID for a signed-in client's portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | LinearStartResponse | Durable work proposal |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## Import current matching open issues

`POST /v1/api/integrations/linear/projects/{projectId}/sync` · operation ID `syncProjectLinearIssues`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `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` | LinearSyncResponse | Import result |
| `400` | ApiError | The request named no active organization. |
| `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 | Project or connection unavailable |
| `409` | ApiError | Source changed, overlaps another project, or work cannot start |
| `502` | ApiError | Linear connection request failed |

## If a request fails

The response table for each operation lists its documented errors. Common status codes include:

- `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` — check the resource ID and your access to the selected Workspace.
- `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/)