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 above
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