Linear
OAuth, AgentSession, and webhook subscribe.
The Linear integration enables workflows to create and manage issues, post comments, transition issues through workflows, track dependencies, and automatically open Linear agent sessions when issues are created or mentioned. This is the recommended tracker for Rensei workflows.
What you can do
- Issue management: create, read, update, search issues and sub-issues
- Comments: post and update comments on issues
- Status and metadata: change issue status, assignee, priority, due date, labels, cycle
- Dependencies: add/remove issue relationships and dependencies
- Agent sessions: automatically create Linear AgentSession entries and emit agent activity (thoughts, responses)
- Webhooks: receive issue.created, issue.updated, comment.created, and mention events
- Conditions: filter on issue status, priority, assignee, cycle, project, and team
Connect Linear
Authorize Rensei via OAuth (recommended)
- In Rensei, go to Settings → Integrations and select the Linear card
- Click Connect
- You are redirected to Linear's OAuth authorization flow
- Authorize the Rensei app to access your workspace
Required OAuth scopes:
| Scope | Purpose |
|---|---|
read | Read issues, comments, teams, cycles, projects |
write | Update issues and comments |
issues:create | Create new issues and sub-issues |
comments:create | Post comments on issues |
app:assignable | Agent can assign issues to itself (required for AgentSession) |
app:mentionable | Agent can be @mentioned in Linear comments (required for activity emission) |
If either app:assignable or app:mentionable is missing, agent activity will fail with a 401 when Rensei tries to emit thoughts or responses to Linear.
Alternative: use an API key
If OAuth is unavailable or you prefer manual key management:
- In Rensei, go to Settings → Integrations → Linear
- Click Use API Key
- Go to linear.app/settings/api and click + Create key
- Paste the key into Rensei and click Connect
API keys grant all workspace permissions but cannot be scoped per team. OAuth is preferred for multi-team workspaces.
Webhooks are auto-managed: Rensei subscribes to Linear events on connect - no manual webhook configuration needed.
Webhook setup (automatic)
Unlike GitHub or Vercel, Linear webhooks are auto-managed: no manual configuration needed.
When you connect the Linear integration, Rensei:
- Validates your credential
- Automatically subscribes to Linear webhook events (issue.created, issue.updated, comment.created)
- Stores the webhook subscription ID
- Begins receiving real-time events
Rensei routes events through the platform webhook gateway at /api/webhooks/ingest/linear. Signing secret configuration is handled at the deployment level by the platform operator.
Webhook events
| Event | Trigger | Payload |
|---|---|---|
issue.created | New issue in any team | Issue #, title, description, creator, team, project |
issue.updated | Issue changed (status, assignee, etc.) | Issue #, field changed, old value, new value |
comment.created | Comment posted on an issue | Issue #, comment body, author |
issue.mention | Issue or URL mentioned in a message | Issue #, mentioned in, context |
These events are available as workflow triggers (e.g., trigger.linear.issue.created).
Workflow nodes
All Linear workflow nodes are in the Linear section of the node palette. Available only when the Linear integration is connected.
Triggers
| Node | Payload |
|---|---|
trigger.linear.issue.created | Issue #, title, description, creator, team, project, priority |
trigger.linear.issue.updated | Issue #, field changed, old/new values |
trigger.linear.comment.created | Issue #, comment body, author |
trigger.linear.mention | Mentioned issue/URL, context, author |
Example: Trigger a workflow when a high-priority issue is created
trigger:
type: trigger.linear.issue.created
steps:
- id: check_priority
type: condition
condition: "{{ $trigger.linear.issue.priority >= 1 }}" # High/Urgent
onTrue: [assign_to_team]Issue CRUD operations
| Node | Description |
|---|---|
linear.issue.create | Create a new issue in a team or project |
linear.issue.get | Fetch issue details by ID or search |
linear.issue.update | Update issue title, description, or metadata |
linear.issue.search | Search issues by team, status, assignee, or custom filter |
linear.issue.create_sub_issue | Create a sub-issue under an existing issue |
Example: Create an issue from a GitHub PR
- id: create_issue
type: linear.issue.create
inputs:
teamId: "ENG"
title: "{{ $trigger.github.pull_request.title }}"
description: |
PR: {{ $trigger.github.pull_request.html_url }}
Files changed:
{{ $trigger.github.pull_request.files | join(', ') }}
priority: 3 # Medium
assignee: "{{ $trigger.github.pull_request.assignee }}"Example: Search for issues in a cycle
- id: find_issues
type: linear.issue.search
inputs:
teamId: "ENG"
filter: 'cycle:"Current" status:"In Progress"'
limit: 50Issue status and metadata
| Node | Description |
|---|---|
linear.issue.set_status | Change issue state (Backlog, Todo, In Progress, Done, Cancelled) |
linear.issue.set_assignee | Assign issue to a team member |
linear.issue.set_priority | Set priority (0=None, 1=Urgent, 2=High, 3=Medium, 4=Low) |
linear.issue.set_due_date | Set or clear the due date |
linear.issue.add_label | Add a label to an issue |
linear.issue.remove_label | Remove a label from an issue |
linear.issue.set_cycle | Assign issue to a cycle |
linear.issue.set_parent | Set the parent issue (for sub-issues) |
Example: Escalate an issue to high priority
- id: escalate
type: linear.issue.set_priority
inputs:
issueId: "{{ $trigger.linear.issue.id }}"
priority: 1 # UrgentExample: Move completed issues to Done
- id: mark_done
type: linear.issue.set_status
inputs:
issueId: "{{ $steps.verify.issue_id }}"
status: "Done"
statusId: "done" # Linear's canonical status IDComments
| Node | Description |
|---|---|
linear.comment.create | Post a comment on an issue |
linear.comment.update | Edit an existing comment |
Example: Post an agent summary comment
- id: post_comment
type: linear.comment.create
inputs:
issueId: "{{ $trigger.linear.issue.id }}"
body: |
## Agent Summary
Status: {{ $steps.agent.status }}
Changes:
- {{ $steps.agent.changes | join('\n- ') }}
Next: {{ $steps.agent.next_action }}Dependencies and relationships
| Node | Description |
|---|---|
linear.issue.add_relation | Create a relationship (blocks, duplicates, relates to) |
linear.issue.remove_relation | Remove a relationship |
Example: Mark an issue as blocking another
- id: mark_blocking
type: linear.issue.add_relation
inputs:
fromIssueId: "{{ $trigger.linear.issue.id }}"
toIssueId: "{{ $steps.find_dependent.id }}"
type: "blocks"Agent sessions
When an agent interacts with Linear (via workflow or dispatch), Rensei automatically creates a Linear AgentSession entry that tracks:
- Session ID: Unique identifier for the agent's interaction
- Issue: The Linear issue being worked on
- Activities: Agent thoughts, actions, responses, errors
- Status: active, complete, failed
AgentSession creation
An AgentSession is created when:
- A workflow with a
trigger.linear.issue.createdortrigger.linear.issue.updatedtrigger fires and the agent is dispatched - An agent is explicitly invoked via the A2A registry with a Linear workspace
- A workflow mentions a Linear issue and an agent is called to respond
Activity emission
During the agent's session, the platform emits activities to Linear as comments on the issue:
| Activity Type | Example | Visibility in Linear |
|---|---|---|
thought | "Analyzing the issue requirements..." | Hidden (internal agent reasoning) |
action | "Creating PR https://github.com/..." | Posted as comment with agent activity |
response | "Done! PR ready for review." | Posted as comment with summary |
error | "Failed: Linear API unavailable" | Posted as error comment |
Activities appear as comments from the Rensei user (assignable via OAuth scopes) or a service account.
Session lifecycle
An AgentSession is created when:
- A
trigger.linear.issue.createdwebhook fires and the workflow dispatches an agent - An agent is directly invoked via A2A with a Linear workspace context
- A @mention in Linear triggers a
promptedevent (feature-gated)
A Linear AgentSession has three trigger types:
| Trigger | Source | Notes |
|---|---|---|
created | SDLC workflow dispatch | Used by the default SDLC template |
prompted | @mention in a Linear comment | Drops silently if no sub-workflow is configured |
primary | A2A direct dispatch | Advanced; requires A2A registry setup |
Note: Only created and primary are currently surfaced in the SDLC default template. prompted (from @mention) is feature-gated and drops silently if no agent sub-workflow is configured.
Session closure
Linear AgentSession has no close mutation - closure is inferred from the last activity.
The SDLC default template emits a linear.agent_session.close node at the terminal of every SDLC branch, which emits a final response activity that transitions the session from active to complete.
Refer to Linear AgentSession for detailed lifecycle semantics.
Conditions
Linear workflow conditions filter on issue metadata:
| Condition | Example |
|---|---|
issue.status == "In Progress" | Check if issue is in progress |
issue.priority >= 2 | Check if high or urgent |
issue.assignee == user | Check assigned person |
issue.cycle == "Current" | Check if in current cycle |
issue.project == "proj" | Check project membership |
issue.team == "ENG" | Check team |
issue.labels contains "bug" | Check labels |
Example: Escalate if unassigned for too long
- id: check_assignment
type: condition
condition: |
{{ $trigger.linear.issue.assignee == null &&
now() - $trigger.linear.issue.createdAt > 48h }}
onTrue: [escalate_to_manager]Authentication and permissions
The Linear integration requires the following OAuth scopes:
read- read issues, comments, cycles, teamswrite- update issues and commentsissues:create- create new issues and sub-issuescomments:create- post comments on issuesapp:assignable- agent can assign issues to itself (required for AgentSession)app:mentionable- agent can be mentioned in comments (required for activity emission)
If a scope is missing, the agent will fail with a 401 error when trying to emit activities.
Webhook secret: Linear issues one signing secret per Rensei Linear App. All organizations that connect to Rensei share the same app-level secret. Per-org custom Linear apps can override via org-level credential configuration; contact your Rensei operator for deployment-level webhook configuration.
Cost and rate limits
Linear's GraphQL API has soft rate limits (not explicitly documented, but ~5,000 query-points/hour per app). Workflow engines respect this limit and retry with exponential backoff if approached.
Recommendation: For high-volume agent workflows:
- Batch multiple issue updates into a single mutation when possible
- Cache issue search results in workflow steps
- Use issue relationships (depends-on) instead of fetching dependent issues directly
Cost is zero - Linear includes API calls in your plan.
Troubleshooting
"Webhook signature verification failed"
- Ensure your Linear API key or OAuth token is still valid
- Re-authorize in Settings → Integrations
- Check that the webhook secret matches (should be auto-managed, but double-check the env var)
"Agent activity not appearing in Linear"
- Verify the Linear OAuth scopes include
app:assignableandapp:mentionable - Check the session's activity feed in Sessions → Inspector → Activities
- Confirm the agent has permission to comment on the issue (team-level access)
"Agent session not created"
- Ensure the issue is in the correct Linear team
- Verify the SDLC template includes agent dispatch on the stage
- Check workflow logs for dispatch errors
"API rate limit exceeded"
- Wait a few minutes before retrying
- Use issue.search() to batch-fetch multiple issues instead of individual get() calls
- Consider caching search results in workflow steps
Next steps
- SDLC default template - See how Linear integrates with agent workflows
- Agent cards - Assign agents to Linear SDLC stages
- Workflow triggers - Set up issue-based triggers
- Agent sessions - Monitor agent activity in Linear