A command-line interface to interact with the Linear API from your terminal. Manage issues, projects, cycles, documents, and more without leaving the shell.
- Deno v2+
- A Linear API key (Settings → API → Personal API keys)
Set your Linear API key as an environment variable:
export LINEAR_API_KEY="lin_api_xxxxx"To make it permanent, add the line to your ~/.zshrc or ~/.bashrc.
deno task dev <command> [subcommand] [options]| Subcommand | Description | Arguments | Options |
|---|---|---|---|
team list |
List all teams | — | — |
team get |
Get a team by ID | <id> |
— |
Examples:
deno task dev team list
deno task dev team get <team-id>| Subcommand | Description | Arguments | Options |
|---|---|---|---|
user get |
Get a user by ID (or "me" for the authenticated user) |
<id> |
— |
user list |
List users | — | --first <count> |
Examples:
deno task dev user get me
deno task dev user list --first 20| Subcommand | Description | Arguments | Options |
|---|---|---|---|
issue list |
List issues | — | --first <count>, --team <teamId>, --assignee <userId>, --state <stateId>, --cycle <cycleId>, --project <projectId>, --label <labelId>, --priority <0-4>, --parent <issueId> |
issue get |
Get an issue by ID | <id> |
— |
issue create |
Create a new issue | — | --title <title> (required), --team-id <teamId> (required), --description <desc>, --priority <0-4>, --assignee-id <userId>, --state-id <stateId>, --label-ids <ids...>, --cycle-id <cycleId>, --due-date <YYYY-MM-DD>, --estimate <n>, --parent-id <issueId>, --project-id <projectId>, --project-milestone-id <id>, --subscriber-ids <ids...>, --sort-order <n>, --priority-sort-order <n> |
issue update |
Update an issue | <id> |
--title <title>, --description <desc>, --priority <0-4>, --assignee-id <userId>, --state-id <stateId>, --parent-id <issueId>, --cycle-id <cycleId>, --due-date <YYYY-MM-DD>, --estimate <n>, --project-id <projectId>, --project-milestone-id <id>, --label-ids <ids...>, --added-label-ids <ids...>, --removed-label-ids <ids...>, --subscriber-ids <ids...>, --team-id <teamId>, --sort-order <n>, --priority-sort-order <n>, --snoozed-until-at <datetime>, --sub-issue-sort-order <n> |
issue delete |
Delete an issue | <id> |
— |
issue download |
Download inline uploaded files from an issue's description and comments | <id> |
--output <dir> |
issue archive |
Archive an issue | <id> |
— |
issue search |
Search issues | <term> |
--first <count> |
Examples:
deno task dev issue list --first 10 --team <team-id>
deno task dev issue create --title "My issue" --team-id <team-id> --priority 2
deno task dev issue update <issue-id> --title "New title" --state-id <state-id>
# Make an issue a sub-issue of another
deno task dev issue update <issue-id> --parent-id <parent-issue-id>
deno task dev issue delete <issue-id>
deno task dev issue download <issue-id>
deno task dev issue download <issue-id> --output ./tmp/files
deno task dev issue archive <issue-id>
deno task dev issue search "bug" --first 20| Subcommand | Description | Arguments | Options |
|---|---|---|---|
comment list |
List comments | — | --issue-id <issueId>, --first <count> |
comment get |
Get a comment by ID | <id> |
— |
comment create |
Create a comment | — | --issue-id <issueId> (required), --body <body> (required), --parent-id <commentId>, --project-update-id <id>, --document-content-id <id> |
comment update |
Update a comment | <id> |
--body <body>, --resolved, --unresolved |
comment resolve |
Resolve a comment | <id> |
— |
comment delete |
Delete a comment | <id> |
— |
Examples:
deno task dev comment list --issue-id <issue-id>
deno task dev comment create --issue-id <issue-id> --body "My comment"
deno task dev comment update <comment-id> --body "Updated comment"
deno task dev comment resolve <comment-id>
deno task dev comment delete <comment-id>| Subcommand | Description | Arguments | Options |
|---|---|---|---|
issue-label list |
List issue labels | — | --first <count>, --team-id <teamId> |
issue-label get |
Get a label by ID | <id> |
— |
issue-label create |
Create a label | — | --name <name> (required), --team-id <teamId>, --color <color>, --description <desc>, --parent-id <id>, --is-group |
issue-label update |
Update a label | <id> |
--name <name>, --color <color>, --description <desc>, --parent-id <id>, --is-group |
issue-label delete |
Delete a label | <id> |
— |
Examples:
deno task dev issue-label list --team-id <team-id>
deno task dev issue-label create --name "Bug" --team-id <team-id> --color "#ff0000"
deno task dev issue-label update <label-id> --color "#00ff00"
deno task dev issue-label delete <label-id>| Subcommand | Description | Arguments | Options |
|---|---|---|---|
project list |
List projects | — | --first <count>, --team <teamId>, --state <state>, --lead <leadId> |
project get |
Get a project by ID | <id> |
— |
project create |
Create a project | — | --name <name> (required), --team-ids <ids...> (required), --description <desc>, --state <state>, --lead-id <id>, --start-date <date>, --target-date <date>, --color <color>, --icon <icon>, --member-ids <ids...>, --priority <0-4>, --status-id <id>, --content <markdown>, --sort-order <n>, --priority-sort-order <n> |
project update |
Update a project | <id> |
--name <name>, --description <desc>, --state <state>, --lead-id <id>, --start-date <date>, --target-date <date>, --color <color>, --icon <icon>, --member-ids <ids...>, --priority <0-4>, --status-id <id>, --content <markdown>, --team-ids <ids...>, --sort-order <n>, --priority-sort-order <n> |
project delete |
Delete a project | <id> |
— |
project archive |
Archive a project | <id> |
— |
project search |
Search projects | <term> |
--first <count> |
Examples:
deno task dev project list --first 10
deno task dev project create --name "My project" --team-ids <team-id>
deno task dev project update <project-id> --state "started"
deno task dev project delete <project-id>
deno task dev project search "redesign"| Subcommand | Description | Arguments | Options |
|---|---|---|---|
cycle list |
List cycles | — | --first <count>, --team <teamId> |
cycle get |
Get a cycle by ID | <id> |
— |
cycle create |
Create a cycle | — | --team-id <teamId> (required), --starts-at <date> (required), --ends-at <date> (required), --name <name>, --description <desc> |
cycle update |
Update a cycle | <id> |
--name <name>, --description <desc>, --starts-at <date>, --ends-at <date> |
cycle archive |
Archive a cycle | <id> |
— |
Examples:
deno task dev cycle list --team <team-id>
deno task dev cycle create --team-id <team-id> --starts-at 2025-01-01 --ends-at 2025-01-14
deno task dev cycle archive <cycle-id>| Subcommand | Description | Arguments | Options |
|---|---|---|---|
workflow-state list |
List states | — | --first <count>, --team <teamId>, --type <type> |
workflow-state get |
Get a state by ID | <id> |
— |
workflow-state create |
Create a state | — | --name <name> (required), --team-id <teamId> (required), --type <type> (required), --color <color> (required), --description <desc>, --position <n> |
workflow-state update |
Update a state | <id> |
--name <name>, --color <color>, --description <desc>, --position <n> |
workflow-state archive |
Archive a state | <id> |
— |
State types: backlog, unstarted, started, completed, cancelled
Examples:
deno task dev workflow-state list --team <team-id> --type started
deno task dev workflow-state create --name "In Review" --team-id <team-id> --type started --color "#f0c000"| Subcommand | Description | Arguments | Options |
|---|---|---|---|
document list |
List documents | — | --first <count>, --project <projectId> |
document get |
Get a document by ID | <id> |
— |
document create |
Create a document | — | --title <title> (required), --content <content>, --project-id <id>, --icon <icon>, --color <color>, --issue-id <issueId>, --sort-order <n> |
document update |
Update a document | <id> |
--title <title>, --content <content>, --project-id <id>, --icon <icon>, --color <color>, --issue-id <issueId>, --sort-order <n> |
document delete |
Delete a document | <id> |
— |
document search |
Search documents | <term> |
--first <count> |
Examples:
deno task dev document list --project <project-id>
deno task dev document create --title "RFC: New Feature" --content "## Summary\n..."
deno task dev document search "architecture"| Subcommand | Description | Arguments | Options |
|---|---|---|---|
initiative list |
List initiatives | — | --first <count> |
initiative get |
Get an initiative | <id> |
— |
initiative create |
Create an initiative | — | --name <name> (required), --description <desc>, --color <color>, --icon <icon>, --owner-id <userId>, --status <status>, --target-date <YYYY-MM-DD>, --content <markdown>, --sort-order <n> |
initiative update |
Update an initiative | <id> |
--name <name>, --description <desc>, --status <status>, --color <color>, --icon <icon>, --owner-id <userId>, --target-date <YYYY-MM-DD>, --content <markdown>, --sort-order <n> |
initiative delete |
Delete an initiative | <id> |
— |
initiative archive |
Archive an initiative | <id> |
— |
Examples:
deno task dev initiative list
deno task dev initiative create --name "Q1 Goals" --color "#3b82f6"| Subcommand | Description | Arguments | Options |
|---|---|---|---|
roadmap list |
List roadmaps | — | --first <count> |
roadmap get |
Get a roadmap | <id> |
— |
roadmap create |
Create a roadmap | — | --name <name> (required), --description <desc>, --color <color>, --owner-id <userId>, --sort-order <n> |
roadmap update |
Update a roadmap | <id> |
--name <name>, --description <desc>, --color <color>, --owner-id <userId>, --sort-order <n> |
roadmap delete |
Delete a roadmap | <id> |
— |
roadmap archive |
Archive a roadmap | <id> |
— |
Examples:
deno task dev roadmap list
deno task dev roadmap create --name "2025 Roadmap"| Subcommand | Description | Arguments | Options |
|---|---|---|---|
project-milestone list |
List milestones | — | --first <count>, --project <projectId> |
project-milestone get |
Get a milestone | <id> |
— |
project-milestone create |
Create a milestone | — | --name <name> (required), --project-id <id> (required), --description <desc>, --target-date <date>, --sort-order <n> |
project-milestone update |
Update a milestone | <id> |
--name <name>, --description <desc>, --target-date <date>, --sort-order <n>, --project-id <id> |
project-milestone delete |
Delete a milestone | <id> |
— |
Examples:
deno task dev project-milestone list --project <project-id>
deno task dev project-milestone create --name "Beta" --project-id <project-id> --target-date 2025-03-01| Subcommand | Description | Arguments | Options |
|---|---|---|---|
project-update list |
List project updates | — | --first <count>, --project <projectId> |
project-update get |
Get a project update | <id> |
— |
project-update create |
Create a project update | — | --project-id <id> (required), --body <body> (required), --health <health> |
project-update update |
Update a project update | <id> |
--body <body>, --health <health>, --is-diff-hidden |
project-update delete |
Delete a project update | <id> |
— |
Health values: onTrack, atRisk, offTrack
Examples:
deno task dev project-update list --project <project-id>
deno task dev project-update create --project-id <project-id> --body "Sprint went well" --health onTrack| Subcommand | Description | Arguments | Options |
|---|---|---|---|
issue-relation list |
List relations | — | --first <count> |
issue-relation get |
Get a relation | <id> |
— |
issue-relation create |
Create a relation | — | --issue-id <id> (required), --related-issue-id <id> (required), --type <type> (required) |
issue-relation update |
Update a relation | <id> |
--type <type>, --issue-id <issueId>, --related-issue-id <issueId> |
issue-relation delete |
Delete a relation | <id> |
— |
Relation types: blocks, duplicate, related, similar
Examples:
# Issue A blocks Issue B
deno task dev issue-relation create --issue-id <issue-a-id> --related-issue-id <issue-b-id> --type blocks
# Issue A is blocked by Issue B (reverse the IDs, still use "blocks")
deno task dev issue-relation create --issue-id <issue-b-id> --related-issue-id <issue-a-id> --type blocks
# Mark Issue B as a duplicate of Issue A
deno task dev issue-relation create --issue-id <issue-a-id> --related-issue-id <issue-b-id> --type duplicate
# Link two related issues
deno task dev issue-relation create --issue-id <issue-a-id> --related-issue-id <issue-b-id> --type related| Subcommand | Description | Arguments | Options |
|---|---|---|---|
webhook list |
List webhooks | — | --first <count> |
webhook get |
Get a webhook | <id> |
— |
webhook create |
Create a webhook | — | --url <url> (required), --resource-types <types...> (required), --label <label>, --team-id <id>, --all-public-teams, --enabled <bool>, --secret <secret> |
webhook update |
Update a webhook | <id> |
--url <url>, --label <label>, --enabled <bool>, --resource-types <types...>, --secret <secret> |
Examples:
deno task dev webhook list
deno task dev webhook create --url "https://example.com/hook" --resource-types Issue Comment| Subcommand | Description | Arguments | Options |
|---|---|---|---|
notification list |
List notifications | — | --first <count> |
notification get |
Get a notification | <id> |
— |
notification update |
Update a notification | <id> |
--read-at <date>, --snoozed-until-at <date> |
notification archive |
Archive a notification | <id> |
— |
Examples:
deno task dev notification list --first 10
deno task dev notification archive <notification-id>| Subcommand | Description | Arguments | Options |
|---|---|---|---|
attachment list |
List attachments | — | --first <count> |
attachment get |
Get an attachment | <id> |
— |
attachment create |
Create an attachment | — | --issue-id <id> (required), --url <url> (required), --title <title> (required), --subtitle <subtitle>, --comment-body <body>, --icon-url <url>, --group-by-source |
attachment update |
Update an attachment | <id> |
--title <title>, --subtitle <subtitle>, --url <url>, --icon-url <url> |
attachment delete |
Delete an attachment | <id> |
— |
Examples:
deno task dev attachment list --first 20
deno task dev attachment create --issue-id <issue-id> --url "https://example.com/file.pdf" --title "Design spec"The scripts/ directory contains convenience scripts that wrap common
workflows. These files are gitignored to protect API keys.
Prerequisites: source a workspace wrapper first (
linear-work.shorlinear-perso.sh) or haveLINEAR_API_KEYset, and have the compiledlinearbinary in the current directory.
./scripts/comments.sh <TICKET_NUMBER>
# ex: ./scripts/comments.sh DAU-42outputs a hierarchical Markdown view of all comments (author, ID, content, resolved status).
./scripts/write-comment.sh <TICKET_NUMBER> --comment "comment body"
# ex: ./scripts/write-comment.sh DAU-42 --comment "LGTM!"./scripts/resolve-comment.sh --commentId <COMMENT_ID>
# ex: ./scripts/resolve-comment.sh --commentId 138d65eb-250a-4efa-9141-f7774d874c63Uses the dedicated commentResolve Linear API mutation (not updateComment).
source scripts/linear-work.sh # set API key
./scripts/project.sh <TICKET_NUMBER>
# ex: ./scripts/project.sh DAU-42Outputs user info, team info, available workflow states, and the full ticket details.
# Create: TICKET_A blocks TICKET_B
./scripts/block.sh <TICKET_A> --blocks <TICKET_B>
# ex: ./scripts/block.sh DAU-10 --blocks DAU-42
# Create: TICKET_A is blocked by TICKET_B
./scripts/block.sh <TICKET_A> --blocked-by <TICKET_B>
# ex: ./scripts/block.sh DAU-42 --blocked-by DAU-10
# Remove: the "TICKET_A blocks TICKET_B" relation
./scripts/block.sh <TICKET_A> --unblocks <TICKET_B>
# ex: ./scripts/block.sh DAU-10 --unblocks DAU-42
# Remove: the "TICKET_B blocks TICKET_A" relation
./scripts/block.sh <TICKET_A> --unblocked-by <TICKET_B>
# ex: ./scripts/block.sh DAU-42 --unblocked-by DAU-10The forms --blocks/--blocked-by and --unblocks/--unblocked-by are
symmetrical — they designate the same relation, formulated from the point of
view of each ticket.
Deno can compile the project into a standalone native binary — no dependencies required on the target machine.
deno compile --allow-env --allow-net --allow-read --allow-write --output linear main.tsThis produces a linear executable in the current directory. --allow-read and
--allow-write are required by issue download (file output).
# macOS Apple Silicon (M1/M2/M3)
deno compile --allow-env --allow-net --allow-read --allow-write --target aarch64-apple-darwin --output linear-macos-arm64 main.ts
# macOS Intel
deno compile --allow-env --allow-net --allow-read --allow-write --target x86_64-apple-darwin --output linear-macos-x64 main.ts
# Linux x64
deno compile --allow-env --allow-net --allow-read --allow-write --target x86_64-unknown-linux-gnu --output linear-linux main.ts
# Windows x64
deno compile --allow-env --allow-net --allow-read --allow-write --target x86_64-pc-windows-msvc --output linear-windows.exe main.tsexport LINEAR_API_KEY="lin_api_xxxxx"
./linear team list
./linear issue list --first 5
./linear cycle list --team <team-id># Option 1: /usr/local/bin (requires sudo)
sudo cp ./linear /usr/local/bin/linear
# Option 2: user-local directory (no sudo)
mkdir -p ~/.local/bin
cp ./linear ~/.local/bin/linear
# Make sure ~/.local/bin is in your PATH:
# export PATH="$HOME/.local/bin:$PATH"Then simply run:
linear issue listTo use multiple Linear workspaces with different API keys, create wrapper
scripts in the scripts/ directory:
scripts/linear-work.sh
#!/bin/bash
export LINEAR_API_KEY="lin_api_YOUR_WORK_KEY"
exec ./linear "$@"scripts/linear-perso.sh
#!/bin/bash
export LINEAR_API_KEY="lin_api_YOUR_PERSONAL_KEY"
exec ./linear "$@"Make them executable:
chmod +x scripts/linear-work.sh scripts/linear-perso.shUsage:
./scripts/linear-work.sh issue list
./scripts/linear-perso.sh team listFiles in the
scripts/directory are gitignored to protect your API keys.
linear-cli/
├── main.ts # Entry point
├── deno.json # Deno configuration & dependencies
├── deno.lock # Dependency lockfile
├── scripts/ # Wrapper scripts (gitignored)
└── src/
├── client.ts # Linear client (singleton)
├── errors.ts # Centralized error handling
├── output.ts # JSON formatting utilities
└── commands/
├── team/ # list, get
├── user/ # get, list
├── issue/ # list, get, create, update, delete, archive, search
├── comment/ # list, get, create, update, resolve, delete
├── issue-label/ # list, get, create, update, delete
├── project/ # list, get, create, update, delete, archive, search
├── cycle/ # list, get, create, update, archive
├── workflow-state/ # list, get, create, update, archive
├── document/ # list, get, create, update, delete, search
├── initiative/ # list, get, create, update, delete, archive
├── roadmap/ # list, get, create, update, delete, archive
├── project-milestone/ # list, get, create, update, delete
├── project-update/ # list, get, create, update, delete
├── issue-relation/ # list, get, create, update, delete
├── webhook/ # list, get, create, update
├── notification/ # list, get, update, archive
└── attachment/ # list, get, create, update, delete
| Command | Description |
|---|---|
deno task dev |
Run the CLI in development mode |
deno task check |
Type-check TypeScript |
deno task lint |
Run the linter |
deno task fmt |
Format the code |
Private project.