> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orchestrahq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Linear issue sync

> Connect Linear once; your issues stay in Orchestra automatically

Connect Linear once. From then on your issues appear in Orchestra and stay
current (new issues, edits, status changes, reassignments) without anyone
running a command.

A synced issue is a real Orchestra work item. It carries its Linear key as its
ref, keeps a link back to Linear, and lands already connected to the sessions and
commits that mention it, because Orchestra has been recording those references
all along.

> [!NOTE]
>
> **A copy you can change.** Synced issues and projects are copies inside
> Orchestra. Change their status, assignee, priority, title or project, comment
> on them, move issues between projects, rename or archive a project, or delete
> any of them, all from Orchestra. Nothing is written back to Linear: your
> changes stay in Orchestra, and Linear keeps its own.

## Your changes win

When Linear syncs an item again, Orchestra keeps every field you changed here
exactly as you set it, and keeps updating every field nobody touched. Rename an
issue here and later rename it in Linear: Orchestra keeps your name. Leave its
description alone and edit it in Linear: Orchestra follows Linear.

Deleting works the same way. Delete a synced issue or project in Orchestra and
it stays deleted, even though it still exists in Linear and Linear keeps
syncing it. A deleted project's issues stay, in no project.

## Connect

The usual way is **Settings, Integrations** in the app, or the Linear step of
workspace setup: choose **Connect Linear**, and approve on Linear's own screen.
Orchestra asks Linear for one thing, read access, which it uses to read your
teams, issues, projects and comments. It never creates, edits or deletes
anything in Linear. Every public team in your Linear workspace is synced.

The authorization belongs to the workspace, not to one person's API key: it
keeps working when the person who connected it leaves. Orchestra keeps it
encrypted on the server and renews it as Linear requires; it is never sent to
your browser. Disconnecting gives it back to Linear.

The page then shows which Linear workspace you are connected to, the last
sync, any error, and whether live updates are on, with **Resync** to pull again
right away.

> [!NOTE]
>
> **Connected with an API key before?** That connection keeps working exactly as
> it did. Settings offers **Switch to Linear sign-in**: approving on Linear
> replaces the stored key with the workspace's authorization and removes the
> webhook the key registered. Nothing already synced changes.

From a terminal, for headless setups and scripting, a key still works:

```sh theme={null}
orchestra connect linear             # every public team
orchestra connect linear --team ENG  # one team
```

That is the whole setup. It validates your API key against Linear, stores it
encrypted, runs a first full sync, and hands the job to the background watcher.

* `--team` is your Linear team key (the `ENG` in `ENG-123`). Without it, every
  team the key can see that is not private is synced.
