Skill Tracer
Skills › Scientific Agent Skills › ncats-arax › query-contract.md

query-contract.md

169 lines · skills/ncats-arax/references/query-contract.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# ARAX query contract
2

ARAX query contract

Raw lines 1 to 2
3## Contents
4
5- [Service boundary](#service-boundary)
6- [Supported query shapes](#supported-query-shapes)
7- [Validation](#validation)
8- [Fixed operations](#fixed-operations)
9- [Limits and retries](#limits-and-retries)
10- [Version and endpoint policy](#version-and-endpoint-policy)
11- [Excluded escape hatches](#excluded-escape-hatches)

Contents

  • Service boundary
  • Supported query shapes
  • Validation
  • Fixed operations
  • Limits and retries
  • Version and endpoint policy
  • Excluded escape hatches
Raw lines 3 to 12
13## Service boundary
15Use `https://arax.transltr.io/api/arax/v1.4` by default. A networked command first retrieves
16`/openapi.json`, verifies an ARAX title, `POST /query`, and `GET /entity`, and records the advertised
17ARAX and TRAPI versions. Normalization uses `/entity`; graph lookup uses `/query`.
19| Endpoint | Request and response contract |
20| --- | --- |
21| `GET /openapi.json` | OpenAPI object; ARAX version is `info.version`, TRAPI version is `info.x-trapi.version` (title fallback). No biomedical term is submitted. |
22| `GET /entity?q=<term>` | URL-encoded `q`; the API permits repeated `q` but this client submits one. Response is keyed by input term, with `id.identifier`, `id.name`, `id.category`, `categories`, `nodes`, and `total_synonyms`. Unknown terms may have no usable record. |
23| `POST /query` | JSON `message.query_graph`, ARAX-specific `operations.actions`, `stream_progress: false`, and `submitter`. Response is a TRAPI envelope with `message`, optional `status`, `description`, `logs`, and version fields. |
25Entity synonym entries use `label` for their display name; the client also accepts older `name`
26entries. The canonical display name remains `id.name`. This is ARAX's entity response contract,
27not the SRI Node Normalizer's direct response schema.
29These routes require no API key in the deployed OpenAPI. The fixed result limit is an ARAXi
30filter, not pagination: the client does not follow pages or promise a complete enumeration of
31all matching graph paths. The API's broader pagination and asynchronous fields are not used.
33Every normalization or graph request requires `--acknowledge-public-query`. This is an explicit
34acknowledgment that query and caller metadata may be visible through service facilities. The
35`store=false` operation reduces intentional response storage but is not a privacy guarantee.

Service boundary

Use https://arax.transltr.io/api/arax/v1.4 by default. A networked command first retrieves /openapi.json, verifies an ARAX title, POST /query, and GET /entity, and records the advertised ARAX and TRAPI versions. Normalization uses /entity; graph lookup uses /query.

EndpointRequest and response contract
GET /openapi.jsonOpenAPI object; ARAX version is info.version, TRAPI version is info.x-trapi.version (title fallback). No biomedical term is submitted.
GET /entity?q=<term>URL-encoded q; the API permits repeated q but this client submits one. Response is keyed by input term, with id.identifier, id.name, id.category, categories, nodes, and total_synonyms. Unknown terms may have no usable record.
POST /queryJSON message.query_graph, ARAX-specific operations.actions, stream_progress: false, and submitter. Response is a TRAPI envelope with message, optional status, description, logs, and version fields.

Entity synonym entries use label for their display name; the client also accepts older name entries. The canonical display name remains id.name. This is ARAX's entity response contract, not the SRI Node Normalizer's direct response schema.

These routes require no API key in the deployed OpenAPI. The fixed result limit is an ARAXi filter, not pagination: the client does not follow pages or promise a complete enumeration of all matching graph paths. The API's broader pagination and asynchronous fields are not used.

Every normalization or graph request requires --acknowledge-public-query. This is an explicit acknowledgment that query and caller metadata may be visible through service facilities. The store=false operation reduces intentional response storage but is not a privacy guarantee.

Raw lines 13 to 36
37## Supported query shapes

Supported query shapes

Raw lines 37 to 38
39### One hop
41Use two qnodes (`n0`, `n1`) and one qedge (`e0`). Require one category on each qnode, one to five
42predicates, and at least one pinned endpoint. Each qnode has at most one CURIE. Omit `ids` from an
43unpinned qnode.

One hop

Use two qnodes (n0, n1) and one qedge (e0). Require one category on each qnode, one to five predicates, and at least one pinned endpoint. Each qnode has at most one CURIE. Omit ids from an unpinned qnode.

Raw lines 39 to 44
45### Two hops
47Use three qnodes (`n0`, `n1`, `n2`) and two qedges (`e0`, `e1`). Pin `n0` and `n2` with exactly one
48CURIE each. Type every qnode. Keep `n1` unpinned. Each edge has one to five predicates.
50For either shape, an edge may have zero to six qualifiers. Combine them in one
51`qualifier_constraints` entry containing one AND-conjoined `qualifier_set`. Omit the whole field
52when no qualifier is supplied. Do not repeat a qualifier type on the same edge.

Two hops

Use three qnodes (n0, n1, n2) and two qedges (e0, e1). Pin n0 and n2 with exactly one CURIE each. Type every qnode. Keep n1 unpinned. Each edge has one to five predicates.

For either shape, an edge may have zero to six qualifiers. Combine them in one qualifier_constraints entry containing one AND-conjoined qualifier_set. Omit the whole field when no qualifier is supplied. Do not repeat a qualifier type on the same edge.

Raw lines 45 to 53
54## Validation
56CURIEs follow this conservative form:
58```text
59^[A-Za-z][A-Za-z0-9._-]*:[^\s]+$
60```
62They must be no more than 200 characters and contain no controls, NUL, tabs, or newlines.
64Categories, predicates, and qualifier types follow:
66```text
67^biolink:[A-Za-z][A-Za-z0-9._-]*$
68```
70Provider identifiers are interpolated into an ARAXi action and therefore use the stricter form:
72```text
73^infores:[A-Za-z0-9._-]+$
74```
76Do not maintain a local Biolink model or provider registry. Shape validation is local; ARAX remains
77the semantic authority. Reject duplicate predicates, qualifier types, provider IDs, and repeated
78scalar endpoint options.

Validation

CURIEs follow this conservative form:

^[A-Za-z][A-Za-z0-9._-]*:[^\s]+$

They must be no more than 200 characters and contain no controls, NUL, tabs, or newlines.

Categories, predicates, and qualifier types follow:

^biolink:[A-Za-z][A-Za-z0-9._-]*$

Provider identifiers are interpolated into an ARAXi action and therefore use the stricter form:

^infores:[A-Za-z0-9._-]+$

Do not maintain a local Biolink model or provider registry. Shape validation is local; ARAX remains the semantic authority. Reject duplicate predicates, qualifier types, provider IDs, and repeated scalar endpoint options.

Raw lines 54 to 79
80## Fixed operations
82Lookup mode fixes the provider to `infores:rtx-kg2`. Federated mode requires two to five explicit,
83distinct provider identifiers and emits them in one list-valued `kp=` argument. Never omit `kp` and
84never generate duplicate `kp=` arguments.
86One hop expands `e0`. Two-hop right-first expands `e1` and then `e0`; left-first reverses only those
87two actions. Append exactly:
89```text
90scoreless_resultify(ignore_edge_direction=true)
91filter_results(action=limit_number_of_results,max_results=<1-50>,prune_kg=true)
92return(response=true,store=false)
93```
95Each expansion fixes:
97```text
98kp_timeout=30,return_minimal_metadata=false
99```
101Always send `stream_progress: false` and the constant submitter
102`scientific-agent-skills-ncats-arax`. Never put a user name, project name, or query term into the
103submitter or User-Agent.

Fixed operations

Lookup mode fixes the provider to infores:rtx-kg2. Federated mode requires two to five explicit, distinct provider identifiers and emits them in one list-valued kp= argument. Never omit kp and never generate duplicate kp= arguments.

One hop expands e0. Two-hop right-first expands e1 and then e0; left-first reverses only those two actions. Append exactly:

scoreless_resultify(ignore_edge_direction=true)
filter_results(action=limit_number_of_results,max_results=<1-50>,prune_kg=true)
return(response=true,store=false)

Each expansion fixes:

kp_timeout=30,return_minimal_metadata=false

Always send stream_progress: false and the constant submitter scientific-agent-skills-ncats-arax. Never put a user name, project name, or query term into the submitter or User-Agent.

Raw lines 80 to 104
105## Limits and retries
107| Control | Value |
108| --- | ---: |
109| OpenAPI/entity HTTP timeout | 30 seconds |
110| Lookup query HTTP timeout | 120 seconds |
111| Federated query HTTP timeout | 180 seconds |
112| ARAX KP timeout | 30 seconds |
113| Lookup default result limit | 20 |
114| Federated default result limit | 50 |
115| Hard result limit | 50 |
116| Provider count | 2-5 in federation |
117| Predicates per edge | 1-5 |
118| Qualifiers per edge | 0-6 |
119| Raw response limit | 25 MiB (26,214,400 bytes) |
121Retry OpenAPI and entity GET requests once after HTTP 429, 502, 503, 504, or a transport timeout.
122Honor `Retry-After` for at most 10 seconds; otherwise wait one second. Never retry POST `/query`.
123A failed POST may have been processed and must be rerun only by an explicit user decision.
125The client requires strict JSON. On 2026-09-30, `/entity?q=primary+myelofibrosis` returned `NaN`
126inside auxiliary knowledge-graph attributes and was correctly retained as a malformed response
127(exit 6). The worked example uses a successfully tested entity. If this happens for another
128term, inspect the raw artifact and curate the CURIE independently; do not treat it as no match.
130Use these headers:
132```text
133Accept: application/json
134Accept-Encoding: identity
135Content-Type: application/json # POST only
136User-Agent: scientific-agent-skills-ncats-arax/1.1
137```

Limits and retries

ControlValue
OpenAPI/entity HTTP timeout30 seconds
Lookup query HTTP timeout120 seconds
Federated query HTTP timeout180 seconds
ARAX KP timeout30 seconds
Lookup default result limit20
Federated default result limit50
Hard result limit50
Provider count2-5 in federation
Predicates per edge1-5
Qualifiers per edge0-6
Raw response limit25 MiB (26,214,400 bytes)

Retry OpenAPI and entity GET requests once after HTTP 429, 502, 503, 504, or a transport timeout. Honor Retry-After for at most 10 seconds; otherwise wait one second. Never retry POST /query. A failed POST may have been processed and must be rerun only by an explicit user decision.

The client requires strict JSON. On 2026-09-30, /entity?q=primary+myelofibrosis returned NaN inside auxiliary knowledge-graph attributes and was correctly retained as a malformed response (exit 6). The worked example uses a successfully tested entity. If this happens for another term, inspect the raw artifact and curate the CURIE independently; do not treat it as no match.

Use these headers:

Accept: application/json
Accept-Encoding: identity
Content-Type: application/json        # POST only
User-Agent: scientific-agent-skills-ncats-arax/1.1
Raw lines 105 to 138
139## Version and endpoint policy
141Production OpenAPI and all eight live smoke tests were verified on 2026-09-30 against ARAX 1.5.4
142with TRAPI 1.5.0. The `/v1.4` URL component is not the advertised TRAPI version. Parse the common response fields for TRAPI 1.5
143and 1.6, warning whenever the version is not the tested value. Refuse an unknown or missing TRAPI
144series unless `--allow-untested-version` is explicit. Record `biolink_version` from each query
145response rather than assuming it.
147Accept only HTTPS base URLs without credentials, query strings, or fragments. Reject localhost and
148literal private, loopback, link-local, or reserved addresses. A URL other than the production base
149requires `--allow-nonproduction-endpoint`, must still identify ARAX through OpenAPI, and receives a
150warning. Reject cross-origin and protocol-downgrade redirects. Never fall back automatically to
151`arax.ncats.io` or another ARA.
153The operations were checked against the [deployed OpenAPI](https://arax.transltr.io/api/arax/v1.4/openapi.json),
154[ARAX query execution](https://github.com/RTXteam/RTX/blob/master/code/ARAX/ARAXQuery/ARAX_query.py),
155[expander](https://github.com/RTXteam/RTX/blob/master/code/ARAX/ARAXQuery/ARAX_expander.py), and
156[result filter](https://github.com/RTXteam/RTX/blob/master/code/ARAX/ARAXQuery/ARAX_filter_results.py).
157`scoreless_resultify` is supported by the query dispatcher even though the DSL guide documents
158`resultify` more prominently; `resultify` additionally triggers ranking and is not interchangeable.
159Provider availability is chosen from ARAX's current registry by version and maturity; the
160MolePro example is a tested selection, not a permanently available provider list.

Version and endpoint policy

Production OpenAPI and all eight live smoke tests were verified on 2026-09-30 against ARAX 1.5.4 with TRAPI 1.5.0. The /v1.4 URL component is not the advertised TRAPI version. Parse the common response fields for TRAPI 1.5 and 1.6, warning whenever the version is not the tested value. Refuse an unknown or missing TRAPI series unless --allow-untested-version is explicit. Record biolink_version from each query response rather than assuming it.

Accept only HTTPS base URLs without credentials, query strings, or fragments. Reject localhost and literal private, loopback, link-local, or reserved addresses. A URL other than the production base requires --allow-nonproduction-endpoint, must still identify ARAX through OpenAPI, and receives a warning. Reject cross-origin and protocol-downgrade redirects. Never fall back automatically to arax.ncats.io or another ARA.

The operations were checked against the deployed OpenAPI, ARAX query execution, expander, and result filter. scoreless_resultify is supported by the query dispatcher even though the DSL guide documents resultify more prominently; resultify additionally triggers ranking and is not interchangeable. Provider availability is chosen from ARAX's current registry by version and maturity; the MolePro example is a tested selection, not a permanently available provider list.

Raw lines 139 to 161
162## Excluded escape hatches
164Expose no raw JSON submission, query-file, generic node/edge list, workflow, operations, action,
165overlay, ranking, inference, creative-query, link-prediction, Pathfinder, ARS, all-provider,
166batching, stdin-list, cache, database, daemon, server, SDK, MCP, or third-hop option.
168The offline summarizer validates the saved request against this same topology and operation
169contract. It refuses unsupported requests rather than becoming a back door for broader ARAX use.

Excluded escape hatches

Expose no raw JSON submission, query-file, generic node/edge list, workflow, operations, action, overlay, ranking, inference, creative-query, link-prediction, Pathfinder, ARS, all-provider, batching, stdin-list, cache, database, daemon, server, SDK, MCP, or third-hop option.

The offline summarizer validates the saved request against this same topology and operation contract. It refuses unsupported requests rather than becoming a back door for broader ARAX use.

Raw lines 162 to 169
Uses an outside tool MCP :166