Skip to content

nshkrdotcom/linear_sdk

Repository files navigation

LinearSDK

Hex.pm HexDocs GitHub

LinearSDK

LinearSDK is an Elixir SDK for Linear with a thin provider-facing client and a generated full-schema API reference published as module docs.

The repo is intentionally thin:

  • committed upstream schema and reference artifacts live in priv/upstream/
  • provider configuration lives in codegen/
  • provider-facing handwritten code stays focused on Linear defaults and ergonomics
  • generated internal support code and API reference docs are committed source

What this repo owns

  • Linear-specific base URL defaults
  • provider-local auth shortcuts for personal API keys and OAuth access tokens
  • provider-local OAuth helpers built on Prismatic.OAuth2
  • committed upstream schema artifacts
  • full generated API reference docs for the upstream graph
  • a small curated document set used for internal generation coverage
  • local generation and verification tasks

Install

def deps do
  [
    {:linear_sdk, "~> 0.2.0"}
  ]
end
mix deps.get

For active local development beside sibling checkouts, linear_sdk can also be consumed from a relative path:

{:linear_sdk, path: "../linear_sdk"}

Inside this repo, the shared prismatic dependencies resolve by one stable policy:

  • prefer sibling-relative paths when local checkouts exist for normal compile, test, and docs work
  • use release Hex/GitHub sources when running mix deps.get, mix hex.build, or mix hex.publish so mix.lock stays publishable
  • otherwise use Hex prismatic ~> 0.2.0 plus GitHub subdir: dependencies for prismatic_codegen and prismatic_provider_testkit

That keeps local development, packaging, and downstream dependency behavior aligned without requiring a committed vendored deps/ tree.

Real Linear Onboarding

The current upstream linear/linear repo and Linear's live docs both point to the same operating model:

  • personal API keys are created in Linear under Settings -> Security & access -> Personal API keys
  • OAuth is supported through Linear's authorization, token, refresh, and revoke endpoints, plus client-credentials tokens and a legacy migrate endpoint
  • the first-party TypeScript SDK accepts either a personal API key or an OAuth access token
  • durable token storage and install lifecycle remain your responsibility, but this SDK now exposes provider-local OAuth helpers and runtime-managed token sources

Auth Model

There are three different things to keep straight:

  1. Personal API key This is a user-created secret from Linear settings. You use it directly against the GraphQL API. No OAuth app is involved.
  2. OAuth app This is the app configuration you create in Linear. It gives you a client_id, client_secret, redirect URI list, and optional client-credentials support. It is not itself a GraphQL credential.
  3. OAuth access token This is the credential returned after the OAuth app completes an authorization-code flow or a client-credentials flow. This is what you send to Linear's GraphQL API.

For authorization-code installs, Linear also returns a refresh token. For client-credentials tokens, Linear's docs say there is no refresh token and your server is expected to fetch a new token when needed.

LinearSDK makes the actual GraphQL auth modes explicit:

# Personal API key from Linear settings
client =
  LinearSDK.Client.new!(
    api_key: System.fetch_env!("LINEAR_API_KEY")
  )

# OAuth access token that you obtained elsewhere
oauth_client =
  LinearSDK.Client.new!(
    access_token: System.fetch_env!("LINEAR_OAUTH_ACCESS_TOKEN")
  )

For provider-local OAuth helpers:

{:ok, request} =
  LinearSDK.OAuth.authorization_request(
    client_id: System.fetch_env!("LINEAR_OAUTH_CLIENT_ID"),
    redirect_uri: System.fetch_env!("LINEAR_OAUTH_REDIRECT_URI"),
    scopes: ["read", "write"],
    actor: :app,
    generate_state: true,
    pkce: true
  )

Generated GraphQL versus provider-local OAuth HTTP:

  • the generated GraphQL surface covers app-related schema such as applicationInfo, Application, OAuthAppWebhookPayload, and OAuthAuthorizationWebhookPayload
  • the OAuth HTTP endpoints themselves are not GraphQL operations, so they are handled by LinearSDK.OAuth
  • current LinearSDK.OAuth coverage is:
    • authorize URL / authorization request
    • authorization-code exchange
    • refresh
    • client credentials
  • Linear's documented revoke and migrate_old_token endpoints are not wrapped yet in linear_sdk

OAuth Quickstart

You do not look up an OAuth access token in Linear account preferences. Linear issues the access token only after the OAuth flow completes. In practice:

  • Linear settings are where you create the OAuth app and copy its client_id, client_secret, and redirect URI
  • mix linear.oauth is what exchanges the returned code for an access token
  • --save writes that token to the default local token file so the examples can use it

If you are trying to find the app setup page inside Linear, the current official docs point to Settings -> API -> Your Applications for OAuth apps. That is different from account preferences.

For humans, the simplest path now uses the example helper:

examples/run_all.sh --setup-oauth
examples/run_all.sh --oauth
examples/run_all.sh

For write-capable example runs:

examples/run_all.sh --setup-oauth-write
examples/run_all.sh --oauth-write
examples/run_all.sh --with-write

Those helpers are shortcuts for the full mix linear.oauth ... commands below.

The direct read-only command is:

export LINEAR_OAUTH_CLIENT_ID="..."
export LINEAR_OAUTH_CLIENT_SECRET="..."
export LINEAR_OAUTH_REDIRECT_URI="http://127.0.0.1:40071/callback"
mix linear.oauth --save --manual --no-browser

That flow:

  1. prints the authorize URL
  2. asks you to approve the Linear app
  3. exchanges the returned code
  4. saves the token JSON to ~/.config/linear_sdk/oauth/linear.json unless you override LINEAR_OAUTH_TOKEN_PATH

If you want a write-capable token for the mutation examples, request explicit write scope:

mix linear.oauth --save --manual --no-browser --scope read --scope write

When the optional loopback callback-listener dependencies are present, mix linear.oauth can capture http://127.0.0.1/... callbacks directly. Without them, it falls back to the same paste-back flow documented above.

To refresh the saved token file in place:

mix linear.oauth refresh

If your Linear app supports the client-credentials grant:

mix linear.oauth client-credentials --save --scope read --scope write

Then run either:

mix run examples/viewer.exs
mix run examples/oauth_saved_token_viewer.exs
mix run examples/oauth_application_info.exs
examples/run_all.sh
examples/run_all.sh --with-write

This repo now includes dedicated OAuth examples as well as the operator-facing task wrapper:

  • examples/oauth_authorize_url.exs
  • examples/oauth_exchange_code.exs
  • examples/oauth_saved_token_viewer.exs
  • examples/oauth_refresh_and_viewer.exs
  • examples/oauth_application_info.exs

For the full walkthrough, including app setup, token modes, and how to find your project slug, issue reference, and target workflow states, see guides/oauth-and-token-management.md, examples/README.md, and guides/real-linear-usage.md.

First Live Query

client =
  LinearSDK.Client.new!(
    api_key: System.fetch_env!("LINEAR_API_KEY")
  )

{:ok, response} =
  LinearSDK.execute_document(
    client,
    """
    query Viewer {
      viewer {
        id
        name
        email
      }
    }
    """
  )

Live Examples

All example scripts under examples/ are real Linear connections only. They do not use mocks or fake transports.

export LINEAR_API_KEY=lin_api_...
examples/run_all.sh

That default suite is read-only and auto-discovers a project slug and issue when your workspace has accessible data. If there is no accessible project slug, the polling example falls back to a workspace-scoped issue query so the suite still runs. Mutation examples are available too. The simplest human path is:

examples/run_all.sh --oauth-write
examples/run_all.sh --with-write

The low-level equivalent is still LINEAR_CONFIRM_WRITE=1.

If you want setup instructions instead of immediately running examples:

examples/run_all.sh --setup
examples/run_all.sh --setup-oauth
examples/run_all.sh --setup-oauth-write

If you want the direct OAuth example scripts instead of the helpers:

mix run examples/oauth_authorize_url.exs
mix run examples/oauth_exchange_code.exs
mix run examples/oauth_saved_token_viewer.exs
mix run examples/oauth_refresh_and_viewer.exs
mix run examples/oauth_application_info.exs

See examples/README.md for the full list and the OAuth onboarding checklist.

Docs Map

API reference is published under the Modules tab in HexDocs:

  • LinearSDK.Queries
  • LinearSDK.Mutations
  • LinearSDK.Subscriptions
  • LinearSDK.Objects
  • LinearSDK.Inputs
  • LinearSDK.Interfaces
  • LinearSDK.Unions
  • LinearSDK.Enums
  • LinearSDK.Scalars

Generation Tasks

mix linear.ir
mix linear.generate
mix linear.verify

Generation consumes the committed upstream schema files:

  • priv/upstream/schema/schema.json
  • priv/upstream/schema/schema.graphql

Quality Bar

mix ci

That runs:

  • format check
  • warnings-as-errors compile
  • tests
  • Credo
  • Dialyzer
  • docs

About

Elixir SDK for Linear built on Prismatic, using a schema-driven GraphQL toolchain, thin provider-specific configuration, generated operations and models, and professional docs, verification, and examples for production-grade client use.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages