# Introduction

## Lattice

Two ways to query the knowledge graph, documented here.

[**Public KG API**](/reference/public-kg-api) — a GraphQL read API. Read-only by construction: there is no `Mutation` and no `Subscription`, and every result carries its provenance. It returns data and evidence only; scoring, ranking, and analysis live in the workflow tier.

[**CLI**](/reference/cli) — `Lattice`, a command-line client over the same surface. Every command prints a machine-readable JSON payload, and every payload carries a `result_id` you can pass to a later command to compose without recomputing.

## Eos

[**Eos**](/eos/quickstart) — the analysis platform: NGS and multi-omics analysis, visualization, and hypothesis generation driven by natural-language questions. See [Supported Features](/eos/supported-features) for what the platform does today, or [Release Notes](/eos/release-notes) for what shipped recently.


# Public KG API

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.

## 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. Returns a single page — `cursor` is always null and `after` is rejected, so use `edges` when you need to page through a large result.

Returns `EdgeConnection!`.

| Argument           | Type               | Default | Description                                                                                                                                                               |
| ------------------ | ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `curie`            | `ID!`              | —       | Canonical CURIE of the node to expand around.                                                                                                                             |
| `predicate`        | `BiolinkPredicate` | —       | 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` | `BiolinkCategory`  | —       | Keep only neighbours in this Biolink category.                                                                                                                            |
| `source`           | `String`           | —       | Keep only edges contributed by this knowledge source. Applied after retrieval, so a filtered page that was already at its size limit is reported as `truncated`.          |
| `first`            | `Int!`             | `50`    | Maximum edges to return. Clamped to 100; asking for more succeeds with `truncated: true` rather than failing.                                                             |
| `after`            | `String`           | —       | **Not supported on this field** — `neighbors` returns a single page and always reports a null `cursor`, so any value here is rejected. Use `edges` when you need to page. |

### `edges`

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

Returns `EdgeConnection!`.

| Argument          | Type                | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------------- | ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `predicate`       | `BiolinkPredicate!` | —       | The relationship to scan for. Required — this is the field's anchor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `subjectCategory` | `BiolinkCategory`   | —       | Keep only edges whose subject is in this Biolink category.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `objectCategory`  | `BiolinkCategory`   | —       | Keep only edges whose object is in this Biolink category.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `source`          | `String`            | —       | Keep only edges contributed by this knowledge source. A single source, not a list.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `qualifier`       | `QualifierFilter`   | —       | Match on an edge qualifier, e.g. direction of effect. The only structured edge filter.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `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. |
| `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`  | `BiolinkCategory` | —       | Only consider candidates in this Biolink category.                                                                                                                                                                    |
| `limitEach` | `Int!`            | `5`     | Maximum candidates returned per input name, best match first. Clamped to 10.                                                                                                                                          |

### `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` | `BiolinkPredicate!` | —       | The membership relationship to query. Only `participates_in` (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`.        |
| `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.                                                                                                                                                 |

### `paths`

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

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` | `[BiolinkPredicate!]` | —       | Only traverse these relationships. Strongly recommended: without it, paths are merely connected rather than mechanistically meaningful. |
| `maxHops`            | `Int!`                | `3`     | Maximum path length. Must be 4 or fewer; a larger value is rejected.                                                                    |
| `first`              | `Int!`                | `10`    | Maximum paths to return. Clamped to 50 — lower than other fields, because paths are expensive.                                          |

### `apiVersion`

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

Returns `String!`.

### `deprecatedApiVersion`

Deprecated alias of `apiVersion` (deprecation-policy demonstration).

**Deprecated:** Renamed to `apiVersion`; kept for the v1 overlap window. Demonstrates the @deprecated policy — remove no earlier than the next major.

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.

Returns `[Node!]!`.

| Argument   | Type              | Default | Description                                                  |
| ---------- | ----------------- | ------- | ------------------------------------------------------------ |
| `query`    | `String!`         | —       | Free-text search string. Matched against names and synonyms. |
| `category` | `BiolinkCategory` | —       | Restrict results to this Biolink category.                   |
| `first`    | `Int!`            | `20`    | Maximum nodes to return, best match first. Clamped to 100.   |

### `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` | `[BiolinkPredicate!]` | —       | 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` | `BiolinkPredicate!` | —       | Which term family to test against. Only `participates_in` (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`.                                                          |
| `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` | `BiolinkPredicate` | —       | 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!`.

## Types

### `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`          | `BiolinkPredicate` | The relationship asserted. Null when the stored predicate is absent from `BiolinkPredicate`.                                                                                                         |
| `qualifiers`         | `JSON`             | Refinements of the assertion, such as direction of effect. Filter on these with the `qualifier` argument.                                                                                            |
| `knowledgeLevel`     | `String`           | How firmly the assertion is held, e.g. `knowledge_assertion` or `prediction`.                                                                                                                        |
| `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.                                                                                                             |
| `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. |
| `publications`       | `[ID!]!`           | Publication CURIEs backing this edge. Part of the mandatory provenance envelope.                                                                                                                     |
| `publicationsInfo`   | `JSON`             | Per-publication detail when a source supplies it, keyed by publication CURIE.                                                                                                                        |
| `properties`         | `JSON`             | Source-specific edge attributes with no typed field. Untyped by design — no key is guaranteed, including any notion of score or confidence.                                                          |

### `EdgeConnection`

One page of edges. Cursor pagination is supported on `edges`; `neighbors` returns this same shape but as a single page, always with a null `cursor`, and rejects `after`.

On `edges`, 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 scan cannot drift or repeat rows the way offset paging does.

This is a flat page of edges rather than Relay-style `edges { node }` nesting, so `items` holds the edges directly.

| Field       | Type       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `items`     | `[Edge!]!` | The edges on this page.                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `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: on `edges`, follow `cursor` whenever it is non-null, and a null `cursor` with `truncated: true` means the scan is exhausted and this page is the whole result. `neighbors` never returns a cursor, so there the elided rows are reachable only by narrowing the query. |

