Founding keys are opena year free at 6,000 req/hour, for the first 1,000 developersClaim yours

Linear

Point @linear/sdk at https://linear.sandboxapis.dev/graphql via the client's apiUrl option (Linear is GraphQL-only — one endpoint). Both auth forms pass: a bare API key in Authorization, or an OAuth Bearer token.

GraphQL · 17 entitiesMCP-ready

Coverage badge

Deep14/17 · 82%

The share of read rows with a final answer — served and verified, a deviation, retired upstream, or a reviewed empty/refusal. Computed in the coverage manifest, copied here.

Live host
linear.sandboxapis.dev
Pinned hosts
9 — generation 1, 2, 3, 5, 6, 8, 9, 10, 11
Serving since
2026-08-04
Lifecycle
Live

Served & verified

13 / 76%

Answering with real universe data, each response checked against Linear's published spec by the conformance suite on this build.

The full read API

17

Every GraphQL entity Linear publishes, deferred long tail included, minus the rows excluded by policy. Writes are out of scope: this universe is read-only.

Not served yet

4

Each returns an explicit, provider-shaped coverage error naming the gap — never invented data.

01 / The swap

Point your client at a different base URL.

No SDK of ours, no shim, no recorded fixtures. The same client library you already use, one environment variable different.

shell
curl -X POST "https://linear.sandboxapis.dev/graphql" -H 'content-type: application/json' -d '{"query":"{ rateLimitStatus { kind } }"}'

Verified drop-in clients

  • @linear/sdk91.0.0

The versions the conformance suite drives against this host on every build — pinned in coverage/client-pins.yaml, and watched weekly for upstream releases, because a client library moving without us is how a shipped integration breaks silently.

02 / Coverage by family

Every read surface, grouped the way Linear groups it.

All 17 rows the coverage manifest carries for Linear, deferred long tail included and nothing capped. Open a family, or filter by path to find the exact endpoint your client calls.

Status — what a conformance test found

served & verified
answers with real universe data, and this build checked that response against the vendor's spec.
deviation
served and faithful to the real provider, but failing the vendored spec — usually a bug in the spec.
retired
the vendor removed the endpoint; snapshots pinned before that date still serve it.
planned / deferred
not served yet — an explicit coverage error naming the gap, never invented data.
excluded
out of the claim by policy (writes, and surfaces we refuse); not in any denominator on this page.

Mode — what kind of answer a row gets

derive
the response is computed from artifact rows that already exist
generate
canon does not carry this yet; the generator will produce it, then derive
empty
the true answer for this universe is an empty collection — reason + reviewed date required
refuse
mirror the provider's OWN refusal (e.g. its 403 for a non-admin token) — reason + reviewed date required
read-only
a write named in the manifest because clients probe it; the read-only 403 IS its final response, and it never joins the badge denominator

A row with no mode shown has not been judged yet. Modes are the manifest's own words, from coverage/MODES.yaml; every empty and refuse carries a written reason and a review date before it counts as final.

Badge — where Deep starts

Full
every published read row has a final answer
Deep
60% up to 100%
Partial
25% up to 60%
Preview
under 25%

REST + GraphQL + git rows that are not `excluded`. Write operations are NOT rows (DECISIONS 2026-09-01 decision 9): they are counted in meta.write_operations and never enter this ratio.

17 read surfaces in 1 family

graphql13 of 17 served & verified
GQL
attachments

