Documentation 29
Linear quickstart · 3 min read
Keep @linear/sdk. Change one line.
The same simulated data set as every other host — as a Linear workspace. GraphQL-only, like the real thing: cycles, projects, workflow histories, and issue branchNames that name real branches on the live git hosts.
Coverage, hosts and pinned snapshots for Linear — 13 of 17 read surfaces served and verified.
01 / Base URL
One endpoint, the real schema subset.
Point your client at https://linear.sandboxapis.dev/graphql. Linear has no REST dialect — one GraphQL endpoint, and the served schema subset IS the coverage surface: introspection reflects exactly what's covered, and anything outside it returns an explicit coverage error in errors[], never a silent null.
curl -X POST "https://linear.sandboxapis.dev/graphql" \
-H 'content-type: application/json' \
-d '{"query":"{ issues(filter: { updatedAt: { gt: \"-P2W\" } }, first: 5) { nodes { identifier title state { name } } } }"}'02 / Drop in your client
@linear/sdk works unmodified.
The only change is the apiUrl — pointed here at the pinned *.snap. host, so the values below are the values you get. The live host re-rolls daily; the pin never moves.
import { LinearClient } from "@linear/sdk";
const client = new LinearClient({
apiKey: "any-token",
apiUrl: "https://linear-2026-08.snap.sandboxapis.dev/graphql",
});
const me = await client.viewer; // full User fragment resolves
const issues = await client.issues({
filter: { updatedAt: { gt: "-P2W" } }, // delta-polling, deterministic
});
const issue = await client.issue("ARGO-59"); // state: Done
console.log(issue.branchName); // "add-per-tenant-backpressure" —
// head branch of the PR that resolved itThere is a client-free version of the same thing — ten lines of fetch, no dependency — proved end to end against the live host https://linear.sandboxapis.dev by a script that checks its output. Verified quickstarts →
03 / A real response
Live from the universe.
{
"data": {
"issues": {
"nodes": [
{
"identifier": "ORCL-2",
"title": "Question: how should the onboarding flow behave when the upstream times out?",
"branchName": "orcl-2-question-how-should-the-onboarding-flow",
"state": {
"name": "In Progress",
"type": "started"
},
"assignee": {
"displayName": "sisyphus"
}
},
{
"identifier": "ORCL-23",
"title": "Config precedence ignores the env var",
"branchName": "clio/types-node",
"state": {
"name": "Done",
"type": "completed"
},
"assignee": null
}
]
}
}
}04 / Pin a snapshot
Deterministic CI.
That *.snap. apiUrl is the whole of it — byte-identical on every request. Relative durations (updatedAt: { gt: "-P2W" }) resolve against the snapshot's anchor, so polling loops are reproducible too.
# reproducible in CI
export LINEAR_API_URL=https://linear-2026-08.snap.sandboxapis.dev/graphqlTour the universe → · Coverage manifest → · Versioning & pinning →