### `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`       | `BiolinkCategory` | Biolink 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, independent of your query.                                                                              |

### `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. |

### `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 the returned list is a prefix of the real set rather than all of it. Read `memberCount` for the true size.                    |

### `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`         | `BiolinkCategory`     | Primary Biolink category. Null when the stored category is absent from `BiolinkCategory`.                                   |
| `allCategories`    | `[BiolinkCategory!]!` | The Biolink categories this entity satisfies, in no particular order. Categories absent from `BiolinkCategory` are omitted. |
| `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.     |
| `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.  |

### `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 active build. Record it alongside results — it is what makes a query reproducible, and what to re-pin if you later see `platform.build_unavailable`. |
| `nodeCount`  | `Int!`                       | Total nodes in the active build.                                                                                                                                       |
| `edgeCount`  | `Int!`                       | Total edges in the active build.                                                                                                                                       |
| `categories` | `[String!]!`                 | Biolink categories this build actually carries — the real set behind `BiolinkCategory`.                                                                                |
| `predicates` | `[String!]!`                 | Biolink predicates this build actually carries — the real set behind `BiolinkPredicate`.                                                                               |
| `sources`    | `[KnowledgeSourceVersion!]!` | Every contributing knowledge source and its ingested version.                                                                                                          |

### `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`.                                                                                                                                                                            |

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

### `BiolinkCategory`

A Biolink entity category, used to narrow results by type. `schemaSummary.categories` reports the categories the active build carries. An entity whose category is absent from this enum reads as `category: null` rather than erroring.

Values: `Gene`, `Protein`, `MicroRNA`, `Disease`, `PhenotypicFeature`, `ChemicalEntity`, `SmallMolecule`, `Drug`, `Pathway`, `BiologicalProcess`, `PathologicalProcess`, `MolecularActivity`, `CellularComponent`, `AnatomicalEntity`

**`PathologicalProcess`**

Aberrant or failed biological processes — e.g. Reactome `FailedReaction` events, which the KG tier canonicalizes onto `biolink:PathologicalProcess` rather than `biolink:BiologicalProcess`. A regulation edge can therefore land on this category, and a consumer measuring regulation scope must be able to filter for it rather than lose the value at enum validation.

### `BiolinkPredicate`

A Biolink relationship type. `schemaSummary.predicates` reports the predicates the active build carries. Predicates are directed: `subject predicate object`.

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`

**`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.* 45 active `predicate-remap.yaml` entries canonicalize onto `biolink:located_in` — a `grep` finds 47 lines, two of which (`GOREL:0001004`, `WIKIDATA_PROPERTY:P276`) are commented out. Exactly one of the 45 is GOA's `GO:located_in`. The rest are anatomical/spatial (BSPO 15, NCIT 13, UBERON 3, RO 3, FMA 2), metabolite location (HMDB 3), 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 `biolink:has_part`, `GO:is_active_in` onto `biolink:actively_involved_in`, and `GO:colocalizes_with` onto `biolink:colocalizes_with`. None of those three are in this enum yet, so they can be neither filtered for nor recognized in a response — they come back as `predicate: null`. A `located_in` filter is a strict subset of GOA cellular-component localization, not a synonym for it.

**`has_participant`**

The inverse of `participates_in`, and a stored predicate in its own right: the KG tier canonicalizes `GO:involved_in` by inverting it onto `biolink: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.

### `Direction`

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

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

## 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.

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


# CLI

Every command prints a machine-readable JSON payload on stdout and a one-line trace of what it mapped to on stderr. Every payload carries a `result_id` you can pass to `Lattice results`, `Lattice filter`, and `Lattice export` to compose without recomputing.

Exit codes: `0` success, `1` error (a structured `{"error": {...}}` on stderr), `2` bad usage.

## Introspection

Emit the machine-readable spec the other CLI surfaces are generated from.

### `Lattice spec`

Emit the machine-readable Lattice command/flag spec — the single source of truth --help, the /Lattice skill, and the MCP wrapper are generated from.

**Examples**

```bash
Lattice spec
```

## Auth & local infra

Sign in, manage API keys, and install the agent-facing tooling.

### `Lattice login`

Browser-based sign-in (interactive; human-only).

**Examples**

```bash
Lattice login
```

### `Lattice logout`

Clear locally stored credentials.

**Examples**

```bash
Lattice logout
```

### `Lattice keys add`

Register an API key locally from `keys create`'s own JSON output (piped via stdin).

**Constraints**

* Reads a JSON object from stdin -- pipe `Lattice keys create`'s own output straight in.

**Examples**

```bash
Lattice keys create --name ci-agent | Lattice keys add
```

### `Lattice keys use`

Activate a locally-registered API key (from `keys add`) instead of an interactive login session.

**Constraints**

* Exactly one of -p/--prefix or -n/--name is required.

**Options**

| Option           | Type | Required | Default | Description                                                                          |
| ---------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------ |
| `-p`, `--prefix` | str  | no       | —       | The key's prefix (from `keys add`/`keys list`, e.g. ltk\_live\_ab12cd34ef56).        |
| `-n`, `--name`   | str  | no       | —       | The key's name (from `keys create --name`), if it uniquely identifies one added key. |

**Examples**

```bash
Lattice keys use -p ltk_live_ab12cd34ef56
Lattice keys use -n ci-agent
```

### `Lattice keys create`

Create a scoped, read-only API key for headless/agent use.

**Options**

| Option   | Type | Required | Default | Description            |
| -------- | ---- | -------- | ------- | ---------------------- |
| `--name` | str  | no       | —       | Label for the new key. |

**Examples**

```bash
Lattice keys create --name ci-agent
```

### `Lattice keys list`

List existing API keys.

**Examples**

```bash
Lattice keys list
```

### `Lattice keys revoke`

Revoke an API key.

**Arguments**

| Argument | Type | Required | Description                                                                          |
| -------- | ---- | -------- | ------------------------------------------------------------------------------------ |
| `key_id` | str  | yes      | The key's prefix (from `keys list`, e.g. ltk\_live\_ab12cd34ef56) or its numeric id. |

**Examples**

```bash
Lattice keys revoke ltk_live_ab12cd34ef56
```

### `Lattice keys rotate`

Rotate an API key.

**Arguments**

| Argument | Type | Required | Description                                                                          |
| -------- | ---- | -------- | ------------------------------------------------------------------------------------ |
| `key_id` | str  | yes      | The key's prefix (from `keys list`, e.g. ltk\_live\_ab12cd34ef56) or its numeric id. |

**Examples**

```bash
Lattice keys rotate ltk_live_ab12cd34ef56
```

### `Lattice api set`

Configure the platform admin API's base URL (persisted locally).

**Constraints**

* Optional: the CLI has a built-in default deployment. Run this only to point it at a different one, such as a self-hosted deployment.

**Arguments**

| Argument | Type | Required | Description                                                              |
| -------- | ---- | -------- | ------------------------------------------------------------------------ |
| `url`    | str  | yes      | Base URL of the platform admin API, e.g. <https://platform.example.com>. |

**Examples**

```bash
Lattice api set https://platform.example.com
```

### `Lattice api use`

Point Lattice at a named deployment (dev, staging, production) in one step.

**Arguments**

| Argument | Type | Required | Description                                    |
| -------- | ---- | -------- | ---------------------------------------------- |
| `name`   | str  | yes      | Deployment alias: dev, staging, or production. |

**Examples**

```bash
Lattice api use staging
```

### `Lattice api show`

Show the platform admin API base URL in effect, and whether it came from local configuration or the built-in default.

**Examples**

```bash
Lattice api show
```

### `Lattice api clear`

Remove the locally configured API base URL, reverting to the built-in default.

**Examples**

```bash
Lattice api clear
```

### `Lattice skill install`

Register the /Lattice skill for coding agents.

**Examples**

```bash
Lattice skill install
```

### `Lattice mcp`

Run the thin (single-tool) MCP wrapper, local-only by default.

**Examples**

```bash
Lattice mcp
```

### `Lattice update`

Signature-verified self-update (binary + snapshot).

**Constraints**

* \--check, --rollback, and --reset-ratchet are mutually exclusive.
* Applying an update requires a packaged install; elsewhere the command reports the available version and points at your package manager instead.
* Applying an update and --rollback are not supported on Windows yet, because a running executable cannot replace itself there.
* \--check works on every platform and install type.

**Options**

| Option            | Type | Required | Default | Description                                                                   |
| ----------------- | ---- | -------- | ------- | ----------------------------------------------------------------------------- |
| `--check`         | bool | no       | `False` | Check for an available update without applying it.                            |
| `--rollback`      | bool | no       | `False` | Restore the previously installed version.                                     |
| `--reset-ratchet` | bool | no       | `False` | Clear the locally-stored last-verified-update-version downgrade/freeze check. |

**Examples**

```bash
Lattice update
Lattice update --check
Lattice update --rollback
```

## KG primitives

Query the knowledge graph directly: resolve names, read nodes, walk edges, find paths.

### `Lattice search`

Resolve a name/exact/regex/substring query to typed nodes.

**Arguments**

| Argument | Type | Required | Description                                  |
| -------- | ---- | -------- | -------------------------------------------- |
| `query`  | str  | yes      | Name, exact/regex/substring query, or CURIE. |

**Options**

| Option          | Type | Required | Default | Description                                                                                                |
| --------------- | ---- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `--type`        | str  | no       | —       | Filter candidates by Biolink category.                                                                     |
| `-n`, `--limit` | int  | no       | —       | Maximum number of candidates to return.                                                                    |
| `-c`, `--count` | bool | no       | `False` | Return only the candidate count (capped by --limit/the API's own default -- not a true server-side total). |
| `--json`        | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                                      |
| `--full`        | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                                             |
| `--provenance`  | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default).                |

**Examples**

```bash
Lattice search BRCA1
Lattice search melanoma --type Disease
```

### `Lattice lookup`

Fetch one node by name or CURIE.

**Arguments**

| Argument | Type | Required | Description               |
| -------- | ---- | -------- | ------------------------- |
| `name`   | str  | yes      | Name or CURIE to look up. |

**Options**

| Option         | Type | Required | Default | Description                                                                                 |
| -------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| `--xrefs`      | bool | no       | `False` | Include cross-references to other vocabularies.                                             |
| `--json`       | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                       |
| `--full`       | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                              |
| `--provenance` | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default). |

**Examples**

```bash
Lattice lookup BRCA1
Lattice lookup BRCA1 --xrefs
```

### `Lattice members`

Bulk gene-to-pathway and gene-to-disease set membership.

**Constraints**

* Exactly one of the positional \<term>, --of, or --batch is required.
* \--in is always required (the membership query needs a predicate either way); must be pathways or diseases.
* \--batch reads newline-separated gene names/CURIEs from stdin; blank lines are skipped.

**Arguments**

| Argument | Type | Required | Description                   |
| -------- | ---- | -------- | ----------------------------- |
| `term`   | str  | no       | Term to query membership for. |

**Options**

| Option         | Type | Required | Default | Description                                                                                                                               |
| -------------- | ---- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `--of`         | str  | no       | —       | Gene to query membership for (alternative to a positional term).                                                                          |
| `--in`         | str  | no       | —       | Membership kind: pathways or diseases.                                                                                                    |
| `--batch`      | bool | no       | `False` | Read a gene set from stdin (one name/CURIE per line) instead of \<term>/--of, resolving the whole set in a single bulk membership() call. |
| `--json`       | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                                                                     |
| `--full`       | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                                                                            |
| `--provenance` | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default).                                               |

**Examples**

```bash
Lattice members BRCA1 --in pathways
Lattice members --of BRCA1 --in pathways
cat genes.txt | Lattice members --batch --in pathways
```

### `Lattice scan`

Stream an unranked graph slice for sweeps and piping.

**Options**

| Option              | Type            | Required | Default | Description                                                                                                                               |
| ------------------- | --------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `--predicate`, `-p` | str             | yes      | —       | Biolink predicate to scan for, e.g. regulates or interacts\_with.                                                                         |
| `--type`            | str             | no       | —       | Filter by Biolink category (the edges' object category).                                                                                  |
| `--source`          | str, repeatable | no       | —       | Filter by contributing knowledge source (repeatable). **Limited:** edges(...) takes a single source, not a list — pass at most one value. |
| `--json`            | bool            | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                                                                     |
| `--full`            | bool            | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                                                                            |
| `--provenance`      | bool            | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default).                                               |

**Examples**

```bash
Lattice scan --predicate regulates --type Gene --source DoRothEA
```

### `Lattice cat`

Print a node's properties/edges/citations.

**Arguments**

| Argument | Type | Required | Description                                                                                                                                                                           |
| -------- | ---- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `target` | str  | yes      | Node, optionally suffixed with /meta, /edges, or /provenance. /meta and /edges are backed by real operations; /provenance has no whole-node equivalent yet and returns a placeholder. |

**Options**

| Option         | Type | Required | Default | Description                                                                                 |
| -------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| `--json`       | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                       |
| `--full`       | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                              |
| `--provenance` | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default). |

**Examples**

```bash
Lattice cat BRCA1
Lattice cat BRCA1/edges
```

### `Lattice ls`

List a node's neighbors/edges, filtered by relation.

**Arguments**

| Argument | Type | Required | Description                |
| -------- | ---- | -------- | -------------------------- |
| `node`   | str  | yes      | Node to list neighbors of. |

**Options**

| Option         | Type | Required | Default | Description                                                                                 |
| -------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| `--rel`        | str  | no       | —       | Filter by relation/predicate.                                                               |
| `--json`       | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                       |
| `--full`       | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                              |
| `--provenance` | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default). |

**Examples**

```bash
Lattice ls BRCA1
Lattice ls BRCA1 --rel targets
```

### `Lattice tree`

Expand an N-hop neighborhood (fan-out capped).

**Arguments**

| Argument | Type | Required | Description     |
| -------- | ---- | -------- | --------------- |
| `node`   | str  | yes      | Node to expand. |

**Options**

| Option         | Type | Required | Default | Description                                                                                 |
| -------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| `--depth`      | int  | no       | `1`     | Neighborhood depth.                                                                         |
| `--rel`        | str  | no       | —       | Filter by relation/predicate.                                                               |
| `--json`       | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                       |
| `--full`       | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                              |
| `--provenance` | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default). |

**Examples**

```bash
Lattice tree BRCA1 --depth 2
```

### `Lattice match`

Find edges matching a single-edge pattern; for multi-hop, use path instead.

**Arguments**

| Argument  | Type | Required | Description                                                                                                                                                      |
| --------- | ---- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pattern` | str  | yes      | A single-edge pattern, e.g. '\<Gene> regulates \<Gene>' — category names are case-sensitive Biolink categories (PascalCase, e.g. Gene, Disease, ChemicalEntity). |