SERVED 2026-09-12: a Linear Attachment is an issue-to-external-URL LINK rather than an uploaded file (the SDL's own `url` description), so the canonical row behind it is canon's `issue.closed_by_pull` edge - the same edge GitHub renders as a pull request's closing reference and GitLab as a merge request's closed issue, now with a fourth rendering and nothing new asserted. NOT canon's `attachment` table, whose only parents are ticket_comment and macro; reading it that way would have made this row a canon widening instead of a rendering. `url` points at gh.sandboxapis.dev, which is exactly what renderer-github prints as the pull's html_url, so the link resolves (invariant #5) - the VCS_ORIGIN precedent renderer-circleci already set. NO generation gate: closed_by_pull is a base-schema column, so an older pin answers FEWER attachments rather than an error. `subtitle` and `bodyData` are null because composing Linear's widget copy would be authoring it

served & verified
Core
GQL
comments
served & verified
Core
GQL
cycles
served & verified
Core
GQL
issue-history
served & verified
Core
GQL
issue-relations

SERVED 2026-09-12 (hello-17): IssueRelation is the Linear rendering of canon's issue_link - the same row GitLab serves at /issues/{iid}/links. Linear names both ends outright (issue and relatedIssue) and keeps ONE word for the relationship, so Issue.relations is the rows an issue is the source of and Issue.inverseRelations the rows it is the target of, and neither needs GitLab's direction-dependent vocabulary. The type is mapped to Linear's own set - canon `relates` is Linear `related`, canon `duplicates` is `duplicate` - and the mapping THROWS on a kind with no Linear spelling rather than guessing; `parent` has no member in IssueRelationType at all and carries no row. IssueRelation.type is String! and not the enum, copied verbatim from the pinned SDL. On an artifact without the domain every relation field answers an explicit generation error in `errors` rather than an empty connection, which would assert that nothing in this universe is linked (invariant #4's GraphQL clause)

served & verified
Core
GQL
issues
served & verified
Core
GQL
labels
served & verified
Core
GQL
orgs
served & verified
Core
GQL
projects
served & verified
Core
GQL
rate-limit
served & verified
Core
GQL
teams
served & verified
Core
GQL
users
served & verified
Core
GQL
workflow-states
served & verified
Core
GQL
initiatives

generate — new canon entity Initiative

deferred
Next
GQL
project-milestones

derive

deferred
Next
GQL
project-updates

generate — new canon entity ProjectUpdate

deferred
Next
GQL
roadmaps

refuse — Linear itself deprecated this surface: packages/conformance/specs/linear/graphql/schema.graphql:39381 marks `roadmap` and :39419 marks `roadmaps` with @deprecated(reason: `Roadmaps are deprecated, use initiatives instead.`), so mirroring it would advertise a surface Linear tells clients to stop calling (the ruled vendor-removed precedent, coverage/reviews/2026-09-01-gitlab-modes.md)

deferred
Long tail

03 / What's simulated

One data set, rendered in Linear's dialect.

Every Linear call resolves against the same simulated data set every other provider serves. Counted from the linear-2026-08-g11 artifact (universe generation 11):

What another provider has to agree with, and the test that makes it

Each line below is one assertion in the conformance suite named beside it — run on every build, over one artifact, through the real renderers. Nothing is claimed here that no expect checks.

05 / Pinned snapshots

Frozen universes, on their own hostnames.

Each pin regenerates byte-identically on every request, so a test written against one never drifts. Generations are DIFFERENT universes, not versions of one — never swap a suffix expecting the same data.

PinHostUniverse generationLinear API versionRepository files
linear-2026-08linear-2026-08.snap.sandboxapis.devgeneration 1unversionednot in this generation
linear-2026-08-g10linear-2026-08-g10.snap.sandboxapis.devgeneration 10unversionedserved
linear-2026-08-g11linear-2026-08-g11.snap.sandboxapis.devgeneration 11unversionedserved
linear-2026-08-g2linear-2026-08-g2.snap.sandboxapis.devgeneration 2unversionedserved
linear-2026-08-g3linear-2026-08-g3.snap.sandboxapis.devgeneration 3unversionedserved
linear-2026-08-g5linear-2026-08-g5.snap.sandboxapis.devgeneration 5unversionedserved
linear-2026-08-g6linear-2026-08-g6.snap.sandboxapis.devgeneration 6unversionedserved
linear-2026-08-g8linear-2026-08-g8.snap.sandboxapis.devgeneration 8unversionedserved
linear-2026-08-g9linear-2026-08-g9.snap.sandboxapis.devgeneration 9unversionedserved

Need an endpoint that is not served yet?

Every row Linear's manifest carries is on this page, so “not here” is an answer rather than a gap in the rendering. Tell us which path and which client, and it moves up the queue — the order is set by what people ask for.

Request coverage