> For the complete documentation index, see [llms.txt](https://docs.pagerly.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pagerly.io/task-management/assign-tickets-to-current-oncall/assign-linear-issues-to-current-oncall.md).

# Assign Linear Issues to the Current Oncall

Put the current on-call engineer on Linear triage and issue assignment — using Linear's native Triage Responsibility or the Linear GraphQL API.

Linear has a first-class concept for this — **Triage Responsibility** — and Pagerly plugs straight into it. That is the path to use if you can. The GraphQL API covers everything else.

## Option 1 — Triage Responsibility (recommended)

Linear's [Triage](https://linear.app/docs/triage) is the inbox for issues that arrive without an owner: bug reports from customers, Sentry issues, form submissions, anything filed by someone outside the team. Triage Responsibility decides who picks them up.

Pagerly keeps a Linear **time schedule** in sync with your Pagerly rotation, then binds that schedule to the team's Triage Responsibility with the `assign` action. The effect: Linear itself assigns triage issues to whoever Pagerly says is on call, and it keeps working during overrides and swaps because the schedule is rewritten, not the rule.

### Set it up

1. [Connect your Linear account](/integrations/linear-integration/connect-linear-account.md) to Pagerly.
2. [Connect the Pagerly team to the Linear team](/integrations/linear-integration/connect-pagerly-team-and-linear-team.md).
3. Enable triage assignment on the Pagerly team. Pagerly creates the Linear time schedule and the triage responsibility for you.

Pagerly pushes schedule entries as `{ startsAt, userId, endsAt }`, resolving each Pagerly user to a Linear user by email. Once it is running, an issue that lands in triage is assigned without anyone touching it.

{% hint style="info" %}
This works best with a [Pagerly schedule rotation](/oncall-and-rotations/create-round-robin-rotations.md) rather than an ad-hoc list — the Linear schedule mirrors Pagerly's shift boundaries directly.
{% endhint %}

### What it does not cover

Triage Responsibility only fires for issues that enter triage. Issues created directly in a project by a team member skip triage entirely. For those, use option 2.

## Option 2 — Linear GraphQL API

Two steps: resolve the on-call user's email to a Linear user ID, then update the issue.

### Step 1 — who is on call

```bash
curl -s 'https://api.pagerly.io/pagerly/o/currentusers?teamname=devops' \
  -H "X-APIKEY: $PAGERLY_API_KEY"
```

```json
[{ "name": "mansi", "email": "mansi@pagerly.io", "id": "U04CTTV5Z6G", "imageurl": null }]
```

### Step 2 — email to Linear user ID

```graphql
query {
  users(filter: { email: { eq: "mansi@pagerly.io" } }) {
    nodes {
      id
      email
      name
    }
  }
}
```

```bash
curl -s https://api.linear.app/graphql \
  -H "Authorization: $LINEAR_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"query":"query { users(filter: {email: {eq: \"mansi@pagerly.io\"}}) { nodes { id email name } } }"}'
```

`nodes` is empty if the email does not match a Linear member — treat that as a hard failure, not a silent no-op.

### Step 3 — assign the issue

```graphql
mutation {
  issueUpdate(
    id: "<issue-uuid>"
    input: { assigneeId: "<linear-user-id>" }
  ) {
    success
    issue {
      id
      identifier
      title
      url
      assignee { id name }
    }
  }
}
```

Check `success` in the response — Linear returns `200` with `success: false` for a rejected update, so an HTTP status check alone is not enough.

### Assign at creation time

If your service files the issue itself, set the assignee in the same call rather than creating then updating:

```graphql
mutation {
  issueCreate(
    input: {
      teamId: "<linear-team-id>"
      title: "Checkout returns 500 for EU cards"
      description: "..."
      assigneeId: "<linear-user-id>"
    }
  ) {
    success
    issue { id identifier url assignee { id name email } }
  }
}
```

## Full example

```bash
#!/usr/bin/env bash
set -euo pipefail

TEAM="devops"
ISSUE_ID="$1"

EMAIL=$(curl -sf "https://api.pagerly.io/pagerly/o/currentusers?teamname=$TEAM" \
  -H "X-APIKEY: $PAGERLY_API_KEY" | jq -r '.[0].email // empty')

if [ -z "$EMAIL" ]; then
  echo "Nobody on call for $TEAM — leaving issue unassigned" >&2
  exit 1
fi

USER_ID=$(curl -sf https://api.linear.app/graphql \
  -H "Authorization: $LINEAR_API_KEY" \
  -H 'Content-Type: application/json' \
  -d "{\"query\":\"query { users(filter: {email: {eq: \\\"$EMAIL\\\"}}) { nodes { id } } }\"}" \
  | jq -r '.data.users.nodes[0].id // empty')

if [ -z "$USER_ID" ]; then
  echo "On-call user $EMAIL has no Linear account" >&2
  exit 1
fi

curl -sf https://api.linear.app/graphql \
  -H "Authorization: $LINEAR_API_KEY" \
  -H 'Content-Type: application/json' \
  -d "{\"query\":\"mutation { issueUpdate(id: \\\"$ISSUE_ID\\\", input: {assigneeId: \\\"$USER_ID\\\"}) { success } }\"}"
```

## Reassignment on handover

Triage Responsibility handles new issues, not ones already open. If you want in-flight issues to move at shift change, run a scheduled job that queries issues in the states you care about and re-runs the mutation. Be selective — silently moving an issue away from someone mid-investigation loses context. Most teams only move issues that are still untouched.

## Troubleshooting

| Symptom                                        | Cause                                            | Fix                                                                                                                     |
| ---------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `users.nodes` empty                            | Pagerly email ≠ Linear email                     | Align the primary email, or map it in your automation                                                                   |
| `issueUpdate` returns `success: false`         | Issue ID is an identifier (`ENG-42`), not a UUID | Resolve the UUID first, or use the `issue(id:)` lookup                                                                  |
| Triage assignment stopped                      | Pagerly team no longer linked to the Linear team | Re-run [Connect Pagerly Team and Linear Team](/integrations/linear-integration/connect-pagerly-team-and-linear-team.md) |
| Issues created in a project are never assigned | They never entered triage                        | Use option 2, or route creation through triage                                                                          |

## Related

* [Linear Integration](/integrations/linear-integration.md)
* [Sync Schedules to Google Calendar, Linear and Jira](/oncall-and-rotations/sync-schedules-to-google-calendar-linear-and-jira.md)
* [Assign Jira Tickets to the Current Oncall](/task-management/assign-tickets-to-current-oncall/assign-jira-tickets-to-current-oncall.md)