**Options**

| Option         | Type            | Required | Default | Description                                                                                                                               |
| -------------- | --------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `--source`     | str, repeatable | no       | —       | Filter by contributing knowledge source (repeatable). **Limited:** edges(...) takes a single source, not a list — pass at most one value. |
| `--json`       | bool            | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                                                                     |
| `--full`       | bool            | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                                                                            |
| `--provenance` | bool            | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default).                                               |

**Examples**

```bash
Lattice match '<Gene> regulates <Gene>' --source DoRothEA
```

### `Lattice path`

Shortest path between two entities (≤ 4 hops).

**Arguments**

| Argument | Type | Required | Description                    |
| -------- | ---- | -------- | ------------------------------ |
| `a`      | str  | yes      | Source entity (name or CURIE). |
| `b`      | str  | yes      | Target entity (name or CURIE). |

**Options**

| Option         | Type | Required | Default | Description                                                                                 |
| -------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| `--max-hops`   | int  | no       | `3`     | Maximum hops (≤ 4).                                                                         |
| `--json`       | bool | no       | `False` | Print the full machine-readable JSON envelope instead of compact TSV.                       |
| `--full`       | bool | no       | `False` | Widen compact TSV output to every field (still TSV, not JSON).                              |
| `--provenance` | bool | no       | `False` | Include full knowledge\_sources/publications in compact TSV output (summarized by default). |

**Examples**

```bash
Lattice path BRCA1 melanoma --max-hops 3
```

## Workflow triggering

List and trigger the analysis workflows that run behind the API.

### `Lattice workflows`

