> ## Documentation Index
> Fetch the complete documentation index at: https://docs.serval.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Linear

> Sync Serval tickets to Linear issues and automate issue management in your Linear workspace with Serval workflows.

## About Linear

Linear is the issue tracker many engineering and product teams use to plan and ship work. Serval's Linear integration connects to your Linear workspace so Serval tickets and Linear issues stay in sync - with comments attributed to the original requester rather than a generic app identity - and ships 15 installable workflows for issue management and workspace lookups. All traffic goes to Linear's GraphQL API (host: api.linear.app).

**Authentication:** OAuth 2.0 - sign in with the Serval-managed Linear OAuth app (recommended), or bring your own Linear OAuth application. Both modes request only the **read** and **write** scopes, and tokens are refreshed automatically.

**Data sync:** Two-way ticket syncing runs in the background once a Linear team is connected as a ticket channel: Serval regularly checks the team for new and updated issues and comments and pulls them in, and pushes Serval-side changes out to Linear as they happen. Workflow actions run on demand, calling Linear at the moment they run.

## What the Linear integration enables

| Capability                                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ticket syncing                                  | Two-way sync between Serval tickets and Linear issues. Outbound, Serval creates and updates issues, adds comments (duplicates are automatically detected and reused), maps issue states, and applies SLA timestamps - and issues and comments show up in Linear attributed to the original requester. Inbound, Serval regularly checks the connected Linear team and pulls new and updated issues and comments into Serval.                                                                                                                           |
| Issue management workflows                      | 11 installable workflows: Get Linear Issue Info (by URL, key like ENG-123, or ID), Add Comment to Linear Issue, Add Label to Linear Issue, Archive Linear Issue, Delete Linear Issue, Clear Linear Issue Priority, Move Linear Issue to Different Cycle, Reopen Issue Based on Related Issues, Update Linear Issue Description (markdown supported), Update Linear Issue Title, and Update Linear Issue Project. Destructive workflows (archive, delete, clear priority, move cycle, reopen, update project) default to requiring installer approval. |
| Workspace workflows                             | 4 installable workflows: Get Linear User ID (email to user ID, including suspended users), Invite Linear User (requires installer approval), List Linear Labels (active global and team labels), and List Linear Teams.                                                                                                                                                                                                                                                                                                                               |
| Generic API access                              | Serval workflows can call any operation in Linear's GraphQL API through the integration, with authentication injected automatically and cursor-based pagination supported. See Linear's [GraphQL API guide](https://developers.linear.app/docs/graphql/working-with-the-graphql-api).                                                                                                                                                                                                                                                                 |
| Access management (deprecated for new installs) | Built-in workflows that invite a user with the Admin or Member role, or suspend a user by email. Existing installs keep working, but this is deprecated for new installs - see Gotchas and troubleshooting below.                                                                                                                                                                                                                                                                                                                                     |

Anything defined in the [Linear API](https://developers.linear.app/docs) can be accessed through Serval.

## Get your credentials

<Tabs>
  <Tab title="Serval-managed OAuth app (recommended)">
    No setup is needed in Linear. Serval uses its own Linear OAuth application, so connecting is just an authorization: you're sent to Linear's consent screen, you approve **read** and **write** access, and Serval records your Linear workspace name and ID as the connected instance. Tokens are refreshed automatically from then on.
  </Tab>

  <Tab title="Bring your own Linear OAuth app">
    If your organization prefers to own the OAuth application, create one in your Linear workspace and hand its credentials to Serval. Linear's official guide is the [OAuth 2.0 authentication documentation](https://developers.linear.app/docs/oauth/authentication).

    <Steps>
      <Step title="Create (or open) an OAuth application in Linear">
        In Linear, go to **Settings → API → Applications** and [create a new OAuth application](https://linear.app/settings/api/applications/new), or open an existing one.
      </Step>

      <Step title="Register Serval's Callback URL">
        Copy the **Callback URL** shown in Serval's connect dialog and paste it into the application's **Callback URLs** list.

        <Warning>
          Linear requires an exact match between the registered Callback URL and the one Serval uses during authorization. Use the Copy button in Serval's dialog and paste it verbatim - a retyped or partial URL will be rejected.
        </Warning>
      </Step>

      <Step title="Copy the Client ID and Client secret">
        Save the application, then copy its **Client ID** and **Client secret** from the application's settings page.

        <Note>
          Linear shows the client secret only once, at creation. If you no longer have it, regenerate the secret on the application's settings page.
        </Note>
      </Step>

      <Step title="Enter the credentials in Serval">
        Back in Serval, enter the optional Display name plus the Client ID and Client secret, and click Connect to run the OAuth authorization.
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Connect in Serval

<Steps>
  <Step title="Choose how to connect">
    The connect dialog offers two options: **"Sign in with Linear (OAuth)"** (tagged "Recommended") - "Connect using the Serval-managed Linear OAuth app." - and **"Use your own Linear OAuth app"** - "Connect with a Linear OAuth application owned by your workspace."
  </Step>

  <Step title="Serval-managed: authorize on Linear">
    Click **Sign in with Linear (OAuth)** and approve the request on Linear's consent screen. If the sign-in can't start, the dialog shows "Failed to initiate Linear OAuth" - try again or contact support.
  </Step>

  <Step title="Your own app: fill in the form">
    The custom-app form contains:

    * **Callback URL** - read-only, with a Copy button. Register this value on your Linear OAuth application before connecting.
    * **Display name** (optional) - "A friendly name shown in Serval - you choose this." Placeholder: "My Company Linear".
    * **Client ID** (required) - "Found on the application's settings page in Linear, under OAuth." Serval rejects a blank value with "clientId is required".
    * **Client secret** (required, hidden as you type) - "Linear only shows this once when the app is created - if you don't have it, regenerate the secret on the application's settings page." Serval rejects a blank value with "clientSecret is required".

    The Connect button stays disabled until both required fields are filled in. If the connection can't start, you'll see "Failed to initiate custom Linear app".
  </Step>

  <Step title="Complete the authorization on Linear">
    Approve the request on Linear's consent screen. You have **10 minutes** from submitting the form - after that the attempt fails with "Invalid or expired OAuth state" and you must resubmit. If Linear rejects the exchange (for example, a mismatched Callback URL or wrong secret), you'll see "Failed to exchange code for token". On success, Serval records your Linear workspace name and ID as the connected instance.
  </Step>
</Steps>

<Note>
  When reconnecting a bring-your-own-app install, the Display name and Client ID are pre-filled from your existing setup, but the Client secret is never pre-filled - re-enter it (or regenerate it in Linear if you've lost it).
</Note>

## Verifying the connection

The Linear integration runs three health checks:

* **Test Linear Connection** - verifies the integration is connected and the OAuth token is valid by reading a single user from your workspace.
  * Success: "Successfully authenticated with Linear (found \[number] user)"
  * Failure: "Unable to authenticate with Linear. Please verify the integration is still connected and the OAuth token has not been revoked."
* **List Linear Users** - checks that Serval can read users from the connected workspace.
  * Success: "Successfully listed Linear users (sample size: \[number])"
  * Failure: "Unable to list users from Linear. Please verify the integration has the read scope and has not been disconnected."
* **List Linear Teams** - checks that Serval can read teams from the connected workspace.
  * Success: "Successfully listed Linear teams (sample size: \[number])"
  * Failure: "Unable to list teams from Linear. Please verify the integration has the read scope and has not been disconnected."

<Tip>
  All three checks exercise read access only. If every check is green but a workflow that invites or suspends a workspace member fails, the cause is usually that this integration deliberately has no admin scope - see the first item under Gotchas and troubleshooting.
</Tip>

## Gotchas and troubleshooting

<AccordionGroup>
  <Accordion title="Only the read and write scopes are granted - there is no admin scope">
    This integration requests exactly **read** and **write**. The connection mode that lets Serval attribute issues and comments to the original requester is incompatible with Linear's admin scope, so admin was deliberately dropped. Admin-level workspace-membership management (inviting and suspending users) lives in the companion **[Linear Admin](/sections/integrations/linear-admin)** integration instead. The older built-in access-provisioning workflows on this integration (invite with the Admin or Member role, suspend by email) still work for existing installs but are deprecated for new ones; their role mapping accepts only "Admin", "Member", or "User" - any other role name fails. If older documentation mentions a third scope or an admin scope, it is out of date.
  </Accordion>

  <Accordion title="Issues and comments are attributed to the original requester">
    Serval connects to Linear in app-actor mode, which is what allows synced issues and comments to appear in Linear as the person who raised the ticket rather than as a generic app identity. This applies to both the Serval-managed and bring-your-own connection options.
  </Accordion>

  <Accordion title="Bring-your-own app: the Callback URL must match exactly, and the secret is shown once">
    Linear requires an exact match between the Callback URL registered on your OAuth application and the one Serval uses during both authorization and token exchange, and it rejects relative URLs. Always copy the value from Serval's connect dialog verbatim. Separately, Linear displays the client secret only once at app creation - if it's lost, regenerate it on the application's settings page and reconnect with the new value.
  </Accordion>

  <Accordion title="&#x22;Invalid or expired OAuth state&#x22; during a bring-your-own connection">
    Submitted credentials are held for only 10 minutes while you complete Linear's consent screen. If the window passes, the attempt fails with "Invalid or expired OAuth state". Re-open the connect dialog and submit the form again, then complete the authorization promptly.
  </Accordion>

  <Accordion title="Tokens refresh automatically - with one hard failure case">
    Serval refreshes OAuth tokens automatically shortly before they expire, and older long-lived tokens on Serval-managed connections are upgraded to refreshable tokens transparently. The one case that requires action: a bring-your-own-app connection whose token expires with no refresh token available fails with "custom Linear app access token expired and no refresh token available; reconnect required". The fix is to reconnect the integration.
  </Accordion>

  <Accordion title="SLA timestamps only apply to unstarted or started issues">
    During ticket sync, SLA-breach timestamps are written to a Linear issue only when that issue is in an unstarted or started state. For issues in any other state, the timestamp is silently dropped rather than causing a sync error.
  </Accordion>

  <Accordion title="&#x22;invalid_grant: authorization code is invalid&#x22; when testing your OAuth app outside Serval">
    Linear authorization codes are single-use, and Linear expects OAuth credentials as form parameters in the request body. Tooling that tries a different credential style first and then retries will burn the code on the failed attempt, producing "invalid\_grant: authorization code is invalid" even with correct credentials. Serval sends credentials correctly on the first attempt - this only matters if you debug the token exchange with your own tooling.
  </Accordion>
</AccordionGroup>

***

Need help? Contact **[support@serval.com](mailto:support@serval.com)** for assistance with your Linear integration.
