Linear Python SDK
raw JSON → 0.2.0 verified Tue May 12 auth: no python install: verified quickstart: verified
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.
pip install linear-api Common errors
error ModuleNotFoundError: No module named 'linear_python' ↓
cause The 'linear-python' package is not installed in the current Python environment.
fix
Install the package using pip:
pip install linear-python. error linear_python.exceptions.LinearAPIError: 401 Unauthorized ↓
cause The Linear API key or authentication token provided to the 'linear-python' client is invalid, missing, or lacks the necessary permissions.
fix
Ensure your Linear API key is correctly configured as an environment variable (e.g.,
LINEAR_API_KEY) or passed directly to the LinearClient constructor, and verify its validity and scopes in your Linear settings. error AttributeError: 'LinearClient' object has no attribute 'create_issue' ↓
cause The method or attribute being called (e.g., `create_issue`) does not exist on the `LinearClient` object, or its name is different, indicating an incorrect usage of the 'linear-python' library.
fix
Consult the 'linear-python' library's source code or any available documentation to find the correct method names and usage patterns, or consider using a more actively maintained library like
linear-api. error linear_python.exceptions.LinearAPIError: 400 Bad Request: GraphQL validation error: Field 'title' is required. ↓
cause The request made through 'linear-python' to the Linear API is missing a required field or contains data that does not conform to the Linear GraphQL schema.
fix
Examine the specific error message to identify the missing or invalid field, and adjust your 'linear-python' call to provide the correct data according to the Linear API's GraphQL schema.
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. ↓
fix Use raw GraphQL over HTTP for production. Use linear-api for prototyping if you want an ORM-style wrapper.
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. ↓
fix Always check 'if errors in result' before accessing result['data'].
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. ↓
fix Implement refresh token flow before April 1 2026. See Linear OAuth developer documentation.
breaking userPromoteAdmin, userDemoteAdmin, userPromoteMember, userDemoteMember mutations removed from GraphQL schema. Any code using these will get schema validation errors. ↓
fix Use the current user role management mutations in the schema.
gotcha Linear API token format is 'lin_api_...' — do not use Bearer prefix. Correct header is Authorization: lin_api_... not Authorization: Bearer lin_api_... ↓
fix headers = {'Authorization': 'lin_api_YOUR_KEY'} — no Bearer prefix.
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. ↓
fix Filter by number: {'number': {'eq': 123}} then match exact identifier in results.
gotcha issueAddLabel mutation does not exist. Common LLM-generated code attempts to call it and gets a 400 error. ↓
fix Use issueUpdate with labelIds array instead.
deprecated linear-python (PyPI) is an older abandoned wrapper. Do not confuse with linear-api or linear-py. ↓
fix Use linear-api for community wrapper or raw GraphQL.
Install
pip install linear-py Install compatibility verified last tested: 2026-05-12
python os / libc variant status wheel install import disk
3.10 alpine (musl) linear-api - - - -
3.10 alpine (musl) linear-py - - - -
3.10 slim (glibc) linear-api - - - -
3.10 slim (glibc) linear-py - - - -
3.11 alpine (musl) linear-api - - 1.64s 93.5M
3.11 alpine (musl) linear-py - - - -
3.11 slim (glibc) linear-api - - 1.38s 164M
3.11 slim (glibc) linear-py - - - -
3.12 alpine (musl) linear-api - - 1.65s 84.3M
3.12 alpine (musl) linear-py - - - -
3.12 slim (glibc) linear-api - - 1.63s 154M
3.12 slim (glibc) linear-py - - - -
3.13 alpine (musl) linear-api - - 1.22s 80.2M
3.13 alpine (musl) linear-py - - - -
3.13 slim (glibc) linear-api - - 1.25s 152M
3.13 slim (glibc) linear-py - - - -
3.9 alpine (musl) linear-api - - - -
3.9 alpine (musl) linear-py - - - -
3.9 slim (glibc) linear-api - - - -
3.9 slim (glibc) linear-py - - - -
Imports
- LinearClient wrong
from linear import LinearClientcorrectfrom linear_api import LinearClient - Raw GraphQL (recommended) wrong
from linear_py import Linearcorrectimport urllib.request # raw GraphQL over HTTP
Quickstart verified last tested: 2026-05-12
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'})