<!--
Sitemap:
- [Installation](/installation)
- [Upgrading](/upgrading): Version-specific steps for upgrading an existing Bento install.
- [Concepts](/concepts)
- [Build your first pipeline](/tutorials/pipeline-args)
- [Target a specific issue or PR from a URL](/tutorials/url-targeting)
- [Keep state across runs](/tutorials/pipeline-state)
- [Fire a pipeline on a schedule or on demand](/tutorials/schedule-and-fire)
- [Deploy a box to Railway](/tutorials/deploy-to-railway)
- [Operate a hosted daemon](/tutorials/operate-a-hosted-daemon)
- [Configuration](/configuration)
- [Members](/members)
- [Knowledge base](/knowledge-base/)
- [Method and delivery](/knowledge-base/modes)
- [Config](/knowledge-base/config)
- [MCP](/knowledge-base/mcp)
- [Pipeline configuration reference](/pipelines/config)
- [Filters](/pipelines/filters)
- [Triggers](/triggers/)
- [GitHub trigger](/triggers/github)
- [Linear trigger](/triggers/linear)
- [Webhook trigger](/triggers/webhook)
- [Schedule trigger](/triggers/schedule)
- [Manual trigger](/triggers/manual)
- [Traces](/pipelines/traces)
- [Slack](/integrations/slack)
- [Public access](/public-access)
- [Context engineering](/context-engineering)
- [Best practices](/best-practices)
- [Troubleshooting](/troubleshooting)
- [Architecture](/architecture/vision)
- [Workspaces](/workspaces)
- [Authentication](/authentication)
- [Identity](/identity)
- [Security](/security)
- [References](/references)
- [Changelog](/changelog): Bento release history.
- [CLI reference](/cli/)
- [Setup](/cli/setup)
- [Secrets](/cli/secrets)
- [Lifecycle](/cli/lifecycle)
- [Sandbox image](/cli/image)
- [Sandboxes](/cli/sandbox)
- [Observability](/cli/observability)
- [Diagnostics](/cli/diagnostics)
- [Triggers](/cli/triggers)
- [Workbench](/cli/workbench)
- [Auth](/cli/auth)
- [Knowledge](/cli/knowledge)
- [Evals](/cli/evals)
- [Bento](/index)
- [Runtime wrapper](/architecture/runtime-wrapper)
- [Skill evolve](/architecture/skill-evolve)
-->

# Linear trigger

The daemon accepts Linear webhooks at `/webhooks/linear`. Point the webhook URL at that path — headers never select the route, so a `linear-event` header on another path does not reach the Linear source.

If you relay through Hookdeck, give Linear a dedicated CLI destination and select its connection explicitly. Do not share that destination with GitHub or Slack. The CLI path belongs to the destination, so a shared destination sends those deliveries to the same path.

```bash
hookdeck listen 7890 LINEAR_SOURCE LINEAR_CONNECTION --path /webhooks/linear
```

Replace the source, connection, and port with your configured values. Preserve the original body and `linear-signature` header. See the [Hookdeck CLI reference](https://github.com/hookdeck/hookdeck-cli/blob/main/REFERENCE.md).

:::note
Creating a Linear webhook requires workspace admin access. To run a loop on your own machine without that access, skip the webhook. Use a [schedule trigger](/triggers/schedule) and poll the Linear API with a token listed in the pipeline's [`env:`](/pipelines/config#env) manifest.
:::

## Signature verification

Linear signs each delivery with HMAC-SHA256 over the raw request body and sends the digest in a `linear-signature` header. Copy the signing secret Linear shows when you create the webhook into `daemon.yaml`:

```yaml
webhooks:
  sources:
    linear:
      verify: linear
      secret: ${LINEAR_WEBHOOK_SECRET}
```

The daemon answers `401` to a payload with a bad or missing signature, and records no event for it. Linear also stamps each delivery with `webhookTimestamp`. The daemon rejects a timestamp more than a minute from its own clock. This check rejects replays of older captured deliveries. Omit the source and the `/webhooks/linear` route rejects everything. See [Security](/security#webhook-validation).

## Event string format

Linear sends `type` and optionally `action` in the JSON payload:

```
payload.type:   Issue
payload.action: create
→ event string: "Issue.create"

payload.type:   Issue
(no action)
→ event string: "Issue"
```

## Supported events

| Event pattern | When |
|---|---|
| `Issue.create` | New issue created |
| `Issue.update` | Issue updated |
| `Comment.create` | Comment posted on an issue |
| `AgentSessionEvent.created` | A delegation or mention opens an agent session |
| `AgentSessionEvent.prompted` | A person replies in an agent session |

## Agent sessions

Install the Linear application with [`bento setup linear`](/cli/setup#bento-setup-linear) before you use an agent-session trigger.

An agent session names an issue but does not name a repository. Set `trigger.repo` on each agent-session pipeline. Set `trigger.branch` when the registered repository branch is not correct. Bento rejects an agent-session pipeline that has no registered repository.

Linear opens a session from a project or a document too, not only from an issue. That session names no issue, so Bento refuses it and tells the delegator to delegate from an issue instead.

Each session uses one workspace. A reply starts another run in that workspace, so the run receives the session history and prior notes.

Bento acknowledges each accepted session as soon as its work is queued, and posts one `thought` while it prepares the workspace. Bento reports an error in the session when no pipeline accepts the event.

During a run, the `report_progress` tool publishes `thought`, `action`, `question`, and `done` activities to Linear. Bento records each of those as a progress note. The workspace-preparing `thought` leaves none. An identical retry produces one activity. A completed run gets no terminal activity when it reported `done`, which already closed the session, or when it left a question unanswered, because the question is the live state of the session. Every other run gets a terminal activity: a response when the run completed, an error when it did not.

The **Stop** action sends a prompted event with a stop signal. Bento cancels every active run for that session and starts no run. If no run is active, Bento replies that nothing was running.

See [Linear pipeline configuration](/pipelines/config#linear) for event filters, delegation and mention routing, and a complete agent-session trigger.

## Principal binding

A pipeline with a Linear trigger posts back to Linear as a Linear principal. It must select a [principal binding](/identity#principal-bindings) that names a `linear.principal.*` reference. Config load rejects a pipeline with a Linear trigger that selects no such binding. `bento setup linear` prints the reference to bind.

## Example

```yaml
# Fire when a new issue is created in a specific team
trigger:
  linear:
    - Issue.create
  filter:
    when:
      data.team.key: HAR
principals:
  issue-coordinator:
    - github.principal.your-org-author-agent
    - linear.principal.bento-agent
principal: issue-coordinator
```

## Event variables

In a filter expression, omit the `event.` prefix, for example `data.team.key`. In `instructions`, use the full path, for example `{{event.data.team.key}}`.

| Variable | Value |
|---|---|
| `event.data.title` | Issue title |
| `event.data.description` | Issue description |
| `event.data.team.key` | Team key, for example `HAR` |
| `event.data.priority` | Issue priority |
| `event.agentSession.issue.identifier` | Issue identifier for an agent session |
| `event.promptContext` | Initial request for a new agent session |
| `event.agentActivity.content.body` | Follow-up request in an existing agent session |

## See also

* [Filters](/pipelines/filters) — narrow which events reach this pipeline