List the analysis workflows available through the API.

**Examples**

```bash
Lattice workflows
```

### `Lattice run`

Trigger an analysis workflow (URA / Target ID / Repurposing / Pathways / Tox) through the API to the Workflow Engine.

**Arguments**

| Argument   | Type | Required | Description                                                            |
| ---------- | ---- | -------- | ---------------------------------------------------------------------- |
| `workflow` | str  | yes      | Workflow to trigger (e.g. ura, target-id, repurposing, pathways, tox). |

**Options**

| Option    | Type            | Required | Default | Description                                     |
| --------- | --------------- | -------- | ------- | ----------------------------------------------- |
| `--param` | str, repeatable | no       | —       | A workflow parameter as key=value (repeatable). |

**Examples**

```bash
Lattice run ura --param gene_set=BRCA1,TP53
```

## Composability layer

Replay, narrow, and serialize a stored result set without recomputing it.

### `Lattice results`

Replay/page/reformat a stored result set without recompute.

**Arguments**

| Argument | Type | Required | Description          |
| -------- | ---- | -------- | -------------------- |
| `id`     | str  | yes      | Result ID to replay. |

**Options**

| Option      | Type            | Required | Default | Description                                     |
| ----------- | --------------- | -------- | ------- | ----------------------------------------------- |
| `--page`    | int             | no       | `1`     | Page number.                                    |
| `--per`     | int             | no       | —       | Results per page.                               |
| `--format`  | str             | no       | `tsv`   | Output format: tsv, jsonld, graphml, or cypher. |
| `--columns` | str, repeatable | no       | —       | Columns to include (repeatable).                |

**Examples**

```bash
Lattice results q_abc123 --page 2
```

### `Lattice filter`

Narrow a result set with a structured predicate (no NL).

**Arguments**

| Argument | Type | Required | Description          |
| -------- | ---- | -------- | -------------------- |
| `id`     | str  | yes      | Result ID to filter. |

**Options**

| Option    | Type | Required | Default | Description                                                                                                                                                                                                                                                                   |
| --------- | ---- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--where` | str  | yes      | —       | A single '\<field> \<op> \<value>' predicate: ==, !=, >, >=, <, <= (dot-path fields like properties.degree work). \<value> is coerced to int, then float, then left as a string — quote it (e.g. '007') to force a literal string comparison against a numeric-looking value. |

**Examples**

```bash
Lattice filter q_abc123 --where "degree > 10"
```

### `Lattice export`

Serialize a result set/subgraph, escaped per format.

**Arguments**

| Argument | Type | Required | Description          |
| -------- | ---- | -------- | -------------------- |
| `id`     | str  | yes      | Result ID to export. |

**Options**

| Option     | Type | Required | Default | Description                      |
| ---------- | ---- | -------- | ------- | -------------------------------- |
| `--format` | str  | yes      | —       | tsv, jsonld, graphml, or cypher. |

**Examples**

```bash
Lattice export q_abc123 --format tsv
```

## Feedback

Tell us how Lattice is working for you.

### `Lattice feedback`

Send us your feedback on Lattice, optionally with a 0-3 rating.

**Constraints**

* Run with no arguments at all to be prompted for both fields; give any argument and the message becomes required.

**Arguments**

| Argument  | Type | Required | Description                                                                                                                                         |
| --------- | ---- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message` | str  | no       | Your feedback, as a quoted string. Required unless you run the command with no arguments at all, which prompts for it instead. Max 4000 characters. |

**Options**

| Option           | Type | Required | Default | Description                                                                   |
| ---------------- | ---- | -------- | ------- | ----------------------------------------------------------------------------- |
| `-r`, `--rating` | int  | no       | —       | How you'd rate Lattice: 0-Poor, 1-Fine, 2-Good, 3-Great. Optional everywhere. |

**Examples**

```bash
Lattice feedback
Lattice feedback "The graph is missing the pathway I needed."
Lattice feedback -r 2 "Good, but the local graph is too small."
```


# Quickstart

Explore how Mithrl accelerates biological discovery through AI-powered analysis of RNA-seq, multi-omics, and clinical data.

## Welcome to Mithrl

Mithrl is your Scientific Decision Engine. It is an intelligent research discovery engine that helps you go from raw sequencing data to novel discoveries in minutes. From differential expression to multi-omics analysis, Mithrl helps your research team move faster and go deeper.

We ship new features weekly and build closely with our customers. This documentation outlines what the platform can do today, what's being tested with partner labs, and what's coming next.

## Explore the Docs

<table data-view="cards"><thead><tr><th>Title</th><th data-type="content-ref"></th></tr></thead><tbody><tr><td>Interactive Demos</td><td><a href="/pages/GC8uF7AzZtcfxcTHd2vm">/pages/GC8uF7AzZtcfxcTHd2vm</a></td></tr><tr><td>Supported Features</td><td><a href="/pages/irQ5lAP9eOShgEpRlf72">/pages/irQ5lAP9eOShgEpRlf72</a></td></tr><tr><td>Key Concepts</td><td><a href="/pages/UeUrEIREawn2SsIWiv4C">/pages/UeUrEIREawn2SsIWiv4C</a></td></tr><tr><td>Release Notes</td><td><a href="/pages/6t3GHBxNzMEHeVjuvGW3">/pages/6t3GHBxNzMEHeVjuvGW3</a></td></tr></tbody></table>

{% hint style="info" %}
Still have questions? We have answers. Contact us at <support@mithrl.com>
{% endhint %}


# Interactive Demo

See how Mithrl works through guided, embedded demos.

## Using the Demos

These short interactive demos show how you can use Mithrl to explore datasets, ask questions, and go deeper with follow-up insights. Everything works in natural language. No code or configuration required.

