| name | linear |
| description | Linear issue tracking API via curl. Use this skill to create, update, and query issues, projects, and teams using GraphQL. |
| vm0_secrets | LINEAR_API_KEY |
Linear API
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
When to Use
Use this skill when you need to:
- Query issues from Linear workspaces
- Create new issues with title, description, and assignments
- Update issue status and properties
- List teams and projects in an organization
- Add comments to issues
- Search issues with filters
Prerequisites
- Log in to Linear and go to Settings
- Navigate to Security & access → Personal API keys
- Create a new API key with appropriate permissions
export LINEAR_API_KEY="lin_api_..."
Rate Limits
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 .
How to Use
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.
1. List Teams
Get all teams in your workspace:
Write to /tmp/linear_request.json:
{
"query": "{ teams { nodes { id name key } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.teams.nodes'
Save a team ID for subsequent queries.
2. List Issues for a Team
Get issues from a specific team:
TEAM_ID="your-team-id"
Write to /tmp/linear_request.json:
{
"query": "{ team(id: \"${TEAM_ID}\") { issues { nodes { id identifier title state { name } assignee { name } } } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.team.issues.nodes'
3. Get Issue by Identifier
Fetch a specific issue by its identifier (e.g., ENG-123):
Write to /tmp/linear_request.json:
{
"query": "{ issue(id: \"ENG-123\") { id identifier title description state { name } priority assignee { name } createdAt } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.issue'
4. Search Issues
Search issues with filters:
Write to /tmp/linear_request.json:
{
"query": "{ issues(filter: { state: { name: { eq: \"In Progress\" } } }, first: 10) { nodes { id identifier title assignee { name } } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.issues.nodes'
5. Create Issue
Create a new issue in a team:
TEAM_ID="your-team-id"
Write to /tmp/linear_request.json:
{
"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 } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.issueCreate'
6. Create Issue with Priority and Labels
Create an issue with additional properties:
TEAM_ID="your-team-id"
LABEL_ID="your-label-id"
Write to /tmp/linear_request.json:
{
"query": "mutation { issueCreate(input: { title: \"High priority task\", teamId: \"${TEAM_ID}\", priority: 1, labelIds: [\"${LABEL_ID}\"] }) { success issue { id identifier title priority } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.issueCreate'
Priority values: 0 (No priority), 1 (Urgent), 2 (High), 3 (Medium), 4 (Low)
7. Update Issue
Update an existing issue:
ISSUE_ID="your-issue-id"
Write to /tmp/linear_request.json:
{
"query": "mutation { issueUpdate(id: \"${ISSUE_ID}\", input: { title: \"Updated title\", priority: 2 }) { success issue { id identifier title priority } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.issueUpdate'
8. Change Issue State
Move an issue to a different state (e.g., "Done"):
ISSUE_ID="your-issue-id"
STATE_ID="your-state-id"
Write to /tmp/linear_request.json:
{
"query": "mutation { issueUpdate(id: \"${ISSUE_ID}\", input: { stateId: \"${STATE_ID}\" }) { success issue { id identifier state { name } } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.issueUpdate'
9. List Workflow States
Get available states for a team:
TEAM_ID="your-team-id"
Write to /tmp/linear_request.json:
{
"query": "{ team(id: \"${TEAM_ID}\") { states { nodes { id name type } } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.team.states.nodes'
10. Add Comment to Issue
Add a comment to an existing issue:
ISSUE_ID="your-issue-id"
Write to /tmp/linear_request.json:
{
"query": "mutation { commentCreate(input: { issueId: \"${ISSUE_ID}\", body: \"This is a comment from the API.\" }) { success comment { id body createdAt } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.commentCreate'
11. List Projects
Get all projects in the workspace:
Write to /tmp/linear_request.json:
{
"query": "{ projects { nodes { id name state progress targetDate } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.projects.nodes'
12. Get Current User
Get information about the authenticated user:
Write to /tmp/linear_request.json:
{
"query": "{ viewer { id name email admin } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.viewer'
13. List Labels
Get available labels for a team:
TEAM_ID="your-team-id"
Write to /tmp/linear_request.json:
{
"query": "{ team(id: \"${TEAM_ID}\") { labels { nodes { id name color } } } }"
}
Then run:
bash -c 'curl -s -X POST "https://api.linear.app/graphql" -H "Content-Type: application/json" -H "Authorization: ${LINEAR_API_KEY}" -d @/tmp/linear_request.json' | jq '.data.team.labels.nodes'
Finding IDs
To find IDs for teams, issues, projects, etc.:
- Open Linear app
- Press
Cmd/Ctrl + Kto open command menu - Type "Copy model UUID"
- Select the entity to copy its ID
Or use the queries above to list entities and extract their IDs.
Guidelines
- Use GraphQL variables: For production, use variables instead of string interpolation for better security
- Handle pagination: Use
first,after,last,beforefor paginated results - Check for errors: GraphQL returns 200 even with errors; always check the
errorsarray - Rate limiting: Implement backoff if you receive rate limit errors
- Batch operations: Combine multiple queries in one request when possible
- Issue identifiers: You can use either UUID or readable identifier (e.g.,
ENG-123) for most queries