> For the complete documentation index, see [llms.txt](https://docs.mithrl.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mithrl.com/docs/public-kg-api.md).

# Mithrl-1 API (GraphQL)

The public knowledge-graph read API. Read-only by construction — there is no `Mutation` and no `Subscription` — and every `Edge` it returns carries its provenance. This API returns data and evidence only; scoring, ranking, and analysis live in the workflow tier.

The page and batch ceilings quoted in the argument descriptions below are the platform **defaults**. A deployment may configure them lower, and the two kinds of ceiling surface differently: a page request above the effective page ceiling is clamped and succeeds with `truncated: true`, while a batch input above the effective batch ceiling (such as an over-cap `subjects` list) is rejected with the effective limit reported in the `platform.invalid_input` error message — so treat a rejection's stated limit as authoritative over this reference.

For uploads, analysis runs, status monitoring, and artifact downloads, see [Running and managing Inference](/guides/workflow-cli.md).

## Queries

### `node`

Single-node lookup by CURIE. Null if not in the active build.

Returns `Node`.

| Argument | Type  | Default | Description                                             |
| -------- | ----- | ------- | ------------------------------------------------------- |
| `curie`  | `ID!` | —       | Canonical CURIE of the node to fetch, e.g. `HGNC:1100`. |

### `neighbors`

Filtered 1-hop expansion around a node. Cursor-paginated — page with `first` and `after` to walk a hub node's complete neighbourhood, following `cursor` until it comes back null. `totalCount` on the first page reports the node's full matching degree, so you can tell how much is still unfetched.

Returns `EdgeConnection!`.

| Argument           | Type                 | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------ | -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `curie`            | `ID!`                | —       | Canonical CURIE of the node to expand around.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `predicate`        | `Predicate`          | —       | Keep only edges with this relationship. Omit for every predicate.                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `direction`        | `Direction!`         | `BOTH`  | Which side of the edge the neighbour sits on, relative to `curie`. Defaults to both.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `neighborCategory` | `Category`           | —       | Keep only neighbours in this category.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `qualifiers`       | `[QualifierFilter!]` | —       | Match on edge qualifiers, e.g. direction of effect. Distinct filters AND; a filter's own `anyOf` is an OR. Pushed down to the store — unlike `source` below, this does not affect `totalCount`/pagination correctness.                                                                                                                                                                                                                                                                                                                     |
| `source`           | `String`             | —       | Keep only edges contributed by this knowledge source. Matched case-insensitively, so a source's branded spelling (`DoRothEA`, `OpenTargets`) selects the same edges as the form reported in `knowledgeSources`. Applied after retrieval, so a page can come back holding fewer edges than `first` — or none — while later pages still hold matches: follow `cursor` until it is null rather than stopping at the first short page. `totalCount` is not reported when this filter is in use, since the count is taken before it is applied. |
| `first`            | `Int!`               | `50`    | Maximum edges to return. Clamped to 100; asking for more succeeds with `truncated: true` rather than failing.                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `after`            | `String`             | —       | The `cursor` from the previous page. Cursors are keyset-based and stable across calls, so paging a node's neighbourhood cannot drift, skip, or repeat an edge. Omit it for the first page.                                                                                                                                                                                                                                                                                                                                                 |
| `taxon`            | `ID`                 | —       | Keep only neighbours in this organism, as an NCBITaxon CURIE (e.g. `NCBITaxon:9606` for human). A neighbour claiming no organism is kept — chemicals, diseases and pathways claim none — so only one positively claiming a different organism is dropped. Pushed down to the store, so `totalCount` and pagination stay correct (unlike `source` above).                                                                                                                                                                                   |

### `edges`

Bulk 1-hop edges by relationship type, optionally anchored to a bounded list of subject and/or object CURIEs. Cursor-paginated — page with `first` and `after`.

Returns `EdgeConnection!`.

| Argument          | Type                 | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------------- | -------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `predicate`       | `Predicate!`         | —       | The relationship to scan for. Required — this is the field's anchor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `subjectCategory` | `Category`           | —       | Keep only edges whose subject is in this category.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `objectCategory`  | `Category`           | —       | Keep only edges whose object is in this category.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `source`          | `String`             | —       | Keep only edges contributed by this knowledge source. A single source, not a list. Matched case-insensitively, so a source's branded spelling (`DoRothEA`, `OpenTargets`) selects the same edges as the form reported in `knowledgeSources`.                                                                                                                                                                                                                                                                                                                                                                                  |
| `qualifiers`      | `[QualifierFilter!]` | —       | Match on edge qualifiers, e.g. direction of effect — the only structured edge filter. Distinct filters AND; a filter's own `anyOf` is an OR. Pushed down to the store, so it composes correctly with pagination — unlike `source` above, it does not affect `totalCount`, which is always null on `edges` regardless of which filters are applied.                                                                                                                                                                                                                                                                            |
| `qualifier`       | `QualifierFilter`    | —       | Deprecated singular predecessor of `qualifiers`. Still pushed down to the store (treated as `qualifiers: [qualifier]` when `qualifiers` is not also supplied), so it composes correctly with pagination, same as `qualifiers` does. **Deprecated:** Use `qualifiers` instead — it accepts a list, so several filters can AND together. Kept for the overlap window; removed no earlier than the next major version.                                                                                                                                                                                                           |
| `subjects`        | `[ID!]`              | —       | Anchor the scan to edges whose subject is one of these CURIEs — the bulk, paginated replacement for predicate-filtered outgoing scans over them; not a general substitute for `neighbors`, whose `predicate` is optional and whose `direction` defaults to both, since `predicate` is required here and only the edge subject is anchored. Duplicates and blanks are dropped first; the subject cap of 100 applies to what remains, and an over-cap or all-blank list is rejected rather than truncated. Omit the argument entirely for an un-anchored whole-network scan; an empty list is a contract error, not a widening. |
| `objects`         | `[ID!]`              | —       | Anchor the scan to edges whose object is one of these CURIEs — the mirror of `subjects`, and the one that reaches relations the graph stores object-first, such as `gene_associated_with_condition` or CTD's `participates_in`. Same rules as `subjects`: duplicates and blanks are dropped first, the object cap of 100 applies to what remains, and an over-cap or all-blank list is rejected rather than truncated. Supplying this **with** `subjects` narrows to edges running from one of those subjects to one of these objects — an AND, not a union. For edges touching either set, issue two calls.                  |
| `first`           | `Int!`               | `100`   | Maximum edges per page. Clamped to 100; asking for more succeeds with `truncated: true` rather than failing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `after`           | `String`             | —       | The `cursor` from the previous page. Cursors are keyset-based and stable across calls, so a paged scan cannot drift or repeat rows.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

### `resolve`

Batch entity resolution. Map names/CURIEs to canonical Nodes, ranked by match quality.

Returns `[Node!]!`.

| Argument    | Type         | Default | Description                                                                                                                                                                                                                                                                                                                                         |
| ----------- | ------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `names`     | `[String!]!` | —       | Names or CURIEs to resolve. Blank entries are dropped first; the cap of 100 applies to what remains, and an over-cap batch is rejected rather than truncated — so no name you supplied is silently left unconsidered.                                                                                                                               |
| `category`  | `Category`   | —       | Only consider candidates in this category.                                                                                                                                                                                                                                                                                                          |
| `limitEach` | `Int!`       | `5`     | Maximum candidates returned per input name, best match first. Clamped to 10.                                                                                                                                                                                                                                                                        |
| `taxon`     | `ID`         | —       | Restrict to one organism, as an NCBITaxon CURIE (e.g. `NCBITaxon:9606` for human). Nodes that claim no organism are kept — a disease, a chemical or a pathway has none — so only a node positively claiming a DIFFERENT organism is excluded. Applied before `limitEach` cuts each name's list, so a correct human match cannot be lost to the cut. |

### `membership`

Bulk term membership — gene→terms or term→members — for a set of genes or a single term.

Returns `[MembershipSet!]!`.

| Argument         | Type         | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------- | ------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `predicate`      | `Predicate!` | —       | The membership relationship to query. Only pathway membership and `gene_associated_with_condition` (disease association) are backed by an aggregate; any other member of this enum is rejected with `platform.invalid_input`. Pathway membership is named by *either* `participates_in` or `has_participant`, and the two are equivalent here: they are inverses, the graph stores both orientations, and this aggregate always answers over their union. Membership is therefore a claim about the relation, not about which way a given source wrote the triple — a gene is reported as belonging to a pathway whether the stored edge runs gene→pathway or pathway→gene. |
| `genes`          | `[ID!]`      | —       | Entity CURIEs to look up membership *for*, populating `terms` on each result. Duplicates and blanks are dropped first; the cap of 100 applies to what remains, and an over-cap batch is rejected rather than truncated. Supply this or `term`, not both.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `term`           | `ID`         | —       | A single term CURIE to look up the *members of*, populating `members`. Supply this or `genes`, not both.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `memberLimit`    | `Int`        | —       | Maximum members returned per set. Clamped to 100; omitted means that same ceiling. A set with more reports `truncated: true` and its true size in `memberCount` — continue with `memberOffset`, do not re-issue with a larger `memberLimit`.                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `memberOffset`   | `Int!`       | `0`     | Skip this many members of every set, in CURIE order, before returning `memberLimit` of them. Successive offsets partition a set with no overlap and no gaps; `memberOffset` on the result echoes the window that was served. An offset past a set's size returns that set with an empty list and its true `memberCount`, which is how the walk ends.                                                                                                                                                                                                                                                                                                                        |
| `includeSources` | `Boolean!`   | `False` | Ask for per-member attribution: `knowledgeSources` and `memberSources` on each result, instead of null. Off by default because it costs the aggregate its fast path. Pass it whenever the answer will be attributed to anyone — a term's own vocabulary is NOT the source of its membership. Sources republish one another's term identifiers, so a `REACT:` pathway's members can be, and often are, asserted by `ctd` or `ensembl` and never by Reactome.                                                                                                                                                                                                                 |

### `paths`

Connecting paths between two nodes, constrained by a predicate whitelist and a hop bound (<= 5).

Returns `[Path!]!`.

| Argument             | Type           | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------- | -------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source`             | `ID!`          | —       | CURIE to start from. Paths are directed, so source and target matter.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `target`             | `ID!`          | —       | CURIE to reach. Swap with `source` if a query returns nothing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `predicateWhitelist` | `[Predicate!]` | —       | Only traverse these relationships. Strongly recommended: without it, paths are merely connected rather than mechanistically meaningful.                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `maxHops`            | `Int!`         | `2`     | Maximum path length. Must be 5 or fewer; a larger value is rejected. Depth 5 is served only by builds carrying the integer-id artifacts; other builds refuse it with `platform.not_available_on_build`.                                                                                                                                                                                                                                                                                                                                                                                             |
| `first`              | `Int!`         | `100`   | Maximum paths to return. Clamped to 1000 — above the page ceiling, because a path is a whole route and enumeration cost is flat in this limit.                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `includeEvidence`    | `Boolean!`     | `True`  | Attach per-hop provenance (sources, publications, sign qualifiers). Default true. Set false for broad enumeration: a screening result's evidence belongs to the shortlisted paths (read it per hop via explainEdge), and each hop's shown edge is one representative of possibly several parallel assertions. Edges then carry empty provenance lists.                                                                                                                                                                                                                                              |
| `taxon`              | `ID`           | —       | Restrict to one organism, as an NCBITaxon CURIE (e.g. `NCBITaxon:9606` for human). Nodes that claim no organism are kept — a disease, a chemical or a pathway has none — so only a node positively claiming a DIFFERENT organism is excluded. It constrains EVERY node on the route, not just the endpoints, so a route reported for one organism cannot run through another one's node. An endpoint claiming a different organism is rejected.                                                                                                                                                     |
| `includeStructural`  | `Boolean!`     | `False` | When false (the default), path interiors exclude organism-taxon, clinical-trial and study nodes, and hops over `in_taxon` and `chemically_similar_to` are not walked: these connect almost everything to everything and carry no mechanism. Set true to include them. The two endpoints are never excluded, so a taxon or trial named as an endpoint still gets its routes; a direct `in_taxon` edge between the endpoints is still withheld by default, since the predicate rule applies to every hop. A `predicateWhitelist` replaces the predicate rule (it already names every hop you accept). |

### `apiVersion`

The public KG API schema version (semver major.minor).

Returns `String!`.

### `search`

Free-text node search. Use `resolve` instead when you already have a list of names or CURIEs to map to canonical identities. Every result carries `matchType`, saying how it matched — check it before treating a hit as the entity you asked for, since a `SYNONYM` match can return a broader or narrower concept whose preferred name shares no words with the query.

Returns `[Node!]!`.

| Argument   | Type       | Default | Description                                                                                                                                                                                                                                                                                  |
| ---------- | ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`    | `String!`  | —       | Free-text search string. Matched against names and synonyms only — a genomic coordinate such as `chr12:56,700,000` is matched as literal text and returns nothing, because there is no coordinate-to-node lookup in this API. Resolve genes by symbol or CURIE and variants by rsID instead. |
| `category` | `Category` | —       | Restrict results to this category.                                                                                                                                                                                                                                                           |
| `first`    | `Int!`     | `20`    | Maximum nodes to return, best match first. Clamped to 100.                                                                                                                                                                                                                                   |

### `searchNodes`

Free-text node search with an organism filter, reporting what the filter removed. Same matching and same ranking as `search` — use this one whenever you care about species. The filter is applied in the graph store ahead of `first`, so the page holds `first` matches in your organism rather than the remainder of a mixed-species page, and `excludedByOrganism` tells you which species were dropped and how many matches each accounted for. Without `organism` this is `search` plus an envelope, and the exclusion fields are empty.

Returns `NodeSearchResult!`.

| Argument   | Type       | Default | Description                                                                                                                                                                                                                                                                                                                            |
| ---------- | ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`    | `String!`  | —       | Free-text search string. Matched against names and synonyms only — a genomic coordinate such as `chr12:56,700,000` is matched as literal text and returns nothing, because there is no coordinate-to-node lookup in this API. Resolve genes by symbol or CURIE and variants by rsID instead.                                           |
| `category` | `Category` | —       | Restrict results to this category.                                                                                                                                                                                                                                                                                                     |
| `first`    | `Int!`     | `20`    | Maximum nodes to return, best match first. Clamped to 100.                                                                                                                                                                                                                                                                             |
| `organism` | `ID`       | —       | Keep only entities in this organism, as an NCBITaxon CURIE (e.g. `NCBITaxon:9606` for human). An entity claiming no organism is kept — chemicals, diseases and pathways claim none — so only one positively claiming a different organism is dropped. Applied before `first`, and what it dropped is reported in `excludedByOrganism`. |

### `subgraph`

Induced neighbourhood around a seed set: the collected nodes plus every edge between them. `maxHops` must be <= 2 and at most one predicate is supported.

Returns `Subgraph!`.

| Argument     | Type           | Default | Description                                                                                                                                                                                                                                                             |
| ------------ | -------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `seeds`      | `[ID!]!`       | —       | CURIEs to build the neighbourhood around. Duplicates and blanks are dropped first; the cap of 25 applies to what remains, and an over-cap set is rejected rather than truncated. Capped well below other batch limits because every seed is its own traversal frontier. |
| `maxHops`    | `Int!`         | `1`     | How far to expand from each seed. Must be 2 or fewer; a larger value is **rejected** rather than quietly reduced, so you never receive a smaller neighbourhood than you asked for.                                                                                      |
| `predicates` | `[Predicate!]` | —       | Only traverse these relationships. At most one is supported on this field.                                                                                                                                                                                              |
| `nodeLimit`  | `Int!`         | `60`    | Maximum nodes to collect. Clamped to 100, and reported via `truncatedNodes`. Edges are bounded separately — see `truncatedEdges`.                                                                                                                                       |

### `enrichment`

Hypergeometric over-representation of a gene set against pathway, disease or regulator terms. `pValue` is RAW — no multiple-testing correction is applied, because this list is truncated to `first` and an FDR over a truncated, sorted slice would be invalid. Apply correction yourself over the full test set.

Returns `[EnrichmentResult!]!`.

| Argument    | Type         | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------- | ------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `genes`     | `[ID!]!`     | —       | The gene set to test for over-representation. Duplicates and blanks are dropped first (a repeated gene would inflate the hypergeometric overlap); the cap of 100 applies to what remains, and an over-cap set is rejected rather than truncated, since a silently truncated set would change the statistics.                                                                                                                                                                                                                                                                                          |
| `predicate` | `Predicate!` | —       | Which term family to test against. Only pathways, `gene_associated_with_condition` (diseases) and `regulates` (regulators) are backed by an aggregate; any other member of this enum is rejected with `platform.invalid_input`. Pathways are named by *either* `participates_in` or `has_participant` — the two are inverses, the graph stores both orientations, and this aggregate tests against their union. The background set and every term size are computed over that union, so the p-values reflect all participation evidence rather than whichever orientation a source happened to write. |
| `first`     | `Int!`       | `20`    | Maximum terms to return, lowest p-value first. Clamped to 50. Note this truncation is why `pValue` is left uncorrected — see `EnrichmentResult`.                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

### `explainEdge`

The backing evidence for one asserted triple, or null when no such edge exists. Edges are directed: if this returns null, try swapping subject and object.

Returns `Edge`.

| Argument    | Type        | Default | Description                                                                      |
| ----------- | ----------- | ------- | -------------------------------------------------------------------------------- |
| `subject`   | `ID!`       | —       | CURIE of the entity the assertion is made about.                                 |
| `object`    | `ID!`       | —       | CURIE of the entity on the receiving end.                                        |
| `predicate` | `Predicate` | —       | Narrow to one relationship. Omit to match whichever predicate connects the pair. |

### `schemaSummary`

The active build's identity, vocabularies and knowledge-source versions — the provenance a run records to be reproducible.

Returns `SchemaSummary!`.

### `dwpcRanking`

Rank what a source reaches along one named mechanism, degree-calibrated.

Walks a curated metapath — a typed hop sequence — from `source`, scores every target it reaches by degree-weighted path count, and calibrates that score against a permutation null that preserves typed degree. The calibrated number is `z`, and it is the quantity to rank on: the raw `dwpc` correlates +0.567 with target degree (it is largely a popularity measure), while `z` correlates −0.043.

**z ranks; z is not a p-value.** See the caveat on the `z` field itself — the null is right-skewed and the normal-tail reading does not apply.

Supply `target` to score one pair; omit it to rank everything the metapath reaches. Read every score alongside its `support`: the head of a z ranking is dominated by very-low-degree targets, and no minimum-support floor is applied.

Returns `DwpcRanking!`.

| Argument       | Type        | Default | Description                                                                                                                                                                                                                                                                |
| -------------- | ----------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source`       | `ID!`       | —       | CURIE to score from. Must hold the metapath's starting category — a compound for a compound-first metapath — or nothing is reached.                                                                                                                                        |
| `metapath`     | `Metapath!` | —       | Which mechanism to walk, by name. Metapaths are curated rather than author-supplied: each name has a permutation null table provisioned against the serving build, which is what makes `z` available at all.                                                               |
| `target`       | `ID`        | —       | Score this one target instead of ranking all of them. The result is a ranking of one, so `results` still carries the score. A pair reached by no route scores an exact 0.0 — a measurement, not a failure.                                                                 |
| `first`        | `Int!`      | `100`   | How many ranked targets to return. Clamped to 500. Note the ranking is computed over EVERY reached target and then trimmed — a calibrated top-10 is not a re-sort of the raw top-10, which is the whole point of calibrating. `targetCount` reports how many were reached. |
| `includePaths` | `Boolean!`  | `False` | Return the concrete routes behind the score. Single-pair reads only — ignored when `target` is absent, where it would enumerate routes to every target reached.                                                                                                            |
| `pathLimit`    | `Int!`      | `20`    | How many routes to show when `includePaths` is set. Clamped to 200. `support.pathsComplete` says whether the listing is the whole set.                                                                                                                                     |

## Types

### `DwpcCalibration`

The permutation null this request was calibrated against, and its identity. Present on every response; `available: false` when no table applied.

| Field                   | Type                 | Description                                                                                                                                                                                                                                 |
| ----------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `available`             | `Boolean!`           | True when a null table for this metapath was found beside the serving build and consulted. False means every `z` in this response is null and the raw scores are all you have — check `unavailableReason`.                                  |
| `unavailableReason`     | `ZWithheldReason`    | Why no table applied. Null when `available` is true.                                                                                                                                                                                        |
| `unavailableDetail`     | `String`             | The graph's own sentence for the above. Null when `available` is true.                                                                                                                                                                      |
| `buildId`               | `String`             | The graph build the table was measured on. A table that does not describe the build being served is REFUSED outright rather than used, so this always matches the serving build when it is present.                                         |
| `costFunctionId`        | `String`             | Which scoring function the null was measured under, including the evidence-weighting policy. Part of the table's identity: a table measured under a different one is refused, not reused.                                                   |
| `algorithmVersion`      | `Int`                | The permutation algorithm generation the table was measured with.                                                                                                                                                                           |
| `permutations`          | `Int`                | How many permuted graphs the moments were pooled over.                                                                                                                                                                                      |
| `swapMultiplier`        | `Int`                | Edge swaps per edge in each permutation — how thoroughly the graph was shuffled.                                                                                                                                                            |
| `converged`             | `Boolean`            | Whether the permutation sweep's moments had settled when it stopped. False is not an error, but a z from an unconverged table is a coarser instrument — read `convergedMassFraction` before drawing fine distinctions between near-equal z. |
| `convergedMassFraction` | `Float`              | The fraction of scored mass sitting in cells whose moments had settled.                                                                                                                                                                     |
| `minCell`               | `Int`                | The minimum number of pooled pairs a degree cell must hold before it publishes moments. Cells below it withhold rather than publish a noisy z.                                                                                              |
| `targetsWithoutZ`       | `Int`                | How many of the reached targets — across the whole ranking, not just the returned page — could not be calibrated. Null on a single-pair read, where the result's own `zWithheld` says it.                                                   |
| `withheld`              | `[ZWithheldCount!]!` | The breakdown of `targetsWithoutZ` by reason. Empty when every reached target was calibrated.                                                                                                                                               |

### `DwpcPath`

One concrete route behind a single-pair score.

| Field   | Type       | Description                                                                                                          |
| ------- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
| `hops`  | `Int!`     | How many relationships this route crosses — the metapath's length.                                                   |
| `nodes` | `[Node!]!` | Source first, target last.                                                                                           |
| `pdp`   | `Float!`   | This route's own degree-weighted contribution. The `pdp` of every route sums to `dwpc` when `pathsComplete` is true. |

### `DwpcRanking`

A calibrated ranking along one named metapath. With a `target` it holds exactly one result; without one it holds every target the metapath reaches, best first.

| Field          | Type               | Description                                                                                                                                                                                                                                                                                                      |
| -------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source`       | `ID!`              | The entity the metapath was walked from.                                                                                                                                                                                                                                                                         |
| `target`       | `ID`               | The single target scored, or null when this is a ranking over all reached targets.                                                                                                                                                                                                                               |
| `metapath`     | `Metapath!`        | The catalogue name that was walked.                                                                                                                                                                                                                                                                              |
| `metapathHops` | `[MetapathHop!]!`  | What that name expands to, so the number can be checked against its definition.                                                                                                                                                                                                                                  |
| `orderedBy`    | `DwpcOrdering`     | Which quantity `results` is sorted on. `Z` when the ranking was calibrated — note this is reported even when every individual `z` was withheld, because a null WAS consulted. `DWPC` when it was not, in which case the order is degree-confounded. Null on a single-pair read, where there is nothing to order. |
| `results`      | `[DwpcResult!]!`   | Scored targets, best first.                                                                                                                                                                                                                                                                                      |
| `targetCount`  | `Int!`             | How many targets the metapath reaches in total, before `first` trims the page.                                                                                                                                                                                                                                   |
| `truncated`    | `Boolean!`         | True when `targetCount` exceeds what `results` holds.                                                                                                                                                                                                                                                            |
| `exact`        | `Boolean!`         | True when every score is a path count. The one shape that could not be exact is refused rather than approximated, so this is true on every response you receive.                                                                                                                                                 |
| `correction`   | `String!`          | Which argument makes the count exact — how repeated node positions were handled.                                                                                                                                                                                                                                 |
| `damping`      | `Float!`           | The degree-damping exponent the score was computed with. Fixed by the catalogue entry's null table: calibration is only meaningful against a null measured under the same cost function, so this is not a caller's choice.                                                                                       |
| `calibration`  | `DwpcCalibration!` | The null this was measured against.                                                                                                                                                                                                                                                                              |
| `paths`        | `[DwpcPath!]`      | The concrete routes behind a single-pair score. Only populated for a `target` read with `includePaths: true`; null otherwise.                                                                                                                                                                                    |

### `DwpcResult`

One scored endpoint of the metapath. A single-pair read returns exactly one of these; a ranking returns many, best first.

| Field       | Type           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `node`      | `Node!`        | The target entity this score is about.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `dwpc`      | `Float!`       | The RAW degree-weighted path count: every typed route from the source to this target along the metapath, each route discounted by the degree of the nodes it passes through. Exact — a path count, not a sample. It is NOT comparable across targets of different connectivity. Measured rank correlation with target degree is +0.567, so a ranking on this number is substantially a ranking on popularity. That is what `z` exists to remove; prefer `z` wherever it is present, and use this only to compare like with like.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `z`         | `Float`        | The CALIBRATED score: how far this target's `dwpc` sits above what the same metapath produces for an equally-connected pair, measured against a permutation null that preserves typed degree. Rank correlation with target degree is −0.043, against the raw score's +0.567 — this is the one number here that survives the question *is this big for a pair this connected?* **z RANKS. z IS NOT A p-VALUE.** Do not convert it to a probability, a significance level, or a false-discovery rate, and do not read `z = 2` as any particular tail. The null is strongly right-skewed — median per-cell coefficient of variation 1.8, and 27 of 176 cells above 10 — so the normal-tail arithmetic a z-score invites does not apply. Concretely: an observed score of exactly 0.0 sits at a median z of −0.57, where a normal null would require −∞. Use it to order candidates against each other; nothing more. Null when the score could not be calibrated. When it is null, `zWithheld` says why — a null `z` NEVER means zero, and never means a low score. |
| `zWithheld` | `ZWithheld`    | Non-null on exactly the results whose `z` is null. This is how you distinguish "not calibratable here" from "calibrated, and unremarkable".                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `support`   | `DwpcSupport!` | The evidence behind the score. Read it with `z`, not after it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |

### `DwpcSupport`

How much graph stands behind this result's score. Read it alongside `z`, always.

The top of a z ranking is dominated by TINY-DEGREE targets — a disease associated with a single gene, where the source happens to bind that gene, scores z ≈ 20. Those are real excursions under the null and not artifacts, but whether "shares one gene with a rare disease" is *biologically* interesting is a judgement calibration cannot make for you. No minimum-support floor is applied; this is how you apply your own.

| Field           | Type      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `targetDegree`  | `Int`     | The target's TYPED degree at the metapath's final hop — how many ways the target can be reached along that relationship, counted over the whole graph. This is the exact quantity the null is bucketed on, so it is the number the calibration keyed on rather than a general-purpose connectivity count. `1` marks the degree-1 head described above. Null when nothing read a degree — an UNCALIBRATED ranking never does. Null means unknown, never zero: a returned result is reachable by construction. |
| `pathCount`     | `Int`     | How many distinct routes are SHOWN in `paths`, not how many exist. Only populated on a single-pair read with `includePaths: true`; null otherwise. Check `pathsComplete` before reading it as a total.                                                                                                                                                                                                                                                                                                       |
| `pathsComplete` | `Boolean` | True when `paths` is every route, so `pathCount` IS the total. False when the listing was cut at `pathLimit`. Null when paths were not requested.                                                                                                                                                                                                                                                                                                                                                            |

### `Edge`

A directed assertion — `subject predicate object` — with the evidence behind it. Provenance is never optional: every edge carries `knowledgeSources` and `publications`, which may be empty but are never absent. This API returns data and provenance only; it does no scoring, ranking, or analysis.

| Field                | Type         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `subject`            | `ID!`        | CURIE of the entity the assertion is made about.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `object`             | `ID!`        | CURIE of the entity on the receiving end.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `predicate`          | `Predicate`  | The relationship asserted. A predicate outside `Predicate` reads as `related_to`, with the source's own spelling kept in `originalPredicates` — so this is populated on every edge, and the field is nullable only for compatibility.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `qualifiedPredicate` | `Predicate`  | The predicate that applies once this edge's qualifiers are read with it. On an `affects` edge carrying `object_aspect: expression` and `object_direction: increased`, a `qualifiedPredicate` of `causes` makes the full statement *causes increased expression of* — a signed, causal claim. Null means the source asserted no such refinement, and the edge should be read as the unqualified `predicate` alone. Select it whenever direction of effect matters: `predicate` on its own is the deliberately broad rollup that keeps qualified and unqualified edges retrievable by the same query, so two edges reading `affects` can be opposite claims.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `qualifiers`         | `JSON`       | Refinements of the assertion, such as direction of effect. Filter on these with the `qualifier` argument. Read these together with `qualifiedPredicate`, not on their own: the aspect and direction here say *what* changed and *which way*, while `qualifiedPredicate` says whether the source claimed causation. A selection set that omits both cannot distinguish a chemical that increases a gene's expression from one that decreases it — both edges read `affects`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `knowledgeLevel`     | `String`     | How firmly the assertion is held, e.g. `knowledge_assertion` or `prediction`. On a `paths` hop this is the representative row's own value — one of the fields that does NOT aggregate over the hop's parallel rows (`knowledgeLevel`, `properties`, `publicationsInfo`), because a merge of two rows' answers would state something neither row holds. See `parallelAssertions`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `agentType`          | `String`     | What produced the assertion, e.g. `manual_agent` or `automated_agent`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `knowledgeSources`   | `[String!]!` | The knowledge sources contributing this edge. Part of the mandatory provenance envelope. Aligned index-for-index with `knowledgeLevels` and `agentTypes`: `knowledgeLevels[i]`/`agentTypes[i]` is the claim made by `knowledgeSources[i]`. `allKnowledgeLevels` is NOT part of this alignment — it is the unreduced union of every claim ever made on the edge, and can be a different length than this list. On a `paths`/`subgraph` hop this is the **union** across every gold row sharing the hop's triple — see `parallelAssertions` — not one row's, because a hop is a node pair and stands for all of them. `knowledgeLevels` and `agentTypes` are unioned *with* it, as one tuple keyed on the source, so the index alignment above holds on a hop exactly as it does on an edge, and no source is listed twice.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `knowledgeLevels`    | `[String!]!` | Per-source `knowledgeLevel` claim. Aligned index-for-index with `knowledgeSources` (`knowledgeLevels[i]` is the claim made by `knowledgeSources[i]`) — one entry per unique contributing source, not aligned with `allKnowledgeLevels`, which is a separate, unreduced union. On a `paths`/`subgraph` hop this is the **union** across the hop's parallel rows, unioned as one tuple with `knowledgeSources`/`agentTypes` so the alignment survives. Where one source made two different claims across those rows, one of them is the entry here — deterministic per build (the first in gold row order), NOT precedence-ranked the way the edge's own reduction is — and every level is still present in `allKnowledgeLevels`, so nothing is lost. Measured on the `v1-20260830` build, some source's parallel rows disagree on `knowledgeLevel` for 2,454 of 37,145,722 triples (0.0066%).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `agentTypes`         | `[String!]!` | Per-source `agentType` claim. Aligned index-for-index with `knowledgeSources` (`agentTypes[i]` is the claim made by `knowledgeSources[i]`) — one entry per unique contributing source. On a `paths`/`subgraph` hop this is the **union** across the hop's parallel rows, unioned as one tuple with `knowledgeSources`/`knowledgeLevels` so the alignment survives. Where one source made two different claims across those rows, the entry here is the one that came in the same row as that source's `knowledgeLevels` entry — chosen the same deterministic, non-precedence-ranked way, so the pair always reads as one real row (see `knowledgeLevels`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `allKnowledgeLevels` | `[String!]!` | Sorted unique union of every contributing source **row's** `knowledgeLevel` claim ever made on this edge, unreduced. Per row, not per source: that is the distinction the field exists for, since a source contributes exactly one entry to `knowledgeLevels` and it is that source's second and third rows this preserves. NOT aligned with `knowledgeSources`, `knowledgeLevels`, or `agentTypes` — it can be a different length than any of them (a source that both curated and measured the same triple contributes one aligned entry to `knowledgeLevels` but two entries here). Testing whether `allKnowledgeLevels` contains `observation` is the source-agnostic "is this edge measurement-backed by at least one source?" filter — the one `knowledgeLevel`/`knowledgeLevels` alone cannot answer, since either can pick a non-observation value even when an observation also backs the edge. On a `paths`/`subgraph` hop this is the sorted unique union across every gold row sharing the hop's triple (see `parallelAssertions`), so the measurement-backed filter means the same thing on a hop as on an edge.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `originalPredicates` | `[String!]!` | The contributing source's own predicate spellings, before canonicalization — e.g. `["inactivates"]` for an edge stored as `regulates`. Often the only place an unqualified edge's polarity survives. Spellings are published bare, in the same form as `predicate`. On a `paths` hop this is the **union** across the hop's rows (see `parallelAssertions`), and null whenever the hop's sign is withheld — a source's own spelling states the same polarity in prose, so `signAmbiguous` / `signUnverified` withhold this too.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `originalSubjects`   | `[String!]!` | The subject's CURIE as originally asserted by the contributing source(s), before canonicalization. One entry per distinct source-asserted pairing. **Read `originalSubjects[i]` together with `originalObjects[i]` as a pair, never positionally against `subject`/`object`.** The two lists are aligned with each other and with nothing else — `originalSubjects[i]` is not required to be the same endpoint as `subject`. It differs from the canonical `subject` on roughly a quarter of edges, for three distinct reasons this field cannot tell apart on its own: 1. **Cross-vocabulary merge** — the source's native identifier was merged onto a different-prefix canonical node (an HMDB id onto a CHEBI node, a UniProtKB id onto an NCBIGene node). 2. **Order-free predicate** — for a symmetric predicate (the `interactsWith` / `physicallyInteractsWith` / `inComplexWith` family) the canonical endpoints are SORTED into a stable order while these are left in the order the source asserted, so `originalSubjects[i]` routinely corresponds to the canonical `object` with no vocabulary merge involved at all. 3. **Inverted predicate** — where canonicalization inverted the source's predicate, subject and object were swapped and these were deliberately not, so the original subject IS the canonical object. Preserving the source's asserted direction is what this field is for. On a `paths`/`subgraph` hop this is the **union** across every gold row sharing the hop's triple (see `parallelAssertions`), deduplicated as PAIRS so the pairwise alignment survives. A small population of pipeline-minted `exactMatch` edges (the synthetic survivors of an identifier-conflation decision) carry the pipeline's own claim here rather than any source's assertion. |
| `originalObjects`    | `[String!]!` | The object's CURIE as originally asserted by the contributing source(s), before canonicalization. One entry per distinct source-asserted pairing. **Read `originalObjects[i]` together with `originalSubjects[i]` as a pair, never positionally against `subject`/`object`.** It differs from the canonical `object` on roughly a quarter of edges, for the same three distinct reasons listed on `originalSubjects` — a cross-vocabulary merge, an order-free predicate whose canonical endpoints were sorted while these were left in source order, or an inverted predicate that swapped the canonical endpoints and deliberately not these. On a `paths`/`subgraph` hop it is the same pair-deduplicated union across the hop's rows.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `publications`       | `[ID!]!`     | Publication CURIEs backing this edge. Part of the mandatory provenance envelope. On a `paths` hop this is the **union** across every gold row sharing the hop's triple, not the one row's the hop's other detail comes from: a hop asserted by five parallel rows citing four papers lists all four. `parallelAssertions` says how many rows stand behind it, and `evidenceTruncated` whether the union is complete.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `publicationsInfo`   | `JSON`       | Per-publication detail when a source supplies it, keyed by publication CURIE. Results that return many edges apply a cap of 5 publications per edge and shorten long evidence sentences; when anything was left out, a `_truncated` entry alongside the publication CURIEs records how many there really are. That name is reserved: a source key of `_truncated` is moved aside and the entry names where it went. `explainEdge` returns the detail in full for a single edge.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `properties`         | `JSON`       | Source-specific edge attributes with no typed field. Untyped by design — no key is guaranteed, including any notion of score or confidence. Results that return many edges keep every key but bound each value, cutting a long list to a cap of 20 entries and shortening long text; when anything was left out, a `_truncated` entry records which keys were cut and by how much. That name is reserved: a source key of `_truncated` is moved aside and the entry names where it went. `explainEdge` returns the values in full for a single edge.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `signAmbiguous`      | `Boolean`    | True when this edge's sign could not be determined because two rows behind the same `paths` hop assert OPPOSITE directions of effect, so neither could be attached without picking one at random. `qualifiedPredicate`, `originalPredicates` and the direction entry of `qualifiers` are withheld in that case; the rest of `qualifiers` — the aspect, the species, the tissue, the molecular form — stays, because none of it was in dispute. Only a genuine disagreement about the DIRECTION sets this. Rows that differ on anything else (a different aspect, a different source's wording, a spelling of the same polarity, or a row that states no direction at all) agree as far as this field is concerned. Do not read a null `qualifiedPredicate` here as "the source asserted no sign" without first checking this field (and `signUnverified`) — that reading is only safe when neither is true. Null (not `false`) on every edge with nothing ambiguous to report.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `signUnverified`     | `Boolean`    | True when this edge's sign could not be confirmed because the evidence lookup behind a `paths` hop was truncated before every row could be checked -- an unseen row disagreeing with this hop's sign can't be ruled out, even though nothing actually observed conflicts. Distinct from `signAmbiguous`, which means a disagreement was SEEN: this means the check itself was incomplete. The same fields are withheld as for `signAmbiguous` — the direction, not the whole qualifier set. Null (not `false`) on every edge with nothing left unverified.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `parallelAssertions` | `Int`        | How many gold assertions share this `paths` hop's `subject predicate object` — the parallel rows the single hop stands for. `knowledgeSources`, `publications` and `originalPredicates` are the UNION over those rows; `predicate`, the orientation, `knowledgeLevel`, `properties` and `publicationsInfo` are the one representative row's. Exact, never a floor. Read it before treating this hop's evidence as the whole story: `1` means the union IS that row, and a larger number means several independent assertions back the same link. Null on `edges`, `neighbors` and `subgraph`, which resolve a real edge row and so stand for exactly one assertion.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `evidenceTruncated`  | `Boolean`    | True when this `paths` hop had more parallel rows than the evidence read covers, so `knowledgeSources` / `publications` / `originalPredicates` are the union over the rows READ and not over all of them. `parallelAssertions` says how many there really are. Distinct from `signUnverified`, which is about the sign check rather than the union, and which a hop with an observed disagreement does not carry. Null (not `false`) whenever the union is complete.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

### `EdgeConnection`

One page of edges. Both `edges` and `neighbors` are cursor-paginated and return this shape.

Pass the returned `cursor` back as `after` to fetch the next page, and stop when it is null. Cursors are opaque and keyset-based, and because a build is immutable a cursor stays **stable across calls** — a paged walk cannot drift, skip, or repeat rows the way offset paging does. To retrieve a hub node's complete neighbourhood, keep following `cursor` until it comes back null; `totalCount` on the first page tells you how many edges to expect in total.

This is a flat page of edges rather than Relay-style `edges { node }` nesting, so `items` holds the edges directly, and the entities those edges reference are resolved alongside in `nodes` rather than repeated on every edge.

| Field        | Type       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `items`      | `[Edge!]!` | The edges on this page.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `nodes`      | `[Node!]!` | The entities this page's edges reference, fully resolved — one entry per distinct CURIE appearing as a `subject` or `object` in `items`, in first-appearance order. Join on `Node.id`. This is what makes a page of edges readable on its own: every endpoint's label, category, and organism arrive with it, rather than costing a `node` lookup per identifier. Entries are the same shape `node` returns for the same entity, so `name`, `category`, `inTaxon`, `description`, and the rest are populated wherever the build has them. Populated by both `neighbors` and `edges`. An entry is never omitted for a CURIE that appears in `items` — a join over this list can always account for every endpoint. An entity the build cannot resolve is therefore present with its `id` alone and its other fields empty, which means *not resolvable in this build*, not *absent from the entity*. |
| `cursor`     | `String`   | Opaque pointer to the next page. Null when there are no further pages.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `truncated`  | `Boolean!` | True when a cap cut this page short of natural exhaustion — a platform page ceiling, an internal cap, or a post-filter applied to a full page. Do not branch on it to decide whether to keep paging: follow `cursor` whenever it is non-null, and a null `cursor` with `truncated: true` means the result is exhausted and this page is the whole result.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `totalCount` | `Int`      | Total edges matching the query, across every page — not just this one. Sent by `neighbors` on the first page of a walk (it is null on continuation pages, which do not recount) so a caller can tell how much of a node's neighbourhood is still unfetched. Always null on `edges`, where counting an un-anchored scan would cost as much as running it; null means *not counted*, never zero matches.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

### `EnrichmentResult`

One over-represented term from a seed-set enrichment.

**`pValue` is raw and uncorrected** — a right-tailed hypergeometric probability with no multiple-testing correction applied. None is applied here on purpose: correction has to run over the complete set of tested terms, and this list is already sorted and truncated to `first`, so a q-value computed from it would be wrong in a way that looks right. If you need FDR, apply it yourself over an untruncated result set.

| Field            | Type       | Description                                                                                                                                                                                               |
| ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `term`           | `ID!`      | CURIE of the over-represented term.                                                                                                                                                                       |
| `name`           | `String`   | Human-readable label for the term.                                                                                                                                                                        |
| `category`       | `Category` | Category of the term, e.g. `Pathway` or `Disease`.                                                                                                                                                        |
| `pValue`         | `Float!`   | Raw right-tailed hypergeometric p-value. **Uncorrected** — apply multiple-testing correction yourself, over the full untruncated set of tested terms.                                                     |
| `foldEnrichment` | `Float`    | Observed overlap divided by the overlap expected by chance. Null when it is undefined.                                                                                                                    |
| `overlap`        | `Int!`     | How many of your queried entities belong to this term.                                                                                                                                                    |
| `setSize`        | `Int!`     | Total size of the term in the background set — the members of the term that share your queried entities' categories, so it does not depend on *which* entities you queried but does depend on their type. |

### `KnowledgeSourceVersion`

A knowledge source contributing to the active build, with the version of that source the build ingested. Record both to make a run reproducible.

| Field     | Type      | Description                                                                       |
| --------- | --------- | --------------------------------------------------------------------------------- |
| `name`    | `String!` | Name of the knowledge source, e.g. `DoRothEA`.                                    |
| `version` | `String`  | The source's own version string as ingested. Null when the source publishes none. |

### `MemberAttribution`

Which knowledge sources assert one membership. A membership relation is the union of both stored orientations and of every source that wrote one, so a set's members do not all come from the term's own vocabulary — this says, per member, who actually asserted it.

| Field              | Type         | Description                                                                                                                                                                                                                                         |
| ------------------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `member`           | `ID!`        | The member CURIE this attribution is about.                                                                                                                                                                                                         |
| `knowledgeSources` | `[String!]!` | The knowledge sources asserting this membership, as the graph's own source slugs (`reactome`, `ctd`, `ensembl`), sorted. Empty when the backing edges record no knowledge source: the membership is in the graph, but nothing says who asserted it. |

### `MembershipSet`

Set membership for one term, answering either direction: the members belonging to a term, or the terms a queried entity belongs to. Which of `members` and `terms` is populated depends on how you queried.

| Field              | Type                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `term`             | `ID!`                  | The CURIE this set is about — a term when you queried by term, an entity when you queried by genes.                                                                                                                                                                                                                                                                                                                                                |
| `members`          | `[ID!]`                | The entities belonging to `term`. Populated when you queried by `term`; null otherwise.                                                                                                                                                                                                                                                                                                                                                            |
| `terms`            | `[ID!]`                | The terms `term` belongs to. Populated when you queried by `genes`; null otherwise.                                                                                                                                                                                                                                                                                                                                                                |
| `memberCount`      | `Int`                  | The true size of the set, which exceeds the length of the returned list when `truncated` is true. Use it rather than counting the list.                                                                                                                                                                                                                                                                                                            |
| `truncated`        | `Boolean!`             | True when members exist beyond the returned window rather than the window being all of them. Read `memberCount` for the true size, and continue with `memberOffset`.                                                                                                                                                                                                                                                                               |
| `memberOffset`     | `Int!`                 | Where in the set this window starts — the `memberOffset` the answer was produced for. The window is `[memberOffset, memberOffset + len(list))` of the set ordered by CURIE, so successive offsets partition the set with no overlap and no gaps.                                                                                                                                                                                                   |
| `knowledgeSources` | `[String!]`            | Every knowledge source asserting a membership in this set, sorted — the union over `memberSources`. Null when you did not pass `includeSources: true`; null means *not asked for*, never *nothing asserts this*.                                                                                                                                                                                                                                   |
| `memberSources`    | `[MemberAttribution!]` | Per-member attribution, one entry per returned member, in the same order. Null when you did not pass `includeSources: true`. Read this rather than assuming the term's vocabulary is the source of its membership. A pathway CURIE says who *named the pathway*, not who asserted that a gene is in it: several sources republish one another's pathway identifiers, so a `REACT:` pathway routinely has members no Reactome release ever claimed. |

### `MetapathHop`

One hop of the metapath, so a returned score is auditable.

| Field       | Type      | Description                                               |
| ----------- | --------- | --------------------------------------------------------- |
| `predicate` | `String!` | The relationship this hop traverses.                      |
| `direction` | `String!` | `out`, `in`, or `either` — how the hop is traversed.      |
| `category`  | `String`  | The category the hop's far end must hold, if constrained. |

### `Node`

A knowledge-graph entity, resolved to its canonical identity.

| Field              | Type            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`               | `ID!`           | Canonical CURIE for this entity, e.g. `HGNC:1100`. Stable within a build.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `name`             | `String`        | Preferred human-readable label.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `category`         | `Category`      | Primary category. Null only when the entity carries no category at all — a category outside `Category` reads as `NamedThing`, not null.                                                                                                                                                                                                                                                                                                                                                                                             |
| `allCategories`    | `[Category!]!`  | The categories this entity satisfies, in no particular order and without repeats. A category outside `Category` reads as `NamedThing` rather than being dropped silently.                                                                                                                                                                                                                                                                                                                                                           |
| `description`      | `String`        | Free-text definition, when a contributing source supplies one.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `synonyms`         | `[String!]!`    | Alternative names, including source-specific spellings.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `equivalentCuries` | `[ID!]!`        | CURIEs that denote this same entity and were merged into it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `xrefs`            | `[ID!]!`        | Cross-references to other vocabularies. Unlike `equivalentCuries` these are related identifiers, not asserted identity.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `sources`          | `[String!]!`    | Knowledge sources that contributed this entity's own record — its identity, label and attributes. Not the sources of the assertions it participates in; those are on each `Edge.knowledgeSources`.                                                                                                                                                                                                                                                                                                                                  |
| `publications`     | `[ID!]!`        | Publication CURIEs cited by this entity's own record (e.g. the paper a curated concept was defined in). Not the union of citations across its edges; those are on each `Edge.publications`.                                                                                                                                                                                                                                                                                                                                         |
| `inTaxon`          | `ID`            | Species CURIE, e.g. `NCBITaxon:9606` for human.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `properties`       | `JSON`          | Source-specific attributes with no typed field. Untyped by design — no key is guaranteed, so treat every read as optional.                                                                                                                                                                                                                                                                                                                                                                                                          |
| `matchType`        | `NodeMatchType` | How this entity matched the query, on a `search` result. Null on every other field — `resolve`, `lookup`, and the node envelopes attached to edge pages return entities, not matches. Null on a `search` result too if the active build does not report one.                                                                                                                                                                                                                                                                        |
| `matchedSynonyms`  | `[String!]!`    | The alternative names that matched the query, on a `search` result. Populated whenever a synonym matched, independently of `matchType` — a query can match the preferred name and a synonym at once. Empty when nothing matched by synonym, and on every field other than `search`.                                                                                                                                                                                                                                                 |
| `candidateTotal`   | `Int`           | On a `resolve` result, the true number of candidates that matched this node's query name — populated only when it exceeds the number `resolve` actually returned for that name (`limitEach` cut the list short). Null when the returned set was already complete, or on every field other than `resolve`.                                                                                                                                                                                                                           |
| `matchScore`       | `Int`           | How strongly this entity matched, on a `search` or `resolve` result: an opaque rank combining match strength (an exact name beats an exact synonym beats a substring), whether the entity comes from a curated vocabulary or from corpus free text, and whether it is of the requested `category` and organism. Higher is better, and it is meaningful ONLY as a comparison between rows of the same response — not a similarity, and not stable across builds. Null on every other field, and on a build that does not report one. |
| `matchedNames`     | `[String!]!`    | On a `resolve` result, which of the queried `names` this entity was returned for — more than one when several names matched it equally strongly. A name that matched it at a different strength gets its own row, so a row's `matchScore` always describes how the entity matched the names on that row. `resolve` returns one flat ranked list across all names, so this is what maps a result back onto the input it answers. Empty on every field other than `resolve`.                                                          |

### `NodeSearchResult`

A `searchNodes` result: the page of matches, plus what the `organism` filter removed to produce it.

The filter runs in the store, ahead of `first`, so the page holds `first` matches in the organism you asked for rather than whatever survived a mixed-species window. That is the correct order, and it is also why the exclusions are reported here: a page cannot show what is not on it, and a short — or empty — result would otherwise be indistinguishable from an entity the graph does not hold. Check `excludedByOrganism` before reading an empty `results` as a negative finding.

Both exclusion fields are empty when no `organism` was given, and when one was given and removed nothing. A node claiming no organism is never removed — chemicals, diseases and pathways claim none — so it never appears here either.

| Field                | Type                    | Description                                                                                                                                                     |
| -------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `results`            | `[Node!]!`              | The matching entities, best match first.                                                                                                                        |
| `excludedByOrganism` | `[OrganismExclusion!]!` | What the `organism` filter removed, largest first — one entry per organism, over every match rather than the returned page. Empty when nothing was removed.     |
| `excludedCount`      | `Int!`                  | Total matches the `organism` filter removed. The sum of `excludedByOrganism`'s counts, so the two always agree; read it when you only need the headline number. |

### `OrganismExclusion`

One organism a `searchNodes` request's `organism` filter removed, and how many matches it removed. Counted over every match, not just the page — so this reports exclusions that ranked below `first` too.

| Field      | Type   | Description                                                     |
| ---------- | ------ | --------------------------------------------------------------- |
| `organism` | `ID!`  | The organism whose matches were removed, as an NCBITaxon CURIE. |
| `count`    | `Int!` | How many matches this organism accounted for.                   |

### `Path`

One connecting route between two entities: the nodes traversed and the edges joining them. A path asserts connection, not mechanism — read the edges' provenance to judge whether the route is meaningful.

| Field   | Type       | Description                                                  |
| ------- | ---------- | ------------------------------------------------------------ |
| `hops`  | `Int!`     | Number of edges traversed on this route.                     |
| `nodes` | `[Node!]!` | Every node on the route, in order from source to target.     |
| `edges` | `[Edge!]!` | The edges joining those nodes, each with its own provenance. |

### `SchemaSummary`

What the active build actually contains: its pin, its size, the vocabularies in use, and the version of every contributing knowledge source. This is the provenance a run records to be reproducible later.

| Field         | Type                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `buildPin`    | `String!`                    | Identifier of the build that answered — the snapshot the knowledge graph was serving when these counts were read, not the build your organisation is entitled to. Record it alongside results: it is what makes a query reproducible, and what to re-pin if you later see `platform.build_unavailable`. Empty when the serving tier cannot name its build, which is reported rather than guessed.                                                                                                                                                        |
| `nodeCount`   | `Int!`                       | Total nodes in the active build.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `edgeCount`   | `Int!`                       | Total edges in the active build.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `categories`  | `[String!]!`                 | Categories this build actually carries — the real set behind `Category`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `predicates`  | `[String!]!`                 | Predicates this build actually carries — the real set behind `Predicate`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `sources`     | `[KnowledgeSourceVersion!]!` | Every contributing knowledge source and its ingested version.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `maxPathHops` | `Int`                        | The deepest `maxHops` the build serving this request can actually search with `paths`. The schema accepts up to 5, but a depth-5 search needs artifacts not every build carries, so a build may top out at 4 — read this before asking for a deeper search. A request beyond this depth is REFUSED with `platform.not_available_on_build`; it is never quietly re-scoped to a shallower search, so any result you do receive is at the depth you asked for. Null when the serving tier does not report a ceiling, which is reported rather than guessed. |

### `Subgraph`

The induced neighbourhood around a seed set: the nodes collected plus every edge between them. Node and edge truncation are reported separately, because a subgraph can be complete in nodes while missing edges.

| Field            | Type       | Description                                                                                                                                                                                                     |
| ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nodes`          | `[Node!]!` | Every node collected within `maxHops` of a seed.                                                                                                                                                                |
| `edges`          | `[Edge!]!` | Returned edges whose subject and object are both in `nodes`. Not necessarily every such edge — check `truncatedEdges`, which reports the induced-edge scan hitting its row cap even when all nodes are present. |
| `truncated`      | `Boolean!` | True when either nodes or edges were cut short. Check the two specific flags to see which.                                                                                                                      |
| `truncatedNodes` | `Boolean!` | True when the node budget was reached, so reachable nodes are missing.                                                                                                                                          |
| `truncatedEdges` | `Boolean!` | True when edges were cut short. Note this can happen even with all nodes present, leaving the returned nodes under-connected.                                                                                   |
| `nodeCount`      | `Int!`     | Number of nodes returned in `nodes`.                                                                                                                                                                            |
| `edgeCount`      | `Int!`     | Number of edges returned in `edges`.                                                                                                                                                                            |

### `ZWithheld`

Present on exactly the results whose `z` is null while a raw score stands. Its presence is the signal: a result carrying this was NOT calibratable, and its `dwpc` must not be compared against another result's `z`.

| Field    | Type               | Description                                                                                                                                                                                                                                            |
| -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `reason` | `ZWithheldReason!` | A stable code to branch on.                                                                                                                                                                                                                            |
| `detail` | `String!`          | The graph's own sentence explaining the withholding, verbatim. Show this to a human; branch on `reason`. Wording may be revised without notice — a revision that outruns our mapping surfaces as `reason: UNRECOGNIZED` with the new text intact here. |

### `ZWithheldCount`

How many results lost their `z` for one reason.

| Field    | Type               | Description                                                                                                     |
| -------- | ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `reason` | `ZWithheldReason!` | The stable code for this group of withholdings.                                                                 |
| `detail` | `String!`          | The graph's own sentence for that reason, verbatim.                                                             |
| `count`  | `Int!`             | How many reached targets were withheld for this reason, across the whole ranking rather than the returned page. |

## Input types

### `QualifierFilter`

Match edges whose qualifier `name` holds any of the given values — e.g. `{ name: "object_direction", anyOf: ["increased", "decreased"] }` to keep only signed regulation. This is the only structured filter on edges; there is no free-form predicate syntax.

| Field   | Type         | Description                                                                   |
| ------- | ------------ | ----------------------------------------------------------------------------- |
| `name`  | `String!`    | The qualifier key to match, e.g. `object_direction`.                          |
| `anyOf` | `[String!]!` | Values to accept for that key. An edge matches if it carries any one of them. |

## Enums

### `Category`

An entity category, used to narrow results by type. `schemaSummary.categories` reports the categories the active build carries, and this enum covers them. An entity whose category is somehow outside it reads as `NamedThing` — the root category every entity satisfies — rather than erroring or coming back null.

Values: `Gene`, `Protein`, `MicroRNA`, `Disease`, `PhenotypicFeature`, `ChemicalEntity`, `SmallMolecule`, `Drug`, `Pathway`, `BiologicalProcess`, `PathologicalProcess`, `MolecularActivity`, `CellularComponent`, `AnatomicalEntity`, `Agent`, `Behavior`, `BiologicalEntity`, `BiologicalProcessOrActivity`, `Cell`, `CellLine`, `ChemicalMixture`, `ChemicalRole`, `ClinicalFinding`, `ClinicalIntervention`, `ClinicalTrial`, `ComplexMolecularMixture`, `Device`, `DiagnosticAid`, `GeneFamily`, `GrossAnatomicalStructure`, `Haplotype`, `MacromolecularComplex`, `MolecularEntity`, `MolecularMixture`, `NamedThing`, `NoncodingRNAProduct`, `NucleicAcidEntity`, `OrganismTaxon`, `PhysiologicalProcess`, `Polypeptide`, `Procedure`, `Publication`, `RNAProduct`, `SequenceVariant`, `Study`, `Transcript`, `Treatment`

**`PathologicalProcess`**

Aberrant or failed biological processes — e.g. Reactome `FailedReaction` events, which are stored as `PathologicalProcess` rather than `BiologicalProcess`. A regulation edge can therefore land on this category; filter on it as well as `BiologicalProcess` when measuring regulation scope.

**`Haplotype`**

A set of alleles inherited together — in this build, pharmacogenomic star-alleles (e.g. `CYP2C19*17`). Contributed by a source that is not present in every build; consult `schemaSummary.categories` to confirm the active build carries it.

**`SequenceVariant`**

A sequence variant. Identified by dbSNP rsID where one applies unambiguously, otherwise by an allele-specific key. Coverage is not a variant catalogue: variants enter the graph only where they carry a genetic-association or functional-consequence edge, so absence of a variant is not evidence it has no effect. Coordinate and allele detail is carried on `properties`, where `genome_assembly` names the build `chromosome`/`position`/`hgvsId` are expressed in — read it before acting on a coordinate, and do not assume a build when it is absent. Coordinates are single points, not intervals, and cannot be searched or ranged over: there is no coordinate-to-node lookup in this API.

### `Direction`

Which end of an edge a neighbour sits on, relative to the anchor node.

Values: `IN`, `OUT`, `BOTH`

### `DwpcOrdering`

Which quantity a ranking was ordered on.

Values: `Z`, `DWPC`

### `Metapath`

A named, curated metapath — a typed hop sequence naming one mechanism. Selecting by name rather than authoring hops is what keeps the cost envelope bounded and what makes a calibrated `z` the normal case: every member here has a permutation null table provisioned against the serving build.

This catalogue is deliberately small today and will grow as more metapaths have null tables measured for them. Members will be ADDED; existing members keep their names.

Values: `COMPOUND_BINDS_GENE_ASSOCIATED_WITH_DISEASE`

### `NodeMatchType`

How an entity matched a `search` query, strongest first. `search` ranks by this, so an `EXACT_NAME` hit always precedes a `SYNONYM` one. Matching is literal — there is no fuzzy, phonetic, or semantic matching — so an approximate-looking result reached the page through one of these arms, not through a similarity score.

Values: `EXACT_NAME`, `EXACT_CURIE`, `EXACT_SYNONYM`, `EQUIVALENT_CURIE`, `XREF`, `NAME_SUBSTRING`, `SYNONYM`

**`EXACT_NAME`**

The query equals the entity's preferred name, ignoring case.

**`EXACT_CURIE`**

The query equals the entity's canonical CURIE. Case-sensitive, unlike name matching.

**`EXACT_SYNONYM`**

The query equals one of the entity's alternative names in full, ignoring case — the entity IS the thing asked for, under a different spelling (`K562` for the cell line `K-562`). Distinct from `SYNONYM`, where the query merely appears somewhere inside an alternative name.

**`EQUIVALENT_CURIE`**

The query equals one of `equivalentCuries` — a CURIE merged into this entity as the same thing.

**`XREF`**

The query equals one of `xrefs`. A cross-reference is a related identifier, not asserted identity, so this is weaker evidence of sameness than `EQUIVALENT_CURIE`.

**`NAME_SUBSTRING`**

The query appears somewhere inside the entity's preferred name. Not anchored, so it may be a fragment rather than the whole name.

**`SYNONYM`**

The query appears inside one of the entity's alternative names and matched nothing stronger — the weakest arm. `matchedSynonyms` carries the names that matched. Treat the hit as approximate: a synonym can be broader or narrower than the entity you asked for, and the preferred name may share no words with your query.

### `Predicate`

A relationship type. `schemaSummary.predicates` reports the predicates the active build carries, and this enum covers them. Predicates are directed: `subject predicate object`. An edge whose predicate is somehow outside this enum reads as `related_to` — the broadest relationship, never wrong but never specific — rather than coming back null; `originalPredicates` still carries the contributing source's own spelling, so the relation remains recoverable.

Values: `affects`, `regulates`, `interacts_with`, `physically_interacts_with`, `related_to`, `associated_with`, `gene_associated_with_condition`, `participates_in`, `located_in`, `has_participant`, `has_input`, `has_output`, `treats`, `causes`, `contributes_to`, `has_phenotype`, `active_in`, `actively_involved_in`, `affects_sensitivity_to`, `associated_with_likelihood_of`, `associated_with_resistance_to`, `associated_with_sensitivity_to`, `biomarker_for`, `catalyzes`, `chemically_similar_to`, `close_match`, `colocalizes_with`, `composed_primarily_of`, `contraindicated_in`, `derives_from`, `directly_physically_interacts_with`, `disrupts`, `enables`, `exact_match`, `expressed_in`, `gene_product_of`, `genetically_associated_with`, `has_adverse_event`, `has_contributor`, `has_metabolite`, `has_part`, `has_substrate`, `in_complex_with`, `in_taxon`, `is_sequence_variant_of`, `is_substrate_of`, `member_of`, `mentions`, `model_of`, `occurs_in`, `orthologous_to`, `overlaps`, `preventative_for_condition`, `same_as`, `subclass_of`, `target_for`, `transcribed_from`, `translates_to`, `treats_or_applied_or_studied_to_treat`

**`located_in`**

A stored spatial-containment assertion. It is **not** GO-specific, **not** inherently positive, and **not** the whole of GO cellular-component localization. Filtering on it without the three caveats below returns the wrong set.

*Producers.* Forty-seven source relations map onto `located_in`, and only one of them is GOA's `GO:located_in`. The rest are anatomical/spatial (BSPO, NCIT, UBERON, RO, FMA), metabolite location (HMDB), DrugMechDB's location relations, ClinPGX's haplotype-to-gene locus bridge, an EFO site term, a LOINC imaging-focus term, and SemMedDB's two location relations. Constrain the object side: for cellular localization, query from a gene or protein with `direction: OUT` and `neighborCategory: CellularComponent`.

*Provenance.* That object-side constraint filters by shape, not by evidence class. SemMedDB's `LOCATION_OF` / `location_of` are machine-read literature co-occurrence rather than curation, and both remap with `operation: invert`, so their orientation is flipped relative to the asserted statement. A SemMedDB gene → cellular-component edge satisfies both `direction: OUT` and `neighborCategory: CellularComponent` and is indistinguishable from a GOA annotation except through `knowledgeSources`. Select that field and require `infores:go` if you want curated GOA localization specifically.

*Negation.* A `NOT\|`-qualified GAF row is kept rather than dropped and carries the *identical* predicate. The only thing separating "P is located in X" from the curator-asserted "P is **not** located in X" is `qualifiers.negated == true`, and canon's dedup key includes the qualifiers JSON, so both edges coexist on the same `(subject, predicate, object)` triple. Select `qualifiers` and filter on it — a selection set that omits `qualifiers` cannot tell a localization from its refutation.

*Partial coverage.* GOA writes cellular-component annotations under four qualifiers and this is one of them. `GO:part_of` canonicalizes (inverted, so the GO term is the subject) onto `has_part`, `GO:is_active_in` onto `active_in`, and `GO:colocalizes_with` onto `colocalizes_with`. All three are in this enum and can be queried directly, but they are different relations: a `located_in` filter is a strict subset of GOA cellular-component localization, not a synonym for it. Ask for all four if you want the whole aspect.

**`has_participant`**

The inverse of `participates_in`, and a stored predicate in its own right: GOA's `GO:involved_in` is inverted onto `has_participant`, so a GO biological-process term is the subject and the participating gene is the object. Query it with `direction: OUT` from the process CURIE.

**`has_input`**

A process/reaction consumes this participant. Required for Reactome event expansion.

**`has_output`**

A process/reaction produces this participant. Required for Reactome event expansion.

**`active_in`**

A gene product carries out its molecular function **in** this cellular component. GOA's `GO:is_active_in` is the producer, and the object is always a `CellularComponent`.

*Not to be confused with two neighbours.* `located_in` is bare spatial containment — the thing is there — while `active_in` additionally asserts the molecular function is carried out there; GOA writes both, over the same cellular-component aspect, and they are not interchangeable. `actively_involved_in` is *process* participation, not location, and is a different aspect of GOA entirely. If you want the whole cellular-component aspect, ask for `located_in`, `active_in`, `has_part` (inverted, so the GO term is the subject) and `colocalizes_with` together.

*Negation.* As with `located_in`, a `NOT\|`-qualified GAF row is kept and carries the identical predicate, separated only by `qualifiers.negated == true`. Select `qualifiers` if the distinction matters.

**`composed_primarily_of`**

More than half of the subject's mass is made of parts of the object. In this build it carries a cell line's cell type: `CellLine -> composed_primarily_of -> Cell`, meaning the line consists of cells of that type. It is a composition claim, deliberately not `derives_from`: it asserts what the line is made of, not a developmental or derivational lineage.

**`contraindicated_in`**

A drug is contraindicated in a condition. **This is deliberately partial: it is not the whole of the graph's contraindication evidence.** MED-RT, the producer, splits its contraindications across two predicates depending on what the object is. Contraindications against a disease (`CI_with`) or a physiological process (`CI_PE`) land here and are selectable by predicate alone. Contraindications against a mechanism-of-action class (`CI_MoA`) or another drug (`effect_may_be_inhibited_by`) instead land on `related_to` carrying the qualifier `association_polarity: negative`, because `contraindicated_in`'s range is `biological entity`, which neither a chemical role nor a drug satisfies, and the predicate vocabulary has no drug-drug-interaction predicate at all. All contraindications is therefore this predicate UNION (`related_to` + `association_polarity: negative`), and an absent `contraindicated_in` edge does not mean no contraindication is recorded.

**`genetically_associated_with`**

Associates a variant with a trait or a gene. **Read the `association_type` qualifier before interpreting this edge — it carries two different kinds of claim.** `gwas` is a statistical association between a variant and a trait, drawn from fine-mapped credible sets, with posterior inclusion probability, effect size and p-value on `properties`. `l2g` is a *computational prediction* of which gene a variant acts through, scored by a model, and carries `knowledgeLevel: prediction` — it is a hypothesis about mechanism, not a curated or experimentally established fact. Treating an `l2g` edge as an assertion attributes a gene-level inference to a specific variant. Neither kind is chromatin-contact evidence: no edge in this graph is backed by Hi-C, ChIA-PET, Capture-C or a perturbation assay, and the graph contains no enhancer, promoter or other regulatory-region entities to anchor one to. A variant-to-gene link here therefore never establishes that the variant lies in an element physically contacting that gene.

**`has_adverse_event`**

A drug or chemical intervention was reported with this adverse event in clinical-trial results: `ChemicalEntity -> has_adverse_event -> ClinicalFinding`. **This is trial-reported co-occurrence, not an established causal or curated pharmacovigilance claim** — the edge is assembled from arm-level results reporting, pooled across every contributing trial, and carries `knowledgeLevel: statistical_association` accordingly. The `adverse_event_level` qualifier separates serious from other events, and `properties` carries the pooled counts (subjects affected / at risk) and the contributing trial ids. Absence of an edge means the trials in this build did not report the event, not that the drug lacks it.

**`has_substrate`**

The stored direction of the substrate/enzyme pair: enzyme -> has\_substrate -> metabolite; query from the enzyme with `direction: OUT`. No source currently populates it. HMDB's enzyme associations used to land here, but HMDB's `protein_type` records what kind of protein an association points at, not whether it metabolizes the metabolite, so those edges now carry `associated_with` with a `protein_role` property. The value stays published so a future drug-metabolism source can fill it.

**`is_sequence_variant_of`**

Links a variant to a gene it has a predicted functional consequence for. Restricted to consequences of high or moderate predicted impact, and collapsed to one edge per gene — so this is not a complete record of a variant's transcript consequences, and the absence of an edge does not mean the variant is silent. The specific consequence term and amino-acid change, where known, are on the edge's `properties`.

**`model_of`**

A cell line's disease of origin: `CellLine -> model_of -> Disease` means the line was established from a donor who had that disease, **not** that the line is a validated model of it. Every such edge says so explicitly via the `model_basis: disease_of_origin` qualifier — read it before treating the edge as model status. Lines the source flags as contaminated, misidentified, or otherwise problematic additionally carry a `subject_problematic_cell_line` qualifier; filter on it to exclude them.

### `ZWithheldReason`

Why a calibrated `z` is unavailable for a result that still has a raw score. Read this before treating a missing `z` as a low one: every value here means *not calibratable*, and none of them means *scored badly*.

Values: `NO_NULL_TABLE`, `EDGELESS_ENDPOINT`, `NO_CELL`, `CELL_INSUFFICIENT`, `CELL_DEGENERATE`, `NOT_THE_NULLS_STATISTIC`, `ENUMERATED_NOT_PROPAGATED`, `UNRECOGNIZED`

## Scalars

### `JSON`

The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).

## Error contract

Every GraphQL error carries `extensions.code` from the `platform.*` namespace, plus `extensions.requestId` for support, and `extensions.httpStatus`. The REST surface uses the same codes as RFC 9457 problem details, and carries the same identifier as `request_id`.

Every response also returns that identifier as the `X-Request-Id` header, including successful ones. Quote it when reporting a problem: it identifies the exact request.

| Code                                         | HTTP | What it means                                                                                                                                                                                                                                                                         |
| -------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform.build_forbidden`                   | 403  | Your organisation has no grant for the requested build.                                                                                                                                                                                                                               |
| `platform.build_unavailable`                 | 409  | The pinned build has been garbage-collected and can no longer be served. Re-pin to a current build and reissue the request.                                                                                                                                                           |
| `platform.forbidden`                         | 403  | The credential is valid but its role does not permit this operation.                                                                                                                                                                                                                  |
| `platform.invalid_input`                     | 400  | The request carried a malformed CURIE, an out-of-range argument, or a query rejected as unsafe. Fix the request; retrying it unchanged will fail again.                                                                                                                               |
| `platform.invalid_run_grant`                 | 401  | First-party integrations only: the run grant presented was rejected — malformed, not valid for this run, or expired. Not resolved by retrying; only a newly submitted run receives a fresh grant.                                                                                     |
| `platform.not_available_on_build`            | 409  | The field is valid in the schema but unsupported by the backend serving the active build. `schemaSummary` reports what the active build supports.                                                                                                                                     |
| `platform.not_found`                         | 404  | The requested node is not present in the active build. It may exist in a different build, or the identifier may not resolve — try `resolve` to map a name to a canonical CURIE.                                                                                                       |
| `platform.persisted_query_hash_mismatch`     | 400  | The request carried both a document and a hash, and the hash is not the sha256 of that document. An integrity failure — send the correct hash, or omit it.                                                                                                                            |
| `platform.persisted_query_not_found`         | 400  | First-party integrations only: the referenced operation hash is not in the registered set. Unlike vanilla APQ there is no resend-the-document fallback, because the document must also be allow-listed. API-key callers do not receive this.                                          |
| `platform.persisted_query_not_supported`     | 400  | Hash-only requests are not supported for your credential — resend the request with the full document. You are permitted to run the operation; only the hash-only shorthand is unavailable. Mirrors APQ's `PersistedQueryNotSupported`, so an APQ-aware client degrades automatically. |
| `platform.persisted_query_required`          | 403  | First-party integrations only: an unregistered ad-hoc document was sent where an allow-listed operation is required. API-key callers are not allow-list-gated and do not receive this.                                                                                                |
| `platform.persisted_query_store_unavailable` | 503  | First-party integrations only: the allow-list store was unreachable, so a genuine miss could not be distinguished from an outage. Retryable. API-key callers never consult the store and do not receive this.                                                                         |
| `platform.query_too_costly`                  | 400  | The query exceeded the cost or depth budget before execution. Narrow the selection, reduce `maxHops`, or paginate with a smaller `first`.                                                                                                                                             |
| `platform.quota_exceeded`                    | 429  | Your organisation's cost budget for the current period is exhausted. Not resolved by retrying. Distinct from `platform.rate_limited`, which is the request-rate cap.                                                                                                                  |
| `platform.rate_limited`                      | 429  | Your organisation's request-rate cap was exceeded. Retryable — honour `Retry-After` and the `X-RateLimit-*` headers. Distinct from `platform.quota_exceeded`, which is the cost budget.                                                                                               |
| `platform.run_budget_unavailable`            | 503  | First-party integrations only: the run grant verified, but its run-scoped budget could not be recorded durably, so the request was refused rather than run uncharged. Retryable once the dependency recovers.                                                                         |
| `platform.run_grant_required`                | 401  | First-party integrations only: a delegated request arrived carrying no run grant. Not resolved by retrying — a grant is issued when the run is submitted, so the same run cannot acquire one later.                                                                                   |
| `platform.run_state_unavailable`             | 503  | First-party integrations only: the run grant verified, but the run could not be confirmed as still active. Retryable once the dependency recovers.                                                                                                                                    |
| `platform.unauthenticated`                   | 401  | No credential was supplied, or it was malformed or expired. Obtain a fresh credential and retry.                                                                                                                                                                                      |
| `platform.upstream_busy`                     | 503  | The knowledge-graph service rate-limited this request. Retryable — back off and retry.                                                                                                                                                                                                |
| `platform.upstream_timeout`                  | 504  | The knowledge-graph service hit its hard timeout. Retryable, but a query that times out repeatedly is usually too broad — narrow it or paginate.                                                                                                                                      |
| `platform.upstream_unavailable`              | 503  | The knowledge-graph service or its store is unavailable. Retryable — honour `Retry-After` when present.                                                                                                                                                                               |
