or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-utilities.mdclient-management.mddata-models-types.mdindex.mdissue-operations.mdproject-management.mdteam-administration.mduser-management.md

index.mddocs/

0

# Linear API

1

2

A comprehensive Python wrapper for the Linear API with rich Pydantic models, simplified workflows, and an object-oriented design. This package provides programmatic access to Linear's project management platform, enabling developers to integrate Linear functionality into their applications and workflows with type safety, automatic pagination handling, intelligent caching, and comprehensive error management.

3

4

## Package Information

5

6

- **Package Name**: linear-api

7

- **Language**: Python

8

- **Installation**: `pip install linear-api`

9

- **Minimum Python Version**: 3.9+

10

- **Dependencies**: `pydantic>=2.0.0`, `requests>=2.25.0`

11

- **License**: MIT

12

13

## Core Imports

14

15

```python

16

from linear_api import LinearClient

17

```

18

19

Import domain models and types:

20

21

```python

22

from linear_api import (

23

LinearIssue,

24

LinearProject,

25

LinearUser,

26

LinearTeam,

27

LinearState,

28

LinearLabel,

29

LinearAttachment,

30

LinearIssueInput,

31

LinearIssueUpdateInput,

32

LinearAttachmentInput,

33

LinearPriority,

34

IntegrationService,

35

SLADayCountType,

36

ProjectStatusType,

37

)

38

```

39

40

Import utility functions for low-level access:

41

42

```python

43

from linear_api.utils import call_linear_api

44

```

45

46

## Basic Usage

47

48

```python

49

from linear_api import LinearClient

50

51

# Create client with API key

52

client = LinearClient(api_key="your_api_key_here")

53

54

# Or use environment variable LINEAR_API_KEY

55

client = LinearClient()

56

57

# Get an issue by ID

58

issue = client.issues.get("issue-id")

59

print(f"Issue: {issue.title} ({issue.state.name})")

60

61

# Create a new issue

62

from linear_api import LinearIssueInput

63

64

new_issue = client.issues.create(LinearIssueInput(

65

title="New task from API",

66

teamName="Engineering",

67

description="Task created via Python API"

68

))

69

70

# Get all projects for a team

71

projects = client.projects.get_all()

72

print(f"Found {len(projects)} projects")

73

74

# Get current user info

75

me = client.users.get_me()

76

print(f"Current user: {me.name} ({me.email})")

77

```

78

79

## Architecture

80

81

The Linear API package follows a manager-based architecture that provides a clean separation of concerns:

82

83

### Core Components

84

85

- **LinearClient**: Central client managing authentication, configuration, and resource access

86

- **Resource Managers**: Specialized managers for different Linear entities (issues, projects, teams, users)

87

- **Domain Models**: Rich Pydantic models with complete field coverage and dynamic properties

88

- **Caching System**: Intelligent caching with TTL support to optimize API calls

89

- **Utility Layer**: Low-level GraphQL access and data transformation utilities

90

91

### Design Patterns

92

93

- **Manager Pattern**: Each resource type has a dedicated manager with consistent CRUD operations

94

- **Active Record**: Domain models include dynamic properties for accessing related data through client references

95

- **Connection Unwrapping**: Automatic handling of GraphQL pagination for improved usability

96

- **Decorator-based Enhancement**: Client references are automatically injected into returned models for method chaining

97

98

This architecture enables both high-level abstractions for common workflows and low-level GraphQL access for advanced use cases, with comprehensive type safety throughout.

99

100

## Capabilities

101

102

### Client Management

103

104

Central client configuration and authentication for accessing Linear's API with caching, connection management, and schema validation capabilities.

105

106

```python { .api }

107

class LinearClient:

108

def __init__(

109

self,

110

api_key: Optional[str] = None,

111

enable_cache: bool = True,

112

cache_ttl: int = 3600,

113

auto_unwrap_connections: bool = True,

114

): ...

115

116

def call_api(self, query: Dict[str, Any] | str) -> Dict[str, Any]: ...

117

def execute_graphql(self, query: str, variables: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: ...

118

def clear_cache(self, cache_name: Optional[str] = None) -> None: ...

119

def enable_connection_unwrapping(self) -> None: ...

120

def disable_connection_unwrapping(self) -> None: ...

121

```

122

123

[Client Management](./client-management.md)

124

125

### Issue Operations

126

127

Comprehensive issue management including creation, updates, querying, and relationship management with support for attachments, comments, and metadata.

128

129

```python { .api }

130

class IssueManager:

131

def get(self, issue_id: str) -> LinearIssue: ...

132

def create(self, issue: LinearIssueInput) -> LinearIssue: ...

133

def update(self, issue_id: str, update_data: LinearIssueUpdateInput) -> LinearIssue: ...

134

def delete(self, issue_id: str) -> bool: ...

135

def get_by_team(self, team_name: str) -> Dict[str, LinearIssue]: ...

136

def get_by_project(self, project_id: str) -> Dict[str, LinearIssue]: ...

137

def get_all() -> Dict[str, LinearIssue]: ...

138

```

139

140

[Issue Operations](./issue-operations.md)

