Linear issue tracking API via curl. Use this skill to create, update, and query issues, projects, and teams using GraphQL.
/plugin marketplace add vm0-ai/api0/plugin install api0@api0This skill inherits all available tools. When active, it can use any tool Claude has access to.
Use the Linear API via direct curl calls to manage issues, projects, and teams with GraphQL queries and mutations.
Official docs:
https://linear.app/developers
Use this skill when you need to:
export LINEAR_API_KEY="lin_api_..."
Linear's API is rate-limited to ensure fair usage. Limits may vary based on your plan.
Important: When using
$VARin a command that pipes to another command, wrap the command containing$VARinbash -c '...'. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly.bash -c 'curl -s "https://api.example.com" -H "Authorization: Bearer $API_KEY"' | jq .
All examples below assume you have LINEAR_API_KEY set.
Base URL: https://api.linear.app/graphql
Linear uses GraphQL for all API operations. Queries retrieve data, mutations modify data.
Get all teams in your workspace:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d '"'"'{"query": "{ teams { nodes { id name key } } }"}'"'"'' | jq '.data.teams.nodes
Save a team ID for subsequent queries.
Get issues from a specific team:
TEAM_ID="your-team-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"{ team(id: \\\"${TEAM_ID}\\\") { issues { nodes { id identifier title state { name } assignee { name } } } } }\"}"' | jq '.data.team.issues.nodes
Fetch a specific issue by its identifier (e.g., ENG-123):
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d '"'"'{"query": "{ issue(id: \"ENG-123\") { id identifier title description state { name } priority assignee { name } createdAt } }"}'"'"'' | jq '.data.issue
Search issues with filters:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d '"'"'{"query": "{ issues(filter: { state: { name: { eq: \"In Progress\" } } }, first: 10) { nodes { id identifier title assignee { name } } } }"}'"'"'' | jq '.data.issues.nodes
Create a new issue in a team:
TEAM_ID="your-team-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"mutation { issueCreate(input: { title: \\\"Bug: Login button not working\\\", description: \\\"Users report the login button is unresponsive on mobile.\\\", teamId: \\\"${TEAM_ID}\\\" }) { success issue { id identifier title url } } }\"}"' | jq '.data.issueCreate
Create an issue with additional properties:
TEAM_ID="your-team-id"
LABEL_ID="your-label-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"mutation { issueCreate(input: { title: \\\"High priority task\\\", teamId: \\\"${TEAM_ID}\\\", priority: 1, labelIds: [\\\"${LABEL_ID}\\\"] }) { success issue { id identifier title priority } } }\"}"' | jq '.data.issueCreate
Priority values: 0 (No priority), 1 (Urgent), 2 (High), 3 (Medium), 4 (Low)
Update an existing issue:
ISSUE_ID="your-issue-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"mutation { issueUpdate(id: \\\"${ISSUE_ID}\\\", input: { title: \\\"Updated title\\\", priority: 2 }) { success issue { id identifier title priority } } }\"}"' | jq '.data.issueUpdate
Move an issue to a different state (e.g., "Done"):
ISSUE_ID="your-issue-id"
STATE_ID="your-state-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"mutation { issueUpdate(id: \\\"${ISSUE_ID}\\\", input: { stateId: \\\"${STATE_ID}\\\" }) { success issue { id identifier state { name } } } }\"}"' | jq '.data.issueUpdate
Get available states for a team:
TEAM_ID="your-team-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"{ team(id: \\\"${TEAM_ID}\\\") { states { nodes { id name type } } } }\"}"' | jq '.data.team.states.nodes
Add a comment to an existing issue:
ISSUE_ID="your-issue-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"mutation { commentCreate(input: { issueId: \\\"${ISSUE_ID}\\\", body: \\\"This is a comment from the API.\\\" }) { success comment { id body createdAt } } }\"}"' | jq '.data.commentCreate
Get all projects in the workspace:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d '"'"'{"query": "{ projects { nodes { id name state progress targetDate } } }"}'"'"'' | jq '.data.projects.nodes
Get information about the authenticated user:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d '"'"'{"query": "{ viewer { id name email admin } }"}'"'"'' | jq '.data.viewer
Get available labels for a team:
TEAM_ID="your-team-id"
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d "{\"query\": \"{ team(id: \\\"${TEAM_ID}\\\") { labels { nodes { id name color } } } }\"}"' | jq '.data.team.labels.nodes
To find IDs for teams, issues, projects, etc.:
Cmd/Ctrl + K to open command menuOr use the queries above to list entities and extract their IDs.
first, after, last, before for paginated resultserrors arrayENG-123) for most queries