Everything an AI agent can do with the Linear API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints20
AuthenticationOAuth 2.0
Last updated23 June 2026
Orientation

How the Linear API works.

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.

20Endpoints
8Capability groups
13Read
7Write
4Permissions
Authentication
Every request needs a token in the Authorization header. A personal API key is sent directly and acts as the user who created it, with that user's full access. An OAuth 2.0 access token is sent as 'Authorization: Bearer ' and carries only the scopes the user granted. OAuth is the recommended route for an app that others install, while a personal API key suits a personal script. There is no anonymous write access.
Permissions
OAuth tokens carry scopes that bound what the token can do. The read scope is always present and covers every query. The write scope grants modify access across the user's account. Targeted scopes narrow that down: issues:create allows creating issues and their attachments, and comments:create allows creating comments, each without granting full write. The admin scope reaches admin-level operations and should be requested only when truly needed. Setting the actor parameter to app, with app:assignable and app:mentionable, lets an app act as its own workspace member, which is how AI agents are attributed.
Versioning
Linear's GraphQL API is not versioned by a dated string or a version segment in the path. There is one continuously updated schema. Fields scheduled for removal are first marked with the GraphQL deprecated directive so a client can see them in introspection before they go, and notable API changes are announced in the changelog with an API tag. Breaking changes are made deliberately and communicated to affected developers.
Data model
The API is a single GraphQL schema at https://api.linear.app/graphql, where reads are queries and changes are mutations. The core objects are issues, comments, projects, teams, users, workflow states, labels, and cycles, related through connections so one request can fetch an issue with its comments and labels. A query asks for exactly the fields it needs, lists page through Relay-style cursors, and Linear can push the same object changes to webhooks.
Connect & authenticate

Connection & authentication methods.

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.

Ways to connect

GraphQL API

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.

Best forConnecting an app or AI agent to Linear.
Governed byThe token or key and the scopes it carries.
Docs ↗

MCP server (Model Context Protocol)

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.

Best forConnecting an AI agent to Linear with no custom integration code.
Governed byThe OAuth token or API key and the scopes it carries.
Docs ↗

Webhooks

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.

Best forReceiving changes from Linear without polling.
Governed byThe webhook's registered events and signing secret.
Docs ↗
Authentication

Personal API key

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.

TokenPersonal API key
Best forPersonal scripts and internal tools
Docs ↗

OAuth 2.0

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.

TokenOAuth access token
Best forApps installed by other users
Docs ↗

OAuth with app actor

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.

TokenOAuth app actor token
Best forAI agents that act as their own member
Docs ↗
Endpoint reference

Every Linear API operation.

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.

MethodEndpointWhat it doesAccessPermissionVersion

Issues

List and read issues, create new issues, update existing ones, and archive them.5

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)read
VersionAvailable since the API’s base version
Webhook eventIssue
Rate limitStandard limits apply

Covered by the read scope. Archived issues are hidden unless includeArchived is passed.

Acts onissue
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventIssue
Rate limitStandard limits apply

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:create
VersionAvailable since the API’s base version
Webhook eventIssue
Rate limitStandard limits apply

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)write
VersionAvailable since the API’s base version
Webhook eventIssue
Rate limitStandard limits apply

Needs the write scope. Archiving is reversible through issueUnarchive, unlike a permanent delete.

Acts onissue
Permission (capability)write
VersionAvailable since the API’s base version
Webhook eventIssue
Rate limitStandard limits apply

Comments

List comments on an issue and create new comments.2

Covered by the read scope. Comments are also reachable through the comments connection on an issue.

Acts oncomment
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventComment
Rate limitStandard limits apply

The targeted comments:create scope allows creating comments without the broad write scope. The write scope also covers it.

Acts oncomment
Permission (capability)comments:create
VersionAvailable since the API’s base version
Webhook eventComment
Rate limitStandard limits apply

Projects

List and read projects, create new projects, and update existing ones.4

Covered by the read scope.

Acts onproject
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventProject
Rate limitStandard limits apply

Covered by the read scope.

Acts onproject
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventProject
Rate limitStandard limits apply

Needs the write scope. There is no targeted create scope for projects, so this requires the broad write scope.

Acts onproject
Permission (capability)write
VersionAvailable since the API’s base version
Webhook eventProject
Rate limitStandard limits apply

Needs the write scope.

Acts onproject
Permission (capability)write
VersionAvailable since the API’s base version
Webhook eventProject
Rate limitStandard limits apply

Teams

List the workspace's teams and read a single team.2

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)read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Covered by the read scope.

Acts onteam
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Users

Read the authenticated user with viewer, list users, and read a single user.3

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)read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Covered by the read scope. Returns the email addresses of workspace members.

Acts onuser
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventUser
Rate limitStandard limits apply

Covered by the read scope.

Acts onuser
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventUser
Rate limitStandard limits apply

Workflow states

List the workflow states a team's issues move through, such as Todo, In Progress, and Done.1

Covered by the read scope. A state id from here is what issueUpdate sets to move an issue.

Acts onworkflow state
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Labels

List the workspace's issue labels and create a new label.2

Covered by the read scope.

Acts onlabel
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventIssueLabel
Rate limitStandard limits apply

Needs the write scope.

Acts onlabel
Permission (capability)write
VersionAvailable since the API’s base version
Webhook eventIssueLabel
Rate limitStandard limits apply

Cycles

List a team's cycles, the time-boxed iterations issues are planned into.1

Covered by the read scope.

Acts oncycle
Permission (capability)read
VersionAvailable since the API’s base version
Webhook eventCycle
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

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.

EventWhat it signalsTriggered by
IssueFires on the create, update, or remove of an issue, such as a new issue, a status change, or an archive.query issues
query issue
mutation issueCreate
mutation issueUpdate
mutation issueArchive
CommentFires on the create, update, or remove of an issue comment.query comments
mutation commentCreate
ProjectFires on the create, update, or remove of a project.query projects
query project
mutation projectCreate
mutation projectUpdate
CycleFires on the create, update, or remove of a cycle.query cycles
IssueLabelFires on the create, update, or remove of an issue label.query issueLabels
mutation issueLabelCreate
UserFires on the create, update, or remove of a workspace user.query users
query user
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

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.

Request rate

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.

Pagination

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.

Request size

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.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
200errors arrayA 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.
400RATELIMITEDA 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.
401AUTHENTICATION_ERRORThe 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.
400Query too complexA 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.
Versioning & freshness

Version history.

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.

Version history

What changed, and when

Latest versionCurrent
CurrentCurrent version
Continuously updated GraphQL schema

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.

What changed
  • Schema introspection is enabled, so the current shape of every type and field is always discoverable
  • Deprecated fields are flagged with the GraphQL deprecated directive ahead of removal
  • Breaking changes are communicated to affected developers before they land
2026-06-18Feature update
OAuth app manifests and template payload validation

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.

What changed
  • OAuth application manifests: URL parameters and a JSON manifest for one-click app setup
  • templateCreate and templateUpdate now reject unsupported form field payloads
2026-05-21Requires migration
Team visibility field and OAuth token migration sunset

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.

What changed
  • Added the Team.visibility field
  • Deprecated Team.private in favour of Team.visibility
  • OAuth token migration endpoint now returns 410 Gone
2026-05-14Feature update
Project channel fields and release backdating

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.

What changed
  • Projects added slackChannelId and microsoftTeamsChannelId fields
  • Releases added createdAt, startedAt, and completedAt backdating fields
  • SCIM payloads now populate user groups

Fields scheduled for removal are marked deprecated in the schema before they go, and notable changes are dated in the changelog.

Linear changelog ↗
Questions

Linear API, answered.

Personal API key or OAuth, which should I use?+
A personal API key is the quick route for a personal script or an internal tool: it acts as the user who created it and has that user's full access, with no scope selection. OAuth 2.0 is the route for an app that other people install, because each user grants a specific set of scopes, such as read with issues:create, rather than handing over full account access. For an app shared beyond one user, OAuth is recommended.
How do permissions work, and what does each scope grant?+
OAuth tokens carry scopes. The read scope is always present and covers every query. The write scope grants modify access across the account. Two targeted scopes narrow writes down: issues:create allows creating issues and their attachments, and comments:create allows creating comments, each without the full write scope. The admin scope reaches admin-level operations and should be avoided unless essential. A personal API key has no scopes and simply inherits its user's access.
How do the rate limits work?+
Two limits apply at once. The first counts requests per hour: 5,000 for an authenticated user or API key, 5,000 per user for an OAuth app, and 600 for an unauthenticated IP address, refilled steadily through a leaky bucket. The second is a complexity budget in points, where each field, object, and paginated connection adds cost: 3,000,000 points per hour for an API key, 2,000,000 for an OAuth app, and any single query capped at 10,000 points. Exceeding either returns a RATELIMITED error, and the X-RateLimit and X-Complexity headers report the current state.
Why did my request return HTTP 200 but still fail?+
Linear follows the standard GraphQL error model, so a request that reaches the server returns HTTP 200 even when the operation has problems. The errors sit in an errors array in the response body, alongside any data that did resolve, which means a single request can be a partial success. A client should read the errors array and each error's code rather than relying on the HTTP status alone. Rate limiting and a too-complex query are the exceptions that return HTTP 400.
Can an AI agent act as itself rather than as a person?+
Yes. When an OAuth app is authorized with the actor parameter set to app, it installs as its own workspace member, so issues and comments it creates are attributed to the app rather than to the authorizing user. The app:assignable scope lets it be delegated issues and added to projects, and app:mentionable lets it be mentioned in issues and documents. An agent installed this way does not count as a billable user.
How do I receive changes instead of polling?+
Webhooks deliver changes without polling. A receiver URL is registered and a set of object types is chosen, such as Issue, Comment, Project, Cycle, IssueLabel, or User, each firing on create, update, or remove. Linear sends an HTTP POST with the payload, and the Linear-Signature header, an HMAC-SHA256 of the raw body checked against the signing secret, confirms it came from Linear. The receiver must respond with HTTP 200 within 5 seconds, and failed deliveries are retried.
Related

More developer API guides for agents

What is Bollard AI?

Control what every AI agent can do in Linear.

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.

  • Set read, write, or full access per agent, never a shared Linear key.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Linear
Triage Agent
Read issues and projects ResourceOffReadFull use
Create issues and comments ActionOffReadFull use
Admin settings ResourceOffReadFull use
Per-agent access, set in Bollard AI, not in Linear