The Linear Client SDK for interacting with the Linear GraphQL API
Comprehensive issue operations for creating, updating, querying, and managing Linear issues and their relationships.
Query individual issues or collections of issues with filtering, sorting, and pagination.
/**
* Get a single issue by ID
* @param id - The issue ID
* @returns Promise resolving to the issue
*/
issue(id: string): LinearFetch<Issue>;
/**
* Get a paginated list of issues with optional filtering
* @param variables - Query parameters including filters and pagination
* @returns Promise resolving to a connection of issues
*/
issues(variables?: IssuesQueryVariables): LinearFetch<IssueConnection>;
interface IssuesQueryVariables extends LinearConnectionVariables {
/** Filter conditions for issues */
filter?: IssueFilter;
/** Sort order for issues */
orderBy?: PaginationOrderBy;
/** Include archived issues */
includeArchived?: boolean;
}
interface IssueFilter {
/** Filter by team */
team?: NullableTeamFilter;
/** Filter by assignee */
assignee?: NullableUserFilter;
/** Filter by creator */
creator?: UserFilter;
/** Filter by project */
project?: NullableProjectFilter;
/** Filter by state */
state?: WorkflowStateFilter;
/** Filter by priority */
priority?: NullableNumberFilter;
/** Filter by estimate */
estimate?: NullableNumberFilter;
/** Filter by title */
title?: StringFilter;
/** Filter by description */
description?: NullableStringFilter;
/** Filter by labels */
labels?: IssueLabelCollectionFilter;
/** Filter by creation date */
createdAt?: DateTimeFilter;
/** Filter by update date */
updatedAt?: DateTimeFilter;
/** Filter by due date */
dueDate?: NullableDateTimeFilter;
/** Filter by completion date */
completedAt?: NullableDateTimeFilter;
/** Filter by cycle */
cycle?: NullableCycleFilter;
/** Combine filters with AND logic */
and?: IssueFilter[];
/** Combine filters with OR logic */
or?: IssueFilter[];
}Usage Examples:
import { LinearClient } from "@linear/sdk";
const client = new LinearClient({ apiKey: "your-api-key" });
// Get a single issue
const issue = await client.issue("issue-id");
console.log(issue.title);
// Get issues for a specific team
const teamIssues = await client.issues({
first: 20,
filter: {
team: {
key: { eq: "ENG" }
}
}
});
// Get high priority issues assigned to current user
const myHighPriorityIssues = await client.issues({
filter: {
assignee: { isMe: { eq: true } },
priority: { gte: 3 }
},
orderBy: PaginationOrderBy.CreatedAt
});
// Get issues in current cycle
const currentCycleIssues = await client.issues({
filter: {
cycle: { isCurrent: { eq: true } }
}
});Create, update, and delete issues with comprehensive input validation and error handling.
/**
* Create a new issue
* @param input - Issue creation data
* @returns Promise resolving to the creation result
*/
createIssue(input: IssueCreateInput): LinearFetch<IssuePayload>;
/**
* Update an existing issue
* @param id - The issue ID to update
* @param input - Issue update data
* @returns Promise resolving to the update result
*/
updateIssue(id: string, input: IssueUpdateInput): LinearFetch<IssuePayload>;
/**
* Delete an issue
* @param id - The issue ID to delete
* @returns Promise resolving to the deletion result
*/
deleteIssue(id: string): LinearFetch<DeletePayload>;
/**
* Archive an issue
* @param id - The issue ID to archive
* @returns Promise resolving to the archive result
*/
archiveIssue(id: string): LinearFetch<ArchivePayload>;
/**
* Unarchive an issue
* @param id - The issue ID to unarchive
* @returns Promise resolving to the unarchive result
*/
unarchiveIssue(id: string): LinearFetch<ArchivePayload>;
interface IssueCreateInput {
/** Issue title */
title: string;
/** Issue description in markdown */
description?: string;
/** Team ID where the issue belongs */
teamId: string;
/** User ID to assign the issue to */
assigneeId?: string;
/** Issue priority (1-4, where 4 is highest) */
priority?: number;
/** Issue estimate (story points or time) */
estimate?: number;
/** Project ID to associate with */
projectId?: string;
/** Cycle ID to associate with */
cycleId?: string;
/** Workflow state ID */
stateId?: string;
/** Label IDs to apply */
labelIds?: string[];
/** Parent issue ID for sub-issues */
parentId?: string;
/** Due date for the issue */
dueDate?: DateTime;
/** Template ID to create from */
templateId?: string;
}
interface IssueUpdateInput {
/** Update issue title */
title?: string;
/** Update issue description */
description?: string;
/** Update assignee */
assigneeId?: string;
/** Update priority */
priority?: number;
/** Update estimate */
estimate?: number;
/** Update project association */
projectId?: string;
/** Update cycle association */
cycleId?: string;
/** Update workflow state */
stateId?: string;
/** Update label associations */
labelIds?: string[];
/** Update parent issue */
parentId?: string;
/** Update due date */
dueDate?: DateTime;
/** Update subscriber list */
subscriberIds?: string[];
}Usage Examples:
// Create a new bug issue
const newBug = await client.createIssue({
title: "Fix login validation",
description: "Users can bypass email validation",
teamId: "team-engineering",
assigneeId: "user-john-doe",
priority: 3,
labelIds: ["label-bug", "label-security"]
});
// Update issue status and add estimate
const updatedIssue = await client.updateIssue("issue-id", {
stateId: "state-in-progress",
estimate: 5,
description: "Updated description with more details"
});
// Archive completed issue
const archivedIssue = await client.archiveIssue("issue-id");Manage issue relationships, dependencies, and hierarchies.
/**
* Create a relationship between two issues
* @param input - Issue relationship data
* @returns Promise resolving to the relationship creation result
*/
createIssueRelation(input: IssueRelationCreateInput): LinearFetch<IssueRelationPayload>;
/**
* Update an issue relationship
* @param id - The relationship ID to update
* @param input - Relationship update data
* @returns Promise resolving to the relationship update result
*/
updateIssueRelation(id: string, input: IssueRelationUpdateInput): LinearFetch<IssueRelationPayload>;
/**
* Delete an issue relationship
* @param id - The relationship ID to delete
* @returns Promise resolving to the deletion result
*/
deleteIssueRelation(id: string): LinearFetch<DeletePayload>;
interface IssueRelationCreateInput {
/** ID of the issue that has the relation */
issueId: string;
/** ID of the related issue */
relatedIssueId: string;
/** Type of relationship */
type: IssueRelationType;
}
enum IssueRelationType {
Blocks = "blocks",
BlockedBy = "blocked_by",
Duplicate = "duplicate",
DuplicateOf = "duplicate_of",
Related = "related"
}Manage issue labels for categorization and organization.
/**
* Get issue labels with filtering and pagination
* @param variables - Query parameters
* @returns Promise resolving to a connection of issue labels
*/
issueLabels(variables?: IssueLabelsQueryVariables): LinearFetch<IssueLabelConnection>;
/**
* Create a new issue label
* @param input - Label creation data
* @returns Promise resolving to the creation result
*/
createIssueLabel(input: IssueLabelCreateInput): LinearFetch<IssueLabelPayload>;
/**
* Update an issue label
* @param id - The label ID to update
* @param input - Label update data
* @returns Promise resolving to the update result
*/
updateIssueLabel(id: string, input: IssueLabelUpdateInput): LinearFetch<IssueLabelPayload>;
interface IssueLabelCreateInput {
/** Label name */
name: string;
/** Label description */
description?: string;
/** Label color hex code */
color?: string;
/** Team ID this label belongs to */
teamId?: string;
}/** Issue model representing a Linear issue */
class Issue extends Request {
/** Unique issue identifier */
id: string;
/** Issue title */
title: string;
/** Issue description in markdown */
description?: string;
/** Issue number (team-specific) */
number: number;
/** Issue identifier (team key + number) */
identifier: string;
/** Issue priority (1-4) */
priority: number;
/** Issue estimate */
estimate?: number;
/** Issue URL in Linear */
url: string;
/** Issue state */
state: WorkflowState;
/** Assigned user */
assignee?: User;
/** Issue creator */
creator?: User;
/** Team the issue belongs to */
team: Team;
/** Associated project */
project?: Project;
/** Associated cycle */
cycle?: Cycle;
/** Issue labels */
labels: IssueLabelConnection;
/** Issue comments */
comments: CommentConnection;
/** Issue attachments */
attachments: AttachmentConnection;
/** Issue subscribers */
subscribers: UserConnection;
/** Parent issue */
parent?: Issue;
/** Child issues */
children: IssueConnection;
/** Creation timestamp */
createdAt: DateTime;
/** Last update timestamp */
updatedAt: DateTime;
/** Completion timestamp */
completedAt?: DateTime;
/** Due date */
dueDate?: DateTime;
}
/** Response payload for issue mutations */
interface IssuePayload {
/** The mutated issue */
issue?: Issue;
/** Whether the mutation was successful */
success: boolean;
/** Last sync ID */
lastSyncId: number;
}
/** Paginated connection of issues */
class IssueConnection extends Connection<Issue> {
/** Issues in this page */
nodes: Issue[];
/** Pagination information */
pageInfo: PageInfo;
}Install with Tessl CLI
npx tessl i tessl/npm-linear--sdk