conductorv2

Integrations

Linear

Create and manage Linear issues, cycles, and projects through Conductor. Covers personal API keys, OAuth apps, finding workspace and team IDs, state UUID lookup, priority values, and webhook configuration.

Authentication

Personal API Key

The quickest way to get started. Acts with the same permissions as your Linear user account. Goes to Settings → API → Personal API keys. Ideal for individual automation. Tokens start with lin_api_.

OAuth App

For team tools or products that multiple Linear users connect to. Create an OAuth app under Settings → API → OAuth applications. Users authorize via Linear's consent screen. More setup, but doesn't rely on one person's account.

Creating a personal API key

  1. 01Open Linear and click your workspace name in the top-left corner → Settings.
  2. 02In the left sidebar, scroll to My Account → API.
  3. 03Under Personal API keys, click Create key. Give it a descriptive label (e.g., "Conductor").
  4. 04Copy the key immediately — Linear only shows it once. It starts with lin_api_.
  5. 05Add it to your Conductor config (see below).

Finding workspace and team IDs

finding IDs
// Your workspace slug is in the Linear URL:
// https://linear.app/YOUR-SLUG/settings
//                  ^^^^^^^^^^^
// Example: https://linear.app/acme/settings → slug is "acme"

// Team IDs: linear.team.list({}) returns id, name, key, slug
// Project IDs: linear.project.list({}) returns id, name, slugId
// Member IDs: linear.member.list({}) returns id, name, email, displayName

Conductor config

Personal API key (most common)

conductor.json
{
  "plugins": {
    "linear": {
      "api_key": "lin_api_your-personal-api-key"
    }
  }
}

OAuth app

conductor.json — oauth
{
  "plugins": {
    "linear": {
      "client_id": "your-oauth-client-id",
      "client_secret": "your-oauth-client-secret",
      "redirect_uri": "https://yourapp.com/linear/callback",
      "access_token": "lin_oauth_access_token"
    }
  }
}

Available tools

ToolDescription
linear.issue.createCreate a new issue in a team. Returns the created issue ID and identifier (e.g., ENG-123).
linear.issue.listList issues with optional filters for team, state, assignee, cycle, project, and priority.
linear.issue.updateUpdate any field on an existing issue: title, description, state, priority, assignee, labels.
linear.issue.commentAdd a comment to an issue. Supports Markdown in the body.
linear.issue.assignAssign an issue to a team member by their user UUID.
linear.cycle.listList all cycles (sprints) for a team, including active, upcoming, and completed ones.
linear.project.listList all projects in the workspace. Projects span across teams.
linear.team.listList all teams in the workspace with their IDs, keys, and slugs.
linear.member.listList all members of the workspace with their user IDs, names, and emails.
linear.label.listList all labels available in the workspace or for a specific team.

Priority values

Linear uses numeric priority values. Lower numbers are higher priority. Priority 0 means no priority has been assigned.

ValueLabelNotes
0No priorityIssue has not been prioritized yet
1UrgentNeeds immediate attention, blocks others
2HighImportant, should be addressed soon
3MediumNormal priority work
4LowNice to have, address when time permits

Issue state IDs

State names like "In Progress" or "Done" are human labels — the API uses UUIDs. Each team has its own set of workflow states. You must look up the UUID for the state you want before creating or updating issues.

finding state UUIDs
// State IDs are UUIDs — you can't use names like "In Progress" directly.
// To find state IDs for a team:
linear.team.list({})
// Then use the team ID to list workflow states via the API:
// GET https://api.linear.app/graphql with query:
// { team(id: "TEAM-UUID") { states { nodes { id name type } } } }
//
// State types: "triage", "backlog", "unstarted", "started", "completed", "cancelled"
// Note: within each type there can be multiple custom states with their own UUIDs.

State types (backlog, started, completed, etc.) are consistent across teams, but the specific states within each type are team-specific with unique UUIDs.

Usage examples

Creating an issue

linear.issue.create
// Create a new issue
linear.issue.create({
  teamId: "TEAM-UUID-HERE",          // required: UUID, not the slug
  title: "Fix login redirect bug",
  description: "Users are being redirected to /404 after login.",
  priority: 2,                        // 0=None, 1=Urgent, 2=High, 3=Medium, 4=Low
  stateId: "STATE-UUID-HERE",        // optional: UUID of the workflow state
  assigneeId: "USER-UUID-HERE",      // optional
  labelIds: ["LABEL-UUID-1"],        // optional: array of label UUIDs
  projectId: "PROJECT-UUID-HERE"     // optional
})

Listing and filtering issues

linear.issue.list
// List issues with filters
linear.issue.list({
  teamId: "TEAM-UUID-HERE",
  filter: {
    state: { name: { eq: "In Progress" } },
    assignee: { id: { eq: "USER-UUID-HERE" } },
    priority: { gte: 2 }              // 2 = High priority or higher (lower number = higher priority)
  },
  orderBy: "updatedAt",
  first: 25
})

// Filter by cycle
linear.issue.list({
  cycleId: "CYCLE-UUID-HERE",
  filter: { state: { type: { neq: "completed" } } }
})

// Filter by project
linear.issue.list({
  projectId: "PROJECT-UUID-HERE"
})

Updating an issue

linear.issue.update
// Update an issue
linear.issue.update({
  issueId: "ISSUE-UUID-HERE",        // UUID, not the identifier like ENG-123
  title: "Updated title",
  stateId: "NEW-STATE-UUID",
  priority: 1,                        // escalate to Urgent
  assigneeId: null                    // unassign
})

Commenting on an issue

linear.issue.comment
// Add a comment to an issue
linear.issue.comment({
  issueId: "ISSUE-UUID-HERE",
  body: "Investigated this — it's caused by the session token expiry. Fix in progress."
})

Working with cycles (sprints)

linear.cycle.list
// List cycles (sprints) for a team
linear.cycle.list({
  teamId: "TEAM-UUID-HERE"
})
// Returns: id, name, number, startsAt, endsAt, completedAt, progress

// Get active cycle issues
linear.issue.list({
  filter: {
    cycle: { isActive: { eq: true } },
    team: { id: { eq: "TEAM-UUID-HERE" } }
  }
})

Working with projects

linear.project.list
// List projects
linear.project.list({
  first: 50
})

// List issues in a project
linear.issue.list({
  projectId: "PROJECT-UUID-HERE",
  filter: {
    state: { type: { neq: "cancelled" } }
  }
})

Webhooks from Linear

webhook setup
// Linear can send webhooks to Conductor when issues change.
// Configure at: linear.app/YOUR-SLUG/settings/api → Webhooks
//
// Supported events:
//   Issue — created, updated, removed
//   Comment — created, updated, removed
//   Cycle — created, updated, removed
//   Project — created, updated, removed
//   IssueLabel — created, updated, removed
//
// The webhook payload includes the resource type, action, and full object data.
// Conductor receives these and can trigger automations based on the event.

Rate limits

Linear uses a GraphQL API with complexity-based rate limiting. Each query is assigned a complexity cost based on how many resources it fetches. The limit is 1,500 complexity points per minute. Simple mutations (create, update) cost around 5–10 points. Paginated list queries cost more depending on the first argument. The API response includes X-RateLimit-Requests-Remaining and X-RateLimit-Complexity-Remaining headers so you can track usage. HTTP 429 is returned when you exceed the limit; retry after 60 seconds.

Common errors

Authentication required

API key is missing or malformed in the request

Fix: Verify the token starts with lin_api_. Check there are no extra spaces or newlines in the config.

Entity not found

The UUID you passed doesn't correspond to any object in the workspace

Fix: Re-fetch the ID. UUIDs are case-sensitive. Make sure you're not mixing up team IDs, issue IDs, and user IDs.

You don't have permission

The API key belongs to a user who lacks access to the resource

Fix: Use an API key from a user with admin or member access. Guest users have restricted API access.

Argument validation error

A field value is wrong type, out of range, or refers to a non-existent enum value

Fix: Check priority is 0–4. Check stateId, assigneeId, and labelIds are valid UUIDs. Check dates are ISO 8601.