← back to viewer

OTT Viewer API v1

Read-only HTTP API over the Open Tree of Life synthesis tree. All responses are JSON unless noted; all endpoints accept GET only.

Conventions about tree subtree nodes hoptree mrca path search

Conventions

URL scheme is /api/v1/<resource>[/<id>][?params]. The version is in the path; bumping to v2 means a breaking change.

Errors share one envelope with a stable error.code string clients can switch on:

{
  "error": {
    "code":    "node_not_found",
    "message": "No node with external_id 'ottBOGUS'.",
    "details": { "id": "ottBOGUS" }
  }
}

Caching: successful responses set Cache-Control: public, max-age=86400. The dataset only changes when OTT republishes.

CORS: Access-Control-Allow-Origin: * on every endpoint. The data is public.

Ids: taxon ids are ottN (e.g. ott93302) or anonymous mrca ids mrcaottXottY. Anything else is rejected with bad_request for the relevant param.

/about

GET/api/v1/about

Capabilities + dataset metadata. Useful for cache-busting clients (the generated_at field changes on each request, but the node_count is stable for a given dataset).

{
    "api_version": "v1",
    "node_count": 2725682,
    "summary_methods": [
        "leaves"
    ],
    "tree_formats": [
        "json",
        "newick"
    ],
    "generated_at": "2026-05-30T07:50:09Z"
}

Try it →

/tree

GET/api/v1/tree?taxon=…&k=…

The focal subtree, summary-pruned to k leaves. Each node carries display name, type, depth, tip count, supertree-leaf flag, weight (supertree descendant count), full annotation lists, and pre-computed x / y coordinates suitable for direct rendering. This is what the viewer fetches on every navigation.

paramtypedefaultnotes
taxonstringott93302OTT external id or mrca id.
kint30Summary leaf budget. Min 2.
formatenumjsonjson or newick.
labelsenumids(newick) ids or names. names emits real taxon names where present and omits internal labels that would otherwise be synthetic mrca strings.
branch_lengthsenumnone(newick) none (default) drops branch lengths; ones emits :1 placeholders.

JSON shape (truncated):

{
  "focal_id":          "ott452461",
  "displayed_root_id": "ott452461",
  "nodes": {
    "ott452461": {
      "id":             "ott452461",
      "display":        "Procellariiformes",
      "type":           "internal",
      "supertree_leaf": false,
      "weight":         231,
      "annotations":    { "supported_by": [...], "terminal": [...], ... },
      "depth":          0,
      "tip_count":      28,
      "x":              0,
      "y":              50
    },
    ...
  },
  "edges": [
    { "source": "ott452461", "target": "ott85277" },
    ...
  ]
}

Try JSON →  ·  Try Newick (ids) →  ·  Try Newick (names) →

/subtree

GET/api/v1/subtree?taxon=…

Full OTT subtree rooted at taxon, in Newick. Distinct from /tree: no summary pruning, no coordinates, no upstream stub — just the topology rooted exactly at the focal node, suitable for export to phylogenetic tooling.

paramtypedefaultnotes
taxonstringrequiredOTT id or mrca id.
formatenumnewicknewick only.
labelsenumnamesids or names. Same semantics as /tree.
branch_lengthsenumnonenone or ones.

Bounded server-side at 50,000 nodes. Requests that resolve to a larger subtree return 413 Payload Too Large with error.code = "subtree_too_large" and the actual count in error.details.node_count:

{
  "error": {
    "code":    "subtree_too_large",
    "message": "Subtree has 2725682 nodes; the cap is 50000. Re-root on a more specific clade.",
    "details": {
      "taxon":      "ott93302",
      "node_count": 2725682,
      "max_nodes":  50000
    }
  }
}

Try it (names) →  ·  Try it (ids) →

/nodes

GET/api/v1/nodes/{id}

Per-node detail. Walks the parent chain to the OTT root and includes a sample of up to 50 children (use /children for full pagination).

{
  "id":              "ott452461",
  "display":         "Procellariiformes",
  "type":            "internal",
  "weight":          231,
  "parents":         [{ "id": "...", "display": "..." }, ...],
  "child_count":     4,
  "children_sample": [{ "id": "ott85277", "display": "Diomedeidae" }, ...],
  "annotations":     { "supported_by": [...], ... },
  "external_links":  { "opentree": "https://tree.opentreeoflife.org/...", "wikidata": null, "ncbi": null }
}

Try it →

GET/api/v1/nodes/{id}/children

Paginated children of a node.

paramtypedefaultnotes
offsetint0
limitint50Cap 500.

Try it →

GET/api/v1/nodes/{id}/descendants

All descendants of a node, flat. Optional tips_only=true filter restricts to leaves of the OTT supertree.

paramtypedefaultnotes
tips_onlyboolfalse
offsetint0
limitint500Cap 5000.

Try it →

/hoptree

GET/api/v1/hoptree?ids=A,B,C…

Minimum spanning subtree of a list of visited nodes (in visit order). Same JSON shape as /tree; each node carries visited and visit_order so a client can highlight the user's path. Used to render the navigation breadcrumb in the viewer.

Try it →

/mrca

GET/api/v1/mrca?ids=A,B…

Most-recent common ancestor of a set of nodes. At least two ids required.

{
  "mrca":   { "id": "...", "display": "..." },
  "inputs": [
    { "id": "ott917716", "display": "Goniurosaurus" },
    { "id": "ott342539", "display": "Hemitheconyx" }
  ]
}

Try it →

/path

GET/api/v1/path?from=A&to=B

Topological path between two nodes via their LCA. length counts edges; via is the ordered node id list from from up to LCA and back down to to.

{
  "from":   "ott917716",
  "to":     "ott342539",
  "lca":    { "id": "...", "display": "..." },
  "length": 4,
  "via":    ["ott917716", "...", "...", "...", "ott342539"]
}

Try it →

GET/api/v1/search?q=…

Taxon name search.

paramtypedefaultnotes
qstringRequired.
modeenumexactexact, prefix, or substring.
limitint50Cap 200.
{
  "query":   "Goniurosaurus",
  "mode":    "prefix",
  "limit":   10,
  "results": [
    { "id": "ott917716", "display": "Goniurosaurus" },
    { "id": "ott665630", "display": "Goniurosaurus araneus" },
    ...
  ]
}

Try exact →  ·  Try prefix →

Source

Reference implementation in PHP, served by api/index.php with the per-resource handlers under api/handlers/. Source on GitHub; design rationale in api-design.md.