{% hint style="info" %}
These interactive demos will open in a modal window or a new tab, depending on your browser settings.
{% endhint %}

## Dataset Selection

See how easy it is to browse, select, and review metadata for your datasets all from a clean, intuitive interface. Discover how Mithrl streamlines data access, so you can focus on insights, not navigation.

{% embed url="<https://demo.arcade.software/xK20B7TU4sNLRvKWxlXb>" %}

## Ask Questions using Natural Language

From query to results, see how complex analyses become manageable with an interface designed for scientists and informatics teams. Ask a question, interact with the data, adjust settings, and generate clear, publication-ready visuals.

{% embed url="<https://demo.arcade.software/8RnPPygJg6PXkS9G6Vsu>" %}

## Explore and Dig Deeper using the Follow-Up Questions

See how the platform supports the scientific process of exploration. Just ask follow-up questions, uncover new insights, and generate hypotheses as you go. Move from high-level summaries to detailed results, visualizations, and analysis code, all within a single interface.

{% embed url="<https://demo.arcade.software/o7oo9cruSQEqDi9NHUdu>" %}

{% hint style="info" %}
Still have questions? We have answers. Contact us at <support@mithrl.com>
{% endhint %}


# Introduction

Mithrl is your AI scientific collaborator.

We've built the first commercially available Scientific Decision Engine (SDE) designed specifically for R\&D and discovery teams. From raw sequencing files to hypotheses, Mithrl compresses the time it takes to analyze, interpret, and act on biological data, from months to minutes.

This documentation outlines what the platform supports today, what is currently in limited release, and what's in active development. If you're running NGS and multi-omics experiments, looking for novel targets, or validating mechanisms of action, this guide is for you.

***

## What is Mithrl?

Mithrl is an AI-powered platform that automates NGS and multi-omics analysis, data visualization, data exploration, and hypothesis generation. It's used by therapeutic research teams to extract biological meaning from large datasets without the need for custom coding or manual data wrangling.

{% hint style="success" %}
**Mithrl supports:**

* **Bulk RNA-seq, scRNA-seq, DRUG-seq, ATAC-seq, and ChIP-seq data analysis** (10X, Smart-seq, and others)
* **Proteomics data from high throughput mass spectrometry (HTS) and Illumina Protein Prep (Somalogics)**
* **Natural language-driven workflows** — ask a scientific question and get real answers
* **Differential expression, enrichment, clustering**, and **network-based analyses**
* **Automated insight reports** with plots, gene-level tables, and mechanistic interpretation
* **Target discovery, mechanism-of-action modeling**, and **hypothesis generation**
  {% endhint %}

Designed for scientists, Mithrl handles everything from normalization, statistical analysis, visualization, literature-backed interpretation & hypothesis generation all behind the scenes.

***

## Clarifying Questions

Mithrl is built to behave like a thoughtful lab partner, not a black box. When your question is ambiguous or missing key details, it won't make assumptions or fill in gaps with made-up answers. Instead, it will ask for clarification so it can give you a precise and scientifically valid response.

For example, if you ask:

```
Show me differentially expressed genes
```

Mithrl might respond with:

```
Which groups should I compare? I didn't detect clear treatment and control labels in your question.
```

Or if you ask:

```
Find genes that are statistically significant
```

It might prompt:

```
Could you confirm the p-value threshold you want to use for significance? Default is 0.05.
```

***

## Follow-Up Questions

Mithrl doesn't just answer one question at a time. It understands context across your entire session and enables a conversational workflow that reflects how scientists naturally think through a problem.

When you ask a follow-up, Mithrl uses the results from the previous step. Whether it's a differential expression list, a filtered dataset, or an enrichment analysis, that result becomes the foundation for the next step. There's no need to restate the entire prompt or re-select your dataset. This allows you to iterate, refine, and dig deeper just like you would at the bench or in a discussion with a teammate.

For example:

```
What genes are upregulated in treated vs control?
```

```
Which of those are involved in apoptosis?
```

```
Show me KEGG pathways enriched in those genes.
```

```
Of those pathways, which ones overlap with known toxicity pathways?
```

***

## How This Documentation is Organized

This site is structured to be navigable by both bench scientists and informatics leads:

* [**Key Concepts**](/eos/key-concepts) - these are the core objects within the Mithrl platform
* [**Supported Features**](/eos/supported-features) — Tools available across all standard accounts.
* [**Trust Center**](https://trust.mithrl.com/resources?s=wgh724r3nig9pglpqnbqp\&name=hipaa-workstation-security-policy) — Mithrl's Trust Center showcases the company's SOC2 compliance certifications, and privacy policies.

If you're new to Mithrl, we recommend starting with **Supported Features** for a sense of what's immediately usable in your workspace.

***

## What Mithrl Replaces

Scientists use Mithrl to eliminate manual bioinformatics bottlenecks:

| Without Mithrl                                    | With Mithrl                                               |
| ------------------------------------------------- | --------------------------------------------------------- |
| Waiting weeks for differential expression results | Results in minutes                                        |
| Manually annotating DE genes in Excel             | Automated pathway enrichment + plots                      |
| Outsourced reports with no reproducibility        | Reproducible reports with all inputs documented           |
| Hard-to-interpret clustering heatmaps             | Dimensionality-reduced plots with annotated clusters      |
| Fragmented tools across multiple systems          | Unified, conversational interface with exportable reports |

***

## Support

{% hint style="info" %}
If you need help with the platform, you have multiple ways to reach us:
{% endhint %}

* **Email**: <support@mithrl.com>
* **Slack or Teams**: Reach out in your **dedicated customer success channel**
* **Feature questions or analysis blockers**: Ping your **Customer Success Manager** directly or email <support@mithrl.com>

We're happy to assist with data uploads, onboarding training, or scientific interpretation of results.

***

Let's get started.

{% hint style="info" %}
Still have questions? We have answers. Contact us at <support@mithrl.com>
{% endhint %}


# Key Concepts

## Raw Data (Files)

Raw data can be in the form of fastq files, matrix data, or tabular data (csv, tsv, etc). Such files can be outputs from scientific instruments or processed data files from such instruments or other bioinformatic sources. These files may be derivatives of image files (ex. processed matrix data from spatial images, cell paintings, etc), proteomics platforms (ex. high throughput mass spectrometry, antibody protein arrays, etc.), or gene expression platforms (ex.microarray).

## Datasets

Mithrl datasets form the foundation of the Mithrl Scientific Decision Engine. A Mithrl dataset is in the MFF format (Mithrl Friendly Format) and is the result of cleaning raw data files via nomenclature standardization, normalization, and harmonization. Once the dataset is created it is then ready for any agentic processing to allow acalable, and flexible tertiary analysis and hypothesis generation. This data clean up process also allows for ready true cross-dataset and cross-omics analysis.

## Analysis

An analysis is the series of natural-language queries (questions) a user asks of one or more datasets. For example, a user might take the results of a one-time single-cell experiment then ask for a volcano plot followed by a list of the top DEGs, followed by a list of the enriched pathways, followed by predicted targets. That entire thread would be an analysis.

## Projects

Projects are an aggregation of Mithrl datasets that are related to a specific research goal. Projects may include multiple analysis threads, multiple datasets and across multiple modalities.

{% hint style="info" %}
Still have questions? We have answers. Contact us at <support@mithrl.com>
{% endhint %}


# Supported Features

The following is a list of supported features

We iterate fast. If there's a feature your team needs sooner, reach out to your Customer Success Manager or contact us at <support@mithrl.com>

## Feature Overview

<table><thead><tr><th width="187">Feature</th><th width="154.6015625">Status</th><th width="201.0078125">Data Types</th><th>Description</th><th data-hidden data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>Exploratory Data Analysis (EDA)</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Supporting QC, normalization, ample filtering, and outlier detection.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Differential Expression Analysis (DEA)</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Supports Bulk RNA-seq (DESeq2, Limma, pseudobulk counts. scRNA-seq (cell type specific Wilcoxon rank-sum. Proteomics, DrugSeq, CodeOmics</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Functional Enrichment Analysis (FEA)</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Performs Gene Set Enrichment Analysis (GSEA) and Over-Representation Analysis (ORA) to identify enriched biological processes, molecular functions, and cellular components from your expression or abundance data. Outputs enrichment bar charts, pathway and gene set overlays and gene-set relationship tables. KEGG-based analysis with overlays.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Target Discovery</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Supporting raw fastq or expression matrix files (h5ad, csv, etc) as input to infer PPI networks and predicted targets. Integrates expression networks and literature.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Protein-Protein Interaction</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Visualize gene interaction networks and identify hubs or regulators based on expression data.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Clustering Analysis</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Group similar samples or cells by expression profile. Leiden/Louvain supported</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Dimensionality Reduction</strong></td><td>✅ Supported</td><td>Bulk, scRNA-seq, Proteomics, DRUG-seq, Code-Omics</td><td>Visualize structure using PCA, UMAP, t-SNE, or PACMAP.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Cell Type Identification</strong></td><td>✅ Supported</td><td>scRNA-seq</td><td>Match cell clusters to reference annotations from public atlases. uses marker gene scoring and optional references.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Discovery Engine</strong></td><td>✅ Supported</td><td>All</td><td>Leveraging the power of Mithrl's Lattice Knowledge Graph to auto-surface known &#x26; predicted associations, drug links, and co-expression via the knowledge inference engine.</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>WGS/WES Analysis</strong></td><td>🔜 Coming Soon</td><td>Genomic</td><td>Detect mutations and structural variants; link to transcriptomic impact</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>DNA Methylation (Bulk + sc)</strong></td><td>🔜 Coming Soon</td><td>Epigenomic</td><td>Identify differentially methylated regions and correlate with gene activity</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Proteomics Integration</strong></td><td>🔜 Coming Soon</td><td>Proteomic</td><td>Connect transcript expression to protein-level data and changes</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Metabolomics Integration</strong></td><td>🔜 Coming Soon</td><td>Metabolomic</td><td>Map transcriptomic shifts to metabolic pathways and readouts</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Multi-Omics Cohort Analysis</strong></td><td>🔜 Coming Soon</td><td>Multi-omics</td><td>Analyze across multiple omics (e.g., RNA, DNA, protein) into unified analysis</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Lead Optimization AI</strong></td><td>🔜 Coming Soon</td><td>Downstream</td><td>Suggest lead molecules based on gene signature, pathway response, and SAR overlays</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>High-Throughput Screening AI</strong></td><td>🔜 Coming Soon</td><td>Downstream</td><td>Interpret large HTS datasets using AI-guided dimensionality reduction, target filtering, and phenotypic enrichment</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>IND Support AI</strong></td><td>🔜 Coming Soon</td><td>Preclinical</td><td>Identify toxicogenomic signatures, validate biomarkers across species, and generate IND-ready transcriptomic justifications</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr><tr><td><strong>Clinical Trial Analysis AI</strong></td><td>🔜 Coming Soon</td><td>Clinical</td><td>Stratify trial arms, match molecular subtypes to response groups, identify responder biomarkers, and generate trial decision support summaries</td><td><a href="/files/Q5YngxGIIAbOlgN1UnYj">/files/Q5YngxGIIAbOlgN1UnYj</a></td></tr></tbody></table>

{% hint style="info" %}
Still have questions? We have answers. Contact us at <support@mithrl.com>
{% endhint %}


# Release Notes

## Release 2026-07-08

**Improved User Experience.** We've streamlined the Mithrl user interface to reduce clutter and verbose text.

* There are now only 3 tabs: Home, Datasets, and Raw Files.
* NEW: Questions panel that list all the questions in the conversation of an analysis\
  NEW: Enlarged Results tab that show the
  * Plan
  * Clarification decisions made by user
  * Artifacts (plots, tables, graphs, etc)
  * Trace (of actions taken)
  * Summary on the answer to your question.

<figure><img src="/files/5MYPEFOwchPrrhC3jXWP" alt=""><figcaption></figcaption></figure>

* NEW: Audit log tab that shows the full thinking process, ad hoc code, and steps taken to arrive at the answer to your question. The artifacts generated here are also available in the Results tab.

<figure><img src="/files/LZpYC1SbBWl1EEaOO8qT" alt=""><figcaption></figcaption></figure>

* NEW: Files tab the shows all the artifacts (Mithrl-generated tables, plots, etc) that are downloadable individually or in bulk download.

<figure><img src="/files/xbsnG8PU83Ynqrc5AzAv" alt=""><figcaption></figcaption></figure>

**Improved interactivity with graphs and plots.** You can now use sliders (when available) to view scatter plots and histograms.

<figure><img src="/files/uRi7EKRHtmgZLSzjDnYH" alt=""><figcaption></figcaption></figure>

**Upstream Regulator Networks.** Leveraging the power of the Mithrl knowledge graph, the platform can now predict the upstream regulator networks to explain observational data.

<figure><img src="/files/4AJWltTKDHyZy9BmIirI" alt=""><figcaption></figcaption></figure>

**Platform perfomance improvements.** The system should be faster to start, less likely to crash, and safer about saving results.

***

## Release 2026-06-22

**Plots and Graphs now available is PRISM format.** You can now export the Mithrl-generated plots and graphs in PRISM format. The exported plot files are in .PRISM format which should be compatible with the current and legacy versions of GraphPad Prism. To export a plot, click on the 3 dots in the upper right corner of the plot then select Export PRISM to export the plot in PRISM format.

<figure><img src="/files/bzMyvCxUlju2WER0dZ9d" alt=""><figcaption></figcaption></figure>

**Minor bug fixes and performance improvements.** The team has been working hard to improve the robustness and performance of the platform.

***

## Release 2026-06-10

**What's New in This Sprint**

**ChIP-seq and ATAC-seq Analysis Have Arrived** The wait is over. Run ChIP-seq and ATAC-seq analyses directly in Mithrl, no detours required. Import your datasets from the same screen you already know, and the platform handles the rest: automated quality control, processing, all of it. Raw data to results, faster than ever.

<div align="center"><figure><img src="/files/NTZ4h7x9IYBqK6Ruri1G" alt=""><figcaption></figcaption></figure></div>

**Your Datasets Now Come With Ideas** Create a new dataset and Mithrl gets to work immediately, inferring your research goal and surfacing up to three suggested questions to kickstart your analysis. Less staring at a blank screen, more discovering.

<figure><img src="/files/WVM0RWmfPwWFdrb204zV" alt=""><figcaption></figcaption></figure>

**Data Visualizations, Now Fully Interactive by Default** Every new visualization ships as an interactive chart. Drag to pan, scroll to zoom, go full-screen when you want the big picture. Annotations leveled up too: rectangle and lasso selection, shaded regions, and a clear-all option (with confirmation, because we've all been there). Note the Toggle New Charts Renderer setting is no longer available.

**Platform Updates:** Fresher Under the Hood Everything is now fully up to date, which means a more stable, secure, and consistent experience every day. We also made internal improvements that help us catch and squash issues before they ever reach you.

**Performance:** Built for the Heavy Lifting Faster, more reliable, and ready for your biggest workloads. Significant infrastructure improvements mean fewer slowdowns when demand spikes, so your analyses keep humming along.

**Security:** Routine security patches

***

## Release 2026-05-28

**What's New in Release 2026-05-08**

**Migration to the New Dataset Format**

If you have existing datasets created in the older Mithrl v1.0, we've started migrating user accounts to the new Mithrl v2 platform. Users have the option to use Mithrl v1 or v2. To toggle between v1 and v2, users should go to Settings>Toggle Analysis Mode.

<figure><img src="/files/Iipm8wZC3PsHJ6NmQR8J" alt=""><figcaption></figcaption></figure>

We suggest you start to use only Mithrl v2 as we plan to retire Mithrl v1 soon. The advantages of Mithrl v2 include:

* collaborative planning of analysis
* faster data analysis
*

**A New Interactive Charting Experience (Opt-In Preview)**

A new charting engine makes it easier to explore, annotate, and share your data, with interactive zoom, lasso selection, custom styling, and one-click export. It is available as an opt-in preview now and will become the default in a future release. To unlock this feature go to Settings>Toggle New Charts Renderer.

<figure><img src="/files/Wrj89pPaK3qbOPS2i4rS" alt=""><figcaption></figcaption></figure>

**More Resilient Dataset Processing**

Importing datasets is now more reliable, even when input files have minor gaps or inconsistencies.

**Platform Stability and Infrastructure**

We've made behind-the-scenes improvements to how we test and deploy updates, so you can expect a more stable and reliable platform going forward.

{% hint style="info" %}
Still have questions? We have answers. Contact us at <support@mithrl.com>
{% endhint %}


