Linear Python SDK
There is NO official Python SDK for Linear. Linear's official SDK is TypeScript only (@linear/sdk). For Python, three competing community packages exist: linear-py, linear-api, and linear-python — none are official. The recommended approach for production Python use is raw GraphQL over HTTP. Current best community package is linear-api 0.2.0.
Warnings
- breaking There is no official Python SDK for Linear. linear-py, linear-api, and linear-python are all community packages with no official support. Linear's official SDK is TypeScript only.
- breaking GraphQL queries return 200 OK even on errors. The 'errors' array in the response must be checked explicitly — HTTP status alone does not indicate success.
- breaking OAuth apps: starting October 1 2025 all newly created OAuth apps issue refresh tokens by default. Existing apps must migrate to refresh tokens by April 1 2026 or OAuth tokens will stop working.
- breaking userPromoteAdmin, userDemoteAdmin, userPromoteMember, userDemoteMember mutations removed from GraphQL schema. Any code using these will get schema validation errors.
- gotcha Linear API token format is 'lin_api_...' — do not use Bearer prefix. Correct header is Authorization: lin_api_... not Authorization: Bearer lin_api_...
- gotcha Issue search by identifier (e.g. ENG-123) requires filtering by number first then matching identifier. Direct filter on identifier string is not supported.
- gotcha issueAddLabel mutation does not exist. Common LLM-generated code attempts to call it and gets a 400 error.
- deprecated linear-python (PyPI) is an older abandoned wrapper. Do not confuse with linear-api or linear-py.
Install
-
pip install linear-api -
pip install linear-py
Imports
- LinearClient
from linear_api import LinearClient
- Raw GraphQL (recommended)
import urllib.request # raw GraphQL over HTTP
Quickstart
import json
import urllib.request
API_KEY = 'lin_api_YOUR_KEY'
def graphql_request(query, variables=None):
data = json.dumps({'query': query, 'variables': variables or {}}).encode()
req = urllib.request.Request(
'https://api.linear.app/graphql',
data=data,
headers={
'Authorization': API_KEY,
'Content-Type': 'application/json'
}
)
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
if 'errors' in result:
raise Exception(result['errors'])
return result['data']
# Get current user
me = graphql_request('{ viewer { id name email } }')
print(me)
# Get issues for a team
query = '''
query TeamIssues($teamId: String!) {
team(id: $teamId) {
issues { nodes { id identifier title state { name } } }
}
}
'''
issues = graphql_request(query, {'teamId': 'YOUR_TEAM_ID'})