lineark-sdk
Typed, async-first Rust SDK for the Linear GraphQL API.
Part of the lineark project — an unofficial Linear ecosystem for Rust.
Install
Quick start
use Client;
async
Authentication
Create a Linear API token and provide it via any of these methods (in priority order):
| Method | Example |
|---|---|
| Direct | Client::from_token("lin_api_...") |
| Env var | export LINEAR_API_TOKEN="lin_api_..." then Client::from_env() |
| File | echo "lin_api_..." > ~/.linear_api_token then Client::from_file() |
| Auto | Client::auto() — tries env var, then file |
Queries
Collection queries use a builder pattern with optional pagination and filtering:
// Paginate with first/last/after/before
let issues = client.issues.first.send.await?;
let page2 = client.issues.first.after.send.await?;
// Search with extra filters
let results = client.search_issues
.first
.team_id
.include_comments
.send
.await?;
| Method | Returns | Description |
|---|---|---|
whoami() |
User |
Authenticated user |
teams() |
Connection<Team> |
List teams |
team(id) |
Team |
Get team by ID |
users() |
Connection<User> |
List users |
projects() |
Connection<Project> |
List projects |
project(id) |
Project |
Get project by ID |
issues() |
Connection<Issue> |
List issues |
issue(id) |
Issue |
Get issue by ID |
search_issues(term) |
Connection<Issue> |
Full-text issue search |
issue_labels() |
Connection<IssueLabel> |
List labels |
cycles() |
Connection<Cycle> |
List cycles |
cycle(id) |
Cycle |
Get cycle by ID |
documents() |
Connection<Document> |
List documents |
document(id) |
Document |
Get document by ID |
issue_relations() |
Connection<IssueRelation> |
List issue relations |
issue_relation(id) |
IssueRelation |
Get issue relation by ID |
workflow_states() |
Connection<WorkflowState> |
List workflow states |
All collection queries support .first(n), .last(n), .after(cursor), .before(cursor), and .include_archived(bool).
Mutations
use IssueCreateInput;
let payload = client.issue_create.await?;
| Method | Description |
|---|---|
issue_create(input) |
Create an issue |
issue_update(input, id) |
Update an issue |
issue_archive(trash, id) |
Archive an issue |
issue_unarchive(id) |
Unarchive a previously archived issue |
issue_delete(permanently, id) |
Delete an issue |
comment_create(input) |
Create a comment |
document_create(input) |
Create a document |
document_update(input, id) |
Update a document |
document_delete(id) |
Delete a document |
issue_relation_create(override_created_at, input) |
Create an issue relation |
file_upload(meta, public, size, type, name) |
Request a signed upload URL |
image_upload_from_url(url) |
Upload image from URL |
File upload and download
The SDK provides high-level helpers for Linear's file operations:
// Upload a file (two-step: get signed URL from Linear, then PUT to GCS)
let bytes = read?;
let result = client.upload_file.await?;
println!;
// Download a file from Linear's CDN
let result = client.download_url.await?;
write?;
Blocking (synchronous) API
For non-async contexts, enable the blocking feature:
[]
= { = "...", = ["blocking"] }
The blocking client mirrors the async API exactly:
use Client;
let client = auto?;
let me = client.whoami?;
println!;
let teams = client.teams.first.send?;
for team in &teams.nodes
// Mutations work the same way
let payload = client.document_create?;
// File operations too
let result = client.upload_file?;
let downloaded = client.download_url?;
Error handling
All methods return Result<T, LinearError>. Error variants:
Authentication— invalid or expired tokenForbidden— insufficient permissionsRateLimited— API rate limit hit (includesretry_after)InvalidInput— bad request parametersGraphQL— errors returned in the GraphQL responseNetwork— connection/transport failuresHttpError— non-200 responses not covered aboveMissingData— expected data path not found in responseAuthConfig— auth configuration error (no token found)Internal— internal error (e.g. runtime creation failure)
Codegen
All types, enums, inputs, and query functions are generated from Linear's official GraphQL schema. The generated code lives in src/generated/ and is checked in for reproducible builds.
License
MIT