* `--key lin_api_…` passes the credential explicitly. Without it, Orchestra reads
  `LINEAR_API_KEY` from the environment. Create a key at
  [linear.app/settings/api](https://linear.app/settings/api).

## Then nothing

After connecting, Orchestra syncs every few minutes by itself. There is no
command to run and no job to schedule.

## Check it is working

```sh theme={null}
orchestra status     # last sync, item counts, failures
orchestra doctor     # the deep check: connection, watermark, circuit breaker
```

A healthy integration reads like this:

```
Integrations:   linear: last sync 2m ago, 62 item(s) synced
```

A broken one says so plainly, which is the point:

```
Integrations:   linear: FAILING as of 4m ago: Linear API 401: invalid API key
```

Orchestra treats a silently dead integration as the failure worth engineering
against. After repeated failures it stops calling Linear, backs off
exponentially, and surfaces the error rather than retrying forever in silence. A
revoked key trips that immediately instead of after five attempts, because a
revoked key is never going to start working on its own.

## Private teams are never synced

A synced issue is visible to everyone in your Orchestra workspace. An issue in
a **private** Linear team is visible only to that team's members. So Orchestra
never syncs a private team: naming one with `--team` is refused, a
workspace-wide connection skips them, and Settings lists the teams it left
alone so the gap is visible rather than silent.

## Live updates

When you connect, Orchestra registers a Linear webhook for your public teams,
signed with a secret it keeps encrypted beside your API key. Changes then
arrive in seconds: issues, comments, projects and labels.

* Every delivery is checked against that secret, over the exact bytes Linear
  sent. A delivery older than a minute is refused as a possible replay.
* A delivery is treated as a signal, not as data: Orchestra fetches the issue or
  project from Linear and writes it exactly as a scheduled pull would. A late or
  repeated delivery therefore applies the current state, and changes nothing the
  second time.
* Registering a webhook needs admin rights in Linear. A connection made on
  Linear's screen asks only to read, so its live updates are off, Settings says
  so, and changes arrive with the sync every few minutes. With an ordinary
  key, live updates stay off too, Settings says why, and the scheduled sync still
  keeps everything current within a few minutes.
* Disconnecting removes the webhook from Linear.

The webhook address is shown in Settings.

## What syncs

| | |
| - | - |
| **Identity** | Issue key (`ENG-123`) becomes the item's ref; the Linear issue id is the stable internal key |
| **Content** | Title, description, and comments (the first fifty per issue) |
| **Projects** | Each Linear project appears as a project in Orchestra, with its issues in it. Rename, archive or delete it here, and move issues in or out; those changes stay in Orchestra |
| **Status** | Mapped to Orchestra's four statuses, with Linear's own workflow name kept alongside |
| **People** | Assignee and comment authors, matched to an Orchestra member by email when one matches |
| **Metadata** | Priority, labels, URL, timestamps |
| **Archived and deleted** | An issue archived or deleted in Linear leaves Orchestra's lists; its page still answers |
| **Provenance** | Source marker (`linear`, external id, URL) so the UI can link back |

**What does not sync:** attachments, sub-issues, relations, cycles, estimates,
and issue history. Nothing is written back to Linear, except registering the
webhook when you connect: changes you make here stay in Orchestra.

### Rate limits

When Linear says to slow down, Orchestra waits exactly as long as Linear asked
before calling again, and deliveries that arrive meanwhile are caught up by the
next pull.

### Status mapping

Linear's workflow state types map onto Orchestra's fixed set:

| Linear state type | Orchestra status |
| - | - |
| `triage`, `backlog`, `unstarted` | `backlog` |
| `started` | `doing` (or `in_review` when the state is named for review) |
| `completed` | `done` |
| `canceled`, `duplicate` | `done` |

Canceled issues land in `done` because Orchestra has no terminal-but-unfinished
status yet. The real Linear state name travels with the item, so a canceled issue
still reads "Canceled" rather than claiming it was completed.

If your team's workflow needs different treatment, a per-connection override map
keyed on the Linear state name takes precedence over this table.

### Assignees

When a Linear user's email matches a known Orchestra identity, the item is
assigned to that person and the link is remembered, so later syncs match
directly.

When no one matches, the item stays **unassigned** and records the Linear display
name. Orchestra does not invent people who have never used it: that would quietly
fill your People list with strangers.

## Two refs, no migration

Orchestra items created natively get refs like `W-7`. Synced issues keep their
tracker key: `ENG-123`. Both live in the same list, and neither is converted into
the other.

The native prefix is one letter on purpose. Orchestra's ticket-key extractor
requires at least two leading characters, so `W-7` in a commit message can never
be mistaken for a tracker issue, while `ENG-123` is recognized, which is exactly
what links your existing sessions and commits to a synced issue the moment it
arrives.

## Disconnecting

In **Settings**, **Integrations**, choose **Disconnect**. Syncing and live
updates stop, and Orchestra deletes its authorization or key. Issues already
synced stay as items: disconnecting does not delete your team's work.

Keys and authorizations are stored encrypted, are never written to Orchestra's
history, and are never shown again after you save them.

## Syncing again now

**Resync** in Settings pulls right away. From a terminal:

```sh theme={null}
orchestra sync linear --dry-run          # show what would change, write nothing
orchestra sync linear --full             # re-read everything
```

Running it is harmless at any time: it ends at the same result as the
scheduled sync.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.