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

> ## Agent Instructions
> Charter works for any HTTP API, including the user's own. The packs are examples of the result, not the limit: an API with no pack is declared the same way, following https://raw.githubusercontent.com/r28ai/charter/main/docs/.mintlify/skills/declaring-charter-tools/SKILL.md.
> Charter is for agents that act in customers' accounts: every call is checked field by field before it's sent, the app says whose account each call is for, and the same declarations list what each tool can reach. https://docs.r28.ai/charter/llms.txt says what it is and lists every page.

# Register a Linear OAuth application

> The OAuth application your users' Linear workspaces authorize: the form, the switch that lets other workspaces install it, and the credentials, with a screenshot for each.

Before your users can connect their Linear workspaces, Linear needs an OAuth
application that you own and they authorize. You register it once, from a
workspace you're an admin of, and it takes about three minutes.

Only connecting your own workspace? A personal API key from
[linear.app/settings/account/security](https://linear.app/settings/account/security)
is all the [`linear`](https://docs.r28.ai/charter/charter/packs/linear) pack needs. Set it as `LINEAR_API_KEY`.

Every Linear link below opens in a new tab, so this page stays where you left it.

**1. Start a new OAuth application**

Open [linear.app/settings/api](https://linear.app/settings/api) and, under
**OAuth Applications**, click **New OAuth application**.

![Linear's API settings page, with a New OAuth application button in the OAuth Applications section.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/linear/01-new-oauth-app.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=621ba3cfd94f57ecaff410319edf4a85)

**2. Fill in the form**

![The new OAuth application form: application name Example App, developer name Example Inc., developer URL https://app.example.com, callback URL https://app.example.com/oauth/linear/callback (highlighted), an empty GitHub username, Public switched on, and Client credentials and Webhooks switched off.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/linear/02-app-form.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=7edb218f6919fe3e5f22d1c7ed220816)

* **Application name**, **Developer name**, **Developer URL**: what your users
  see on the consent screen.
* **Callback URLs**: your app's callback route, one per line. Linear redirects
  only to a URL listed here.
* **GitHub username**: leave it empty. It only matters for apps that act as
  themselves and want their commits attributed.
* **Public**: switch it **on**. With it off, only the workspace you're in can
  authorize the app, which is fine for testing and wrong for your users.
* **Client credentials**: leave it off. That grant is for an app acting on its
  own workspace, and this flow acts on behalf of each user.

Click **Create**.

**3. Copy the client ID and secret**

Linear opens the application's page. Under **OAuth credentials**, copy the
**Client ID** and the **Client secret**.

![The application's page: developer, redirect URIs and availability, then an OAuth credentials panel with the client ID, a masked client secret, and a developer token row.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/linear/03-credentials.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=37d202d6350d5d18f7031b5a4bb25a9a)

```bash theme={null}
export LINEAR_CLIENT_ID=3f9a1c07be52d4e8a6b0c91d27e4f538
export LINEAR_CLIENT_SECRET=...
```

**4. Connect a workspace**

Your app's "Connect Linear" button opens the link that
[`flow.authorize()`](https://docs.r28.ai/charter/charter/reference/oauth#oauth2flow-authorize) builds. Linear
shows what the app is asking for, and the user clicks **Authorize**.

![Linear's consent screen: Example App is requesting access to the Example Workspace workspace, with read and write access listed, and Cancel and Authorize buttons.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/linear/04-consent.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=16c866ba22266b8507810b3c342aea5b)

`read` and `write` cover the pack's tools. Don't ask for `admin`: it adds a
line about managing settings and people to this screen, and no tool needs it.

The server constant and the per-user client are in the
[Linear provider page](https://docs.r28.ai/charter/charter/auth/providers/linear.md). Two details from there
matter here. Linear's access tokens last 24 hours and its refresh tokens
rotate, so `on_refresh` has to store each new one. And Linear separates scopes
with commas, which the constant already declares.

## When it does not work

> **Users in other workspaces can't authorize the app**
>
> **Public** is off. Open the application from
> [linear.app/settings/api](https://linear.app/settings/api), switch it on and
> save.

> **invalid\_request: Invalid refresh token, on a refresh that worked yesterday**
>
> The refresh token was used and its replacement was never saved. Linear
> rotates refresh tokens, and the old one stops working 30 minutes after it
> was used. Linear says so with `invalid_request` rather than
> `invalid_grant`. Store the new one in `on_refresh`, then have the user
> connect again.

> **401 on a token that should be valid**
>
> Linear wants an OAuth token sent as `Bearer` and a personal API key sent
> with no scheme at all. The pack tells them apart by the key's `lin_api_`
> prefix, so make sure what you hand it is the access token, not the client
> secret.

## Related

* [Linear OAuth](https://docs.r28.ai/charter/charter/auth/providers/linear.md) — the server constant, and a pasted key beside OAuth in one configuration
* [Getting the grant](https://docs.r28.ai/charter/charter/auth/oauth-flow.md) — the two routes, `state` and PKCE, inside your app
* [Linear](https://docs.r28.ai/charter/charter/packs/linear.md) — the pack, and why a personal key goes out with no scheme


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.