141

142

### Project Management

143

144

Full project lifecycle management including creation, updates, member management, and relationship tracking with milestones, updates, and documentation.

145

146

```python { .api }

147

class ProjectManager:

148

def get(self, project_id: str) -> LinearProject: ...

149

def create(self, name: str, team_name: str, description: Optional[str] = None) -> LinearProject: ...

150

def update(self, project_id: str, **kwargs) -> LinearProject: ...

151

def delete(self, project_id: str) -> bool: ...

152

def get_all(self, team_id: Optional[str] = None) -> Dict[str, LinearProject]: ...

153

def get_id_by_name(self, project_name: str, team_id: Optional[str] = None) -> str: ...

154

```

155

156

[Project Management](./project-management.md)

157

158

### Team Administration

159

160

Team configuration and member management including workflow states, labels, cycles, templates, and organizational hierarchy.

161

162

```python { .api }

163

class TeamManager:

164

def get(self, team_id: str) -> LinearTeam: ...

165

def get_all() -> Dict[str, LinearTeam]: ...

166

def get_id_by_name(self, team_name: str) -> str: ...

167

def get_states(self, team_id: str, include_issue_ids: bool = False) -> List[LinearState]: ...

168

def get_members(self, team_id: str) -> List[LinearUser]: ...

169

def get_labels(self, team_id: str, include_issue_ids: bool = False) -> List[LinearLabel]: ...

170

```

171

172

[Team Administration](./team-administration.md)

173

174

### User Management

175

176

User operations including profile access, team memberships, issue assignments, and organizational data management.

177

178

```python { .api }

179

class UserManager:

180

def get(self, user_id: str) -> LinearUser: ...

181

def get_all() -> Dict[str, LinearUser]: ...

182

def get_me() -> LinearUser: ...

183

def get_id_by_email(self, email: str) -> str: ...

184

def get_id_by_name(self, name: str) -> str: ...

185

def get_assigned_issues(self, user_id: str) -> Dict[str, LinearIssue]: ...

186

```

187

188

[User Management](./user-management.md)

189

190

### Data Models and Types

191

192

Rich Pydantic models covering all Linear entities with complete field definitions, input/output types, enums, and connection types for GraphQL pagination.

193

194

```python { .api }

195

class LinearIssue(LinearModel):

196

id: str

197

title: str

198

url: str

199

state: LinearState

200

priority: LinearPriority

201

team: LinearTeam

202

# 50+ additional fields...

203

204

class LinearIssueInput(LinearModel):

205

title: str

206

teamName: str

207

# Optional fields for creation...

208

209

class LinearPriority(Enum):

210

URGENT = 0

211

HIGH = 1

212

MEDIUM = 2

213

LOW = 3

214

NONE = 4

215

```

216

217

[Data Models and Types](./data-models-types.md)

218

219

### Cache and Utilities

220

221

Low-level utilities including direct GraphQL access, caching management, data processing functions, and schema validation tools for advanced use cases.

222

223

```python { .api }

224

def call_linear_api(query: str | Dict[str, Any], api_key: Optional[str] = None) -> Dict[str, Any]: ...

225

226

class CacheManager:

227

def get(self, cache_name: str, key: Any) -> Optional[Any]: ...

228

def set(self, cache_name: str, key: Any, value: Any, ttl: Optional[int] = None) -> None: ...

229

def clear(self, cache_name: Optional[str] = None) -> None: ...

230

```

231

232

[Cache and Utilities](./cache-utilities.md)

233

234

## Environment Configuration

235

236

### Authentication

237

238

Set your Linear API key as an environment variable:

239

240

```bash

241

export LINEAR_API_KEY="your_api_key_here"

242

```

243

244

Or pass it directly to the client:

245

246

```python

247

client = LinearClient(api_key="your_api_key_here")

248

```

249

250

### Caching Configuration

251

252

Control caching behavior:

253

254

```python

255

# Disable caching entirely

256

client = LinearClient(enable_cache=False)

257

258

# Custom cache TTL (in seconds)

259

client = LinearClient(cache_ttl=7200) # 2 hours

260

261

# Runtime cache control

262

client.cache.disable()

263

client.cache.clear()

264

client.cache.enable()

265

```

266

267

### Connection Unwrapping

268

269

Control automatic GraphQL pagination handling:

270

271

```python

272

# Disable automatic connection unwrapping for performance

273

client = LinearClient(auto_unwrap_connections=False)

274

275

# Runtime control

276

client.disable_connection_unwrapping()

277

client.enable_connection_unwrapping()

278

```

279

280

## Error Handling

281

282

The package provides comprehensive error handling with descriptive messages:

283

284

```python

285

from linear_api import LinearClient

286

287

try:

288

client = LinearClient() # Will raise if no API key

289

issue = client.issues.get("invalid-id")

290

except ValueError as e:

291

print(f"API Error: {e}")

292

```

293

294

Common error scenarios:

295

- Missing or invalid API key authentication

296

- Invalid GraphQL queries or mutations

297

- Network connectivity issues

298

- Rate limiting from Linear API

299

- Invalid entity IDs or references