A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Linear API is how an app or AI agent works with a Linear workspace: listing and filing issues, moving them through workflow states, commenting on them, and reading projects, teams, and cycles. Access is granted through a personal API key or an OAuth token carrying a set of scopes, and an agent is limited to those scopes and to what the authenticated user or app can see. The schema is continuously updated rather than versioned by date, and Linear can also push object changes to a webhook.
How an app or AI agent connects to Linear determines what it can reach. There are several routes, each governed by the token or key behind it and the scopes that token carries.
The GraphQL API answers at a single endpoint, https://api.linear.app/graphql, with one typed schema. Reads are queries and changes are mutations, and the schema supports introspection.
Linear's hosted MCP server is generally available at https://mcp.linear.app/mcp, with an /sse endpoint for some clients. It lets an agent find, create, and update issues, projects, and comments through the Model Context Protocol, authenticating with OAuth 2.1 or an Authorization Bearer token.
Webhooks deliver the events that have been chosen to a receiver URL as an HTTP POST, and the Linear-Signature header, an HMAC-SHA256 of the body, confirms the payload came from Linear.
A personal API key acts as the user who created it, with the full access that user has. It is sent in the Authorization header and suits personal scripts and internal tools, not an app shared with others.
OAuth 2.0 lets an app act on behalf of a user who grants it a chosen set of scopes, such as read, write, issues:create, or comments:create. The access token is sent as Authorization: Bearer, and this is the recommended route for an app others will install.
With the actor parameter set to app, an OAuth app installs as its own workspace member rather than acting as the authorizing user, so issues and comments it creates are attributed to the app. The app:assignable and app:mentionable scopes let it be delegated issues and mentioned, which suits AI agents.
The Linear API is one GraphQL schema split into the objects an agent can act on, such as issues, comments, projects, teams, and cycles. Reads are queries and changes are mutations, and a single broad scope can reach far more than a targeted one.
List and read issues, create new issues, update existing ones, and archive them.
List comments on an issue and create new comments.
List and read projects, create new projects, and update existing ones.
List the workspace's teams and read a single team.
Read the authenticated user with viewer, list users, and read a single user.
List the workflow states a team's issues move through, such as Todo, In Progress, and Done.
List the workspace's issue labels and create a new label.
List a team's cycles, the time-boxed iterations issues are planned into.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
IssuesList and read issues, create new issues, update existing ones, and archive them.5 | ||||||
| POST | query issues | List issues in the workspace, filtered and paginated through the issues connection. | read | read | Current | |
The read scope is always present on an OAuth token and covers every query. Returns only what the authenticated user or app can see. Acts onissue Permission (capability) readVersionAvailable since the API’s base version Webhook event IssueRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | query issue | Read a single issue by its id, including its title, state, assignee, and relations. | read | read | Current | |
Covered by the read scope. Archived issues are hidden unless includeArchived is passed. Acts onissue Permission (capability) readVersionAvailable since the API’s base version Webhook event IssueRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation issueCreate | Create a new issue in a team, with a title, description, assignee, state, and labels. | write | issues:create | Current | |
The targeted issues:create scope allows creating issues and their attachments without the broad write scope. The write scope also covers it. Acts onissue Permission (capability) issues:createVersionAvailable since the API’s base version Webhook event IssueRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation issueUpdate | Update an existing issue, such as its title, state, assignee, priority, or labels. | write | write | Current | |
Needs the write scope. Moving an issue to a Done or Cancelled state is done through this mutation by setting stateId. Acts onissue Permission (capability) writeVersionAvailable since the API’s base version Webhook event IssueRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation issueArchive | Archive an issue, removing it from the default views while keeping its history. | write | write | Current | |
Needs the write scope. Archiving is reversible through issueUnarchive, unlike a permanent delete. Acts onissue Permission (capability) writeVersionAvailable since the API’s base version Webhook event IssueRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CommentsList comments on an issue and create new comments.2 | ||||||
| POST | query comments | List comments, paginated, including the comments on a given issue. | read | read | Current | |
Covered by the read scope. Comments are also reachable through the comments connection on an issue. Acts oncomment Permission (capability) readVersionAvailable since the API’s base version Webhook event CommentRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation commentCreate | Create a comment on an issue. | write | comments:create | Current | |
The targeted comments:create scope allows creating comments without the broad write scope. The write scope also covers it. Acts oncomment Permission (capability) comments:createVersionAvailable since the API’s base version Webhook event CommentRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ProjectsList and read projects, create new projects, and update existing ones.4 | ||||||
| POST | query projects | List projects in the workspace, filtered and paginated. | read | read | Current | |
Covered by the read scope. Acts onproject Permission (capability) readVersionAvailable since the API’s base version Webhook event ProjectRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | query project | Read a single project by its id, including its status, lead, and target date. | read | read | Current | |
Covered by the read scope. Acts onproject Permission (capability) readVersionAvailable since the API’s base version Webhook event ProjectRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation projectCreate | Create a new project, naming it and assigning it to one or more teams. | write | write | Current | |
Needs the write scope. There is no targeted create scope for projects, so this requires the broad write scope. Acts onproject Permission (capability) writeVersionAvailable since the API’s base version Webhook event ProjectRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation projectUpdate | Update an existing project, such as its name, status, lead, or target date. | write | write | Current | |
Needs the write scope. Acts onproject Permission (capability) writeVersionAvailable since the API’s base version Webhook event ProjectRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TeamsList the workspace's teams and read a single team.2 | ||||||
| POST | query teams | List the teams in the workspace, paginated. | read | read | Current | |
Covered by the read scope. A team groups issues, cycles, and workflow states, so its id is needed to create issues. Acts onteam Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | query team | Read a single team by its id, including its key, members, and settings. | read | read | Current | |
Covered by the read scope. Acts onteam Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
UsersRead the authenticated user with viewer, list users, and read a single user.3 | ||||||
| POST | query viewer | Read the user the token is authenticated as, including name, email, and the teams they belong to. | read | read | Current | |
Covered by the read scope. When the token authorizes as an app rather than a user, viewer reflects the app actor. Acts onuser Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | query users | List the users in the workspace, paginated. | read | read | Current | |
Covered by the read scope. Returns the email addresses of workspace members. Acts onuser Permission (capability) readVersionAvailable since the API’s base version Webhook event UserRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | query user | Read a single user by their id. | read | read | Current | |
Covered by the read scope. Acts onuser Permission (capability) readVersionAvailable since the API’s base version Webhook event UserRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Workflow statesList the workflow states a team's issues move through, such as Todo, In Progress, and Done.1 | ||||||
| POST | query workflowStates | List the workflow states a team's issues move through, such as Todo, In Progress, Done, and Cancelled. | read | read | Current | |
Covered by the read scope. A state id from here is what issueUpdate sets to move an issue. Acts onworkflow state Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
LabelsList the workspace's issue labels and create a new label.2 | ||||||
| POST | query issueLabels | List the issue labels in the workspace, paginated. | read | read | Current | |
Covered by the read scope. Acts onlabel Permission (capability) readVersionAvailable since the API’s base version Webhook event IssueLabelRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | mutation issueLabelCreate | Create a new issue label, with a name and colour. | write | write | Current | |
Needs the write scope. Acts onlabel Permission (capability) writeVersionAvailable since the API’s base version Webhook event IssueLabelRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CyclesList a team's cycles, the time-boxed iterations issues are planned into.1 | ||||||
| POST | query cycles | List a team's cycles, the time-boxed iterations issues are planned into. | read | read | Current | |
Covered by the read scope. Acts oncycle Permission (capability) readVersionAvailable since the API’s base version Webhook event CycleRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Linear can notify an app or AI agent when something happens in a workspace, instead of the app repeatedly asking. Linear sends the event payload to a webhook URL that has been registered, and a signature header lets the receiver confirm it came from Linear.
| Event | What it signals | Triggered by |
|---|---|---|
Issue | Fires on the create, update, or remove of an issue, such as a new issue, a status change, or an archive. | query issuesquery issuemutation issueCreatemutation issueUpdatemutation issueArchive |
Comment | Fires on the create, update, or remove of an issue comment. | query commentsmutation commentCreate |
Project | Fires on the create, update, or remove of a project. | query projectsquery projectmutation projectCreatemutation projectUpdate |
Cycle | Fires on the create, update, or remove of a cycle. | query cycles |
IssueLabel | Fires on the create, update, or remove of an issue label. | query issueLabelsmutation issueLabelCreate |
User | Fires on the create, update, or remove of a workspace user. | query usersquery user |
Linear limits how fast and how much an app or AI agent can call, through an hourly request quota and a separate complexity budget that charges each query by how much data it asks for.
Linear limits requests two ways at once, and a call must stay within both. The first is a count of requests per hour, using a leaky bucket that refills steadily: an authenticated user or personal API key gets 5,000 requests per hour, an OAuth app gets 5,000 per hour per user, and an unauthenticated request gets 600 per hour per IP address. The second is a complexity budget measured in points, where each field costs about 0.1 points, each object 1 point, and a paginated connection multiplies its children by the page size. A personal API key gets 3,000,000 points per hour, an OAuth app 2,000,000, and an unauthenticated caller 100,000, while any single query is capped at 10,000 points and is rejected outright if it exceeds that. The X-RateLimit and X-Complexity response headers report the current state, and exceeding either limit returns a RATELIMITED error.
Lists use Relay-style cursor pagination. A connection returns nodes, or edges each with a node and a cursor, plus a pageInfo object holding hasNextPage and endCursor. The first and after arguments page forward and last and before page backward, and the default page size is 50. To get the next page, the endCursor from pageInfo is passed as the after argument. Archived records are excluded unless includeArchived is set.
Requests and responses are JSON over a single GraphQL endpoint. There is no fixed row cap on a query other than the per-query complexity ceiling of 10,000 points, which in practice bounds how much one request can return; larger result sets are read page by page through cursor pagination.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 200 | errors array | A GraphQL request succeeded at the HTTP level but the operation returned problems. Linear returns HTTP 200 with an errors array alongside any data, so a partial success can carry both. Each error has a message and a code in its extensions. | Read the errors array rather than relying on the HTTP status, and inspect each error's code to decide how to handle it. |
| 400 | RATELIMITED | A rate limit was exceeded, either the hourly request quota or the complexity points budget. The RATELIMITED code is returned in the errors array. | Read the X-RateLimit-Requests-Reset or X-RateLimit-Complexity-Reset header and wait until the limit refills before retrying. |
| 401 | AUTHENTICATION_ERROR | The token is missing, invalid, or expired, so the request is not authenticated. | Check the Authorization header and send a valid personal API key or OAuth access token. |
| 400 | Query too complex | A single query exceeded the maximum complexity of 10,000 points, so it is rejected regardless of the remaining hourly budget. | Request fewer fields, lower the pagination page size, or split the query into smaller requests. |
Linear's GraphQL API is not versioned by a dated string or a version in the path. There is a single, continuously updated schema, and changes are signalled in the schema itself and announced in the changelog.
Linear's GraphQL API has no dated version or version segment in the path. There is one schema that is updated continuously, with fields marked deprecated in introspection before removal and notable changes announced in the changelog under an API tag. The entries below are recent dated API changes from that changelog.
Linear added URL parameters and a JSON manifest format for one-click OAuth app setup with pre-filled forms. The templateCreate and templateUpdate mutations now reject unsupported form field payloads. Dated 18 June 2026.
A Team.visibility field was added and the Team.private field was deprecated in its favour. The older OAuth token migration endpoint now returns 410 Gone. Dated 21 May 2026.
Projects gained slackChannelId and microsoftTeamsChannelId fields, releases gained backdating fields for createdAt, startedAt, and completedAt, and SCIM payloads now populate user groups. Dated 14 May 2026.
Fields scheduled for removal are marked deprecated in the schema before they go, and notable changes are dated in the changelog.
Linear changelog ↗Bollard AI sits between a team's AI agents and Linear. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.