0
# Team Administration
1
2
Team configuration and member management including workflow states, labels, cycles, templates, and organizational hierarchy.
3
4
## Capabilities
5
6
### Core Team Operations
7
8
Basic team management operations for accessing team information and configuration.
9
10
```python { .api }
11
def get(self, team_id: str) -> LinearTeam:
12
"""
13
Fetch a team by ID with comprehensive details including configuration,
14
cycles, states, and memberships.
15
16
Args:
17
team_id: The ID of the team to fetch
18
19
Returns:
20
LinearTeam with complete details
21
22
Raises:
23
ValueError: If team not found
24
"""
25
26
def get_all(self) -> Dict[str, LinearTeam]:
27
"""
28
Get all teams in the organization.
29
30
Returns:
31
Dictionary mapping team IDs to LinearTeam objects
32
"""
33
34
def get_id_by_name(self, team_name: str) -> str:
35
"""
36
Get a team ID by its name.
37
38
Args:
39
team_name: Name of the team to find
40
41
Returns:
42
Team ID string
43
44
Raises:
45
ValueError: If team not found
46
"""
47
```
48
49
Usage examples:
50
51
```python
52
from linear_api import LinearClient
53
54
client = LinearClient()
55
56
# Get a specific team
57
team = client.teams.get("team-id")
58
print(f"Team: {team.name} ({team.key})")
59
60
# Get all teams
61
all_teams = client.teams.get_all()
62
print(f"Organization has {len(all_teams)} teams")
63
64
# Find team by name
65
team_id = client.teams.get_id_by_name("Engineering")
66
engineering_team = client.teams.get(team_id)
67
```
68
69
### Workflow State Management
70
71
Manage team workflow states that control issue progression.
72
73
```python { .api }
74
def get_states(
75
self,
76
team_id: str,
77
include_issue_ids: bool = False,
78
force_refresh: bool = False
79
) -> List[LinearState]:
80
"""
81
Get all workflow states for a team with optional issue ID inclusion
82
and cache refresh.
83
84
Args:
85
team_id: The ID of the team
86
include_issue_ids: Whether to include issue IDs using each state
87
force_refresh: Whether to force cache refresh
88
89
Returns:
90
List of LinearState objects
91
"""
92
93
def get_state_id_by_name(self, state_name: str, team_id: str) -> str:
94
"""
95
Get a state ID by its name within a team.
96
97
Args:
98
state_name: Name of the state to find
99
team_id: The ID of the team
100
101
Returns:
102
State ID string
103
104
Raises:
105
ValueError: If state not found
106
"""
107
```
108
109
Usage examples:
110
111
```python
112
# Get team workflow states
113
states = client.teams.get_states("team-id")
114
for state in states:
115
print(f"State: {state.name} ({state.type}) - {state.color}")
116
117
# Get states with issue counts
118
states_with_issues = client.teams.get_states("team-id", include_issue_ids=True)
119
120
# Find specific state
121
todo_state_id = client.teams.get_state_id_by_name("Todo", "team-id")
122
```
123
124
### Member Management
125
126
Manage team membership and access controls.
127
128
```python { .api }
129
def get_members(self, team_id: str) -> List[LinearUser]:
130
"""
131
Get members of a team with automatic pagination and LinearUser model conversion.
132
133
Args:
134
team_id: The ID of the team
135
136
Returns:
137
List of LinearUser objects
138
"""
139
140
def get_membership(self, team_id: str, user_id: Optional[str] = None) -> Optional[TeamMembership]:
141
"""
142
Get the membership of a user in a team, uses current user if user_id not provided.
143
144
Args:
145
team_id: The ID of the team
146
user_id: Optional user ID, uses current user if not provided
147
148
Returns:
149
TeamMembership object or None if not a member
150
151
Raises:
152
ValueError: If user not found
153
"""
154
```
155
156
Usage examples:
157
158
```python
159
# Get team members
160
members = client.teams.get_members("team-id")
161
print(f"Team has {len(members)} members:")
162
for member in members:
163
print(f" - {member.name} ({member.email})")
164
165
# Check current user's membership
166
my_membership = client.teams.get_membership("team-id")
167
if my_membership:
168
print(f"I am a member with owner status: {my_membership.owner}")
169
170
# Check specific user's membership
171
user_membership = client.teams.get_membership("team-id", "user-id")
172
```
173
174
### Label Management
175
176
Manage team labels for issue categorization and organization.
177
178
```python { .api }
179
def get_labels(self, team_id: str, include_issue_ids: bool = False) -> List[LinearLabel]:
180
"""
181
Get labels for a team with optional issue ID inclusion.
182
183
Args:
184
team_id: The ID of the team
185
include_issue_ids: Whether to include issue IDs using each label
186
187
Returns:
188
List of LinearLabel objects
189
"""
190
191
def get_label_children(self, label_id: str) -> List[LinearLabel]:
192
"""
193
Get child labels for a parent label.
194
195
Args:
196
label_id: The ID of the parent label
197
198
Returns:
199
List of child LinearLabel objects
200
"""
201
```
202
203
Usage examples:
204
205
```python
206
# Get team labels
207
labels = client.teams.get_labels("team-id")
208
for label in labels:
209
print(f"Label: {label.name} ({label.color})")
210
211
# Get labels with usage stats
212
labels_with_usage = client.teams.get_labels("team-id", include_issue_ids=True)
213
for label in labels_with_usage:
214
issue_count = len(label.issue_ids) if hasattr(label, 'issue_ids') else 0
215
print(f"Label: {label.name} - used on {issue_count} issues")
216
217
# Get label hierarchy
218
parent_label = labels[0] # Assuming first label has children
219
children = client.teams.get_label_children(parent_label.id)
220
```
221
222
### Cycle Management
223
224
Manage team development cycles and sprint planning.
225
226
```python { .api }
227
def get_active_cycle(self, team_id: str) -> Optional[Dict[str, Any]]:
228
"""
229
Get the active cycle for a team, returns None if no active cycle.
230
231
Args:
232
team_id: The ID of the team
233
234
Returns:
235
Active cycle dictionary or None
236
"""
237
238
def get_cycles(self, team_id: str) -> List[Dict[str, Any]]:
239
"""
240
Get all cycles for a team with pagination support.
241
242
Args:
243
team_id: The ID of the team
244
245
Returns:
246
List of cycle dictionaries
247
"""
248
```
249
250
Usage examples:
251
252
```python
253
# Get current cycle
254
active_cycle = client.teams.get_active_cycle("team-id")
255
if active_cycle:
256
print(f"Active cycle: {active_cycle['name']} (ends {active_cycle['endsAt']})")
257
else:
258
print("No active cycle")
259
260
# Get all cycles
261
cycles = client.teams.get_cycles("team-id")
262
print(f"Team has {len(cycles)} cycles")
263
for cycle in cycles[-3:]: # Last 3 cycles
264
print(f"Cycle: {cycle['name']} - {cycle['startsAt']} to {cycle['endsAt']}")
265
```
266
267
### Template Management
268
269
Access team templates for consistent issue and project creation.
270
271
```python { .api }
272
def get_templates(self, team_id: str) -> List[Dict[str, Any]]:
273
"""
274
Get templates for a team with error handling.
275
276
Args:
277
team_id: The ID of the team
278
279
Returns:
280
List of template dictionaries
281
"""
282
```
283
284
Usage examples:
285
286
```python
287
# Get team templates
288
templates = client.teams.get_templates("team-id")
289
for template in templates:
290
print(f"Template: {template.get('name')}")
291
```
292
293
### Organizational Hierarchy
294
295
Navigate team hierarchies and organizational structure.
296
297
```python { .api }
298
def get_children(self, team_id: str) -> List[LinearTeam]:
299
"""
300
Get child teams for a parent team.
301
302
Args:
303
team_id: The ID of the parent team
304
305
Returns:
306
List of child LinearTeam objects
307
"""
308
309
def get_parent(self, team_id: str) -> Optional[LinearTeam]:
310
"""
311
Get the parent team of a team, returns None if no parent.
312
313
Args:
314
team_id: The ID of the team
315
316
Returns:
317
Parent LinearTeam object or None
318
"""
319
```
320
321
Usage examples:
322
323
```python
324
# Navigate team hierarchy
325
parent_team = client.teams.get_parent("team-id")
326
if parent_team:
327
print(f"Parent team: {parent_team.name}")
328
329
child_teams = client.teams.get_children("team-id")
330
print(f"Has {len(child_teams)} child teams:")
331
for child in child_teams:
332
print(f" - {child.name}")
333
```
334
335
### Team Content Access
336
337
Access issues, projects, and other content associated with teams.
338
339
```python { .api }
340
def get_issues(self, team_id: str) -> List[Dict[str, Any]]:
341
"""
342
Get issues for a team with basic issue information.
343
344
Args:
345
team_id: The ID of the team
346
347
Returns:
348
List of issue dictionaries
349
"""
350
351
def get_projects(self, team_id: str) -> Dict[str, Any]:
352
"""
353
Get projects for a team (delegates to ProjectManager).
354
355
Args:
356
team_id: The ID of the team
357
358
Returns:
359
Dictionary of project data
360
"""
361
```
362
363
Usage examples:
364
365
```python
366
# Get team issues
367
issues = client.teams.get_issues("team-id")
368
print(f"Team has {len(issues)} issues")
369
370
# Get team projects
371
projects = client.teams.get_projects("team-id")
372
print(f"Team has projects: {list(projects.keys())}")
373
```
374
375
### Integration Management
376
377
Manage team integrations and webhooks.
378
379
```python { .api }
380
def get_webhooks(self, team_id: str) -> List[Dict[str, Any]]:
381
"""
382
Get webhooks for a team.
383
384
Args:
385
team_id: The ID of the team
386
387
Returns:
388
List of webhook dictionaries
389
"""
390
```
391
392
Usage examples:
393
394
```python
395
# Get team webhooks
396
webhooks = client.teams.get_webhooks("team-id")
397
for webhook in webhooks:
398
print(f"Webhook: {webhook.get('url')}")
399
```
400
401
### Triage Management
402
403
Access team triage responsibility and configuration.
404
405
```python { .api }
406
def get_triage_responsibility(self, team_id: str) -> TriageResponsibility:
407
"""
408
Get triage responsibility data for a team.
409
410
Args:
411
team_id: The ID of the team
412
413
Returns:
414
TriageResponsibility object
415
"""
416
```
417
418
Usage examples:
419
420
```python
421
# Get triage configuration
422
triage = client.teams.get_triage_responsibility("team-id")
423
print(f"Triage action: {triage.action}")
424
```
425
426
### Cache Management
427
428
Control caching for team-related data.
429
430
```python { .api }
431
def invalidate_cache(self) -> None:
432
"""
433
Invalidate all team-related caches.
434
"""
435
```
436
437
Usage examples:
438
439
```python
440
# Clear team caches
441
client.teams.invalidate_cache()
442
```
443
444
## Team Configuration
445
446
Teams in Linear have extensive configuration options that control their workflow and behavior:
447
448
### Automation Settings
449
450
```python
451
# Teams have various automation settings
452
team = client.teams.get("team-id")
453
454
print(f"Auto archive period: {team.autoArchivePeriod}")
455
print(f"Auto close child issues: {team.autoCloseChildIssues}")
456
print(f"Auto close parent issues: {team.autoCloseParentIssues}")
457
```
458
459
### Cycle Configuration
460
461
```python
462
# Check cycle settings
463
print(f"Cycles enabled: {team.cyclesEnabled}")
464
print(f"Cycle duration: {team.cycleDuration}")
465
print(f"Cycle start day: {team.cycleStartDay}")
466
```
467
468
### Estimation Settings
469
470
```python
471
# Check estimation configuration
472
print(f"Default issue estimate: {team.defaultIssueEstimate}")
473
print(f"Issue estimation type: {team.issueEstimationType}")
474
```
475
476
## Advanced Team Workflows
477
478
### Team Metrics and Analytics
479
480
```python
481
def analyze_team_performance(team_id: str):
482
team = client.teams.get(team_id)
483
issues = client.teams.get_issues(team_id)
484
states = client.teams.get_states(team_id)
485
members = client.teams.get_members(team_id)
486
487
# Calculate state distribution
488
state_counts = {}
489
for issue in issues:
490
state_name = issue.get('state', {}).get('name', 'Unknown')
491
state_counts[state_name] = state_counts.get(state_name, 0) + 1
492
493
print(f"Team: {team.name}")
494
print(f"Members: {len(members)}")
495
print(f"Total issues: {len(issues)}")
496
print(f"Workflow states: {len(states)}")
497
print("\nIssue distribution by state:")
498
for state, count in state_counts.items():
499
print(f" {state}: {count} issues")
500
501
return {
502
"team": team,
503
"member_count": len(members),
504
"issue_count": len(issues),
505
"state_distribution": state_counts
506
}
507
508
# Analyze team performance
509
analytics = analyze_team_performance("team-id")
510
```
511
512
### Multi-Team Coordination
513
514
```python
515
def get_organization_structure():
516
all_teams = client.teams.get_all()
517
518
# Build hierarchy
519
root_teams = []
520
team_children = {}
521
522
for team_id, team in all_teams.items():
523
if not team.parentId:
524
root_teams.append(team)
525
else:
526
if team.parentId not in team_children:
527
team_children[team.parentId] = []
528
team_children[team.parentId].append(team)
529
530
def print_hierarchy(team, indent=0):
531
print(" " * indent + f"- {team.name} ({team.key})")
532
children = team_children.get(team.id, [])
533
for child in children:
534
print_hierarchy(child, indent + 1)
535
536
print("Organization Structure:")
537
for root in root_teams:
538
print_hierarchy(root)
539
540
# Print organization structure
541
get_organization_structure()
542
```
543
544
### Label Management Workflows
545
546
```python
547
def organize_team_labels(team_id: str):
548
labels = client.teams.get_labels(team_id, include_issue_ids=True)
549
550
# Group by color
551
by_color = {}
552
for label in labels:
553
color = label.color
554
if color not in by_color:
555
by_color[color] = []
556
by_color[color].append(label)
557
558
# Sort by usage (if issue_ids available)
559
for color, color_labels in by_color.items():
560
color_labels.sort(key=lambda l: len(getattr(l, 'issue_ids', [])), reverse=True)
561
562
print(f"Team labels organized by color:")
563
for color, color_labels in by_color.items():
564
print(f"\n{color}:")
565
for label in color_labels:
566
usage = len(getattr(label, 'issue_ids', []))
567
print(f" - {label.name} ({usage} issues)")
568
569
# Organize labels
570
organize_team_labels("team-id")
571
```
572
573
### Cycle Planning
574
575
```python
576
def plan_next_cycle(team_id: str):
577
active_cycle = client.teams.get_active_cycle(team_id)
578
team_issues = client.teams.get_issues(team_id)
579
580
if active_cycle:
581
print(f"Current cycle: {active_cycle['name']}")
582
print(f"Ends: {active_cycle['endsAt']}")
583
584
# Get backlog issues (not in active cycle)
585
backlog = [issue for issue in team_issues
586
if not issue.get('cycle')]
587
588
print(f"\nBacklog items for next cycle: {len(backlog)}")
589
590
# Prioritize by priority and estimate
591
prioritized = sorted(backlog,
592
key=lambda i: (i.get('priority', 4), i.get('estimate', 0)))
593
594
for issue in prioritized[:10]: # Top 10 candidates
595
title = issue.get('title', 'Untitled')
596
priority = issue.get('priority', 'None')
597
estimate = issue.get('estimate', 'Unestimated')
598
print(f" - {title} (Priority: {priority}, Estimate: {estimate})")
599
600
# Plan next cycle
601
plan_next_cycle("team-id")
602
```