# ToxIndex API — agent guide

> Agent-first HTTP gateway over ToxIndex's toxicology services: chemical-property
> predictions (ToxJobs), regulatory-document search + retrieval (Crawler), a
> knowledge graph (Yard), and datasets (Kiln). This page tells an agent how to
> start making calls.

- Base URL: `https://gateway.toxindex.com`
- Every endpoint is under `/v1` and returns JSON.
- Machine-readable spec: `https://gateway.toxindex.com/openapi.json` (interactive: `/docs`)

## Authentication

Every `/v1` endpoint requires an OIDC access token, sent as
`Authorization: Bearer <token>`. Only this guide (`/llms.txt`, `/agents.md`), the
spec (`/openapi.json`), and `/docs` are reachable without one; any other call
returns `401`.

**No account yet?** Sign up at https://sage.toxindex.com/signup (free), then get a
token with the device flow below. Need programmatic API access or a `client_id`?
Request one at https://toxindex.com/contact.

**Getting a token — OAuth 2.0 device flow (RFC 8628).** No redirect/callback URL,
so an agent can walk a human through it end to end:

1. `POST https://auth.toxindex.com/oauth/device/authorize` with your `client_id`
   → returns a `user_code` and a `verification_uri`.
2. Tell the user to open the `verification_uri` and sign in to approve — they can
   create an account there if they don't have one.
3. Poll `POST https://auth.toxindex.com/oauth/token` with
   `grant_type=urn:ietf:params:oauth:grant-type:device_code` until it returns an
   `access_token`.

Endpoints are advertised at
`https://auth.toxindex.com/.well-known/openid-configuration`; a `client_id` is
issued per integrator (request one at https://toxindex.com/contact). Send the
token on every call:

```bash
curl -s https://gateway.toxindex.com/v1/tools \
  -H "Authorization: Bearer $TOKEN" | jq '.items[] | {name, description}'
```

The examples below omit `-H "Authorization: Bearer $TOKEN"` for brevity — add it
to every `/v1` request. Requests are rate-limited per caller, so be gentle.

## Conventions

- List/search endpoints return `{items, total, limit, offset, next_offset}`.
  Page with `?limit=` (max 100) and `?offset=`.
- Predictions are **asynchronous**: submit a run, then poll for the result.
- Rate limited per caller: a `429` response carries a `Retry-After` header —
  wait that many seconds and retry.

## Be a good citizen (please cache + self-throttle)

This is a shared, free service. Two things keep it fast for everyone:

- **Cache results locally.** Responses are stable for the same inputs (identical
  predictions, searches, and resolutions return the same answer), so key a local
  cache on the request URL + params and reuse it instead of re-fetching. A run's
  completed result never changes — store it once. Resolutions and tool/database
  listings change rarely; cache them for minutes-to-hours.
- **Throttle yourself.** Keep well under the limits: a few requests per second,
  not tight loops. When polling a run, wait **2–5 s between polls** (results take
  seconds to minutes), not sub-second. On `429`, back off for the `Retry-After`
  interval. Request only the `limit` you need.

Doing both makes your agent faster (cache hits are instant) and keeps the service
responsive for the room.

## ToxIndex Jobs (ToxJobs) — run chemical predictions

A curated set of **10 well-known prediction tools** is available to the public.
`GET /v1/tools` lists exactly these (with descriptions, tags, and health):

```bash
curl -s https://gateway.toxindex.com/v1/tools | jq '.items[] | {name, description}'
```

| tool | what it predicts |
|------|------------------|
| `admet-ai` | ADMET-AI — #1 on the TDC benchmark; 41 ADMET properties |
| `admetlab` | ADMETlab 3.0 — 119 ADMET properties |
| `admetica-v2` | Admetica — 23-endpoint ADMET (CYP, clearance, hERG, LD50) |
| `amesformer` | AmesFormer — Ames mutagenicity (transformer) |
| `toxtransformer` | ToxTransformer — 6,647 toxicology & bioactivity properties (GPU) |
| `tox21` | Tox21 — 12-endpoint nuclear-receptor & stress-response panel |
| `toxtree` | Toxtree — rule-based structural alerts (Cramer classes, skin sens.) |
| `cardiotox` | CardioTox — hERG channel blockade |
| `biotransformer` | BioTransformer — metabolism prediction (CYP450, Phase II) |
| `dtox` | DTox — knowledge-guided deep-learning toxicity |

Run any of them (input is usually a SMILES string), then poll until done:

```bash
RID=$(curl -s -X POST https://gateway.toxindex.com/v1/runs/admet-ai \
  -H 'Content-Type: application/json' -d '{"smiles":"CCO"}' | jq -r .run_id)

curl -s https://gateway.toxindex.com/v1/runs/$RID | jq '{status, result}'
# repeat until .status == "completed"; then .result holds the prediction
```

- `POST /v1/runs/{tool}` → `202 {run_id, status:"queued"}`
- `GET /v1/runs/{id}` → `{status: queued|running|completed|failed, result, error}`
- GPU/large-result tools (e.g. `toxtransformer`) take longer — keep polling.

## Resolve — name/identifier → canonical chemical

Turn a name, CAS, SMILES, InChI(Key), PubChem CID, or ChEMBL/ChEBI id into a
canonical compound (InChIKey, IUPAC name, synonyms, cross-database ids) — handy
before a prediction or to disambiguate an input:

```bash
curl -s 'https://gateway.toxindex.com/v1/resolve?q=naphthalene' | jq '{title, inchikey, cid, xrefs}'
```

## Crawler — search & read regulatory documents

Search indexed regulatory toxicology documents (`mode=keyword` for exact terms,
`mode=vector` for natural-language queries):

```bash
curl -s 'https://gateway.toxindex.com/v1/documents?q=naphthalene&mode=keyword' \
  | jq '.items[] | {id, url, snippet}'
```

Add `collection=` to scope to one source for a fast, focused query. Available
collections — ECHA / EU regulatory: `echa-substances`, `echa-reach-dossiers`,
`echa-svhc-support`, `echa-clh-rac`, `echa-authorisation-restriction`,
`efsa-opinions`; international authorities: `iarc-monographs`, `atsdr-profiles`,
`who-chemicals`, `health-canada`, `nite-chrip`, `aop-wiki`; open-access
literature: `europepmc-oa`:

```bash
curl -s 'https://gateway.toxindex.com/v1/documents?q=bisphenol&collection=echa-svhc-support' \
  | jq '.items[] | {id, url, snippet}'
```

Fetch a document's full extracted text by its `id` (from a search hit):

```bash
curl -s https://gateway.toxindex.com/v1/documents/28cc2cb766ae58b4 \
  | jq '{url, size_bytes, text}'
```

## Yard — search open-access databases

Search one open-access database at a time via the required `db` parameter. ~20
curated, freely-redistributable databases are available:

- **Literature & chemistry:** `pubmed`, `pubchem`, `pubchem-annotations`, `pubchemghs`, `ebi-chembl`, `bindingdb-bindingdb`, `lotus-nps`
- **Drugs & clinical:** `drugcentral`, `opentargets-platform`, `clinicaltrials`, `faers`, `fda-orange-book`, `fda-drug-induced-liver-injury-rank-dili`, `fda-drug-induced-cardiotoxicity-rank-di`
- **Toxicology & regulatory:** `toxvaldb-update`, `japan-nite-ghs`, `comptox`, `cpdat-products`, `ntp-roc`, `nci-dtp-open`

```bash
# literature
curl -s 'https://gateway.toxindex.com/v1/search?db=pubmed&q=acetaminophen+hepatotoxicity' | jq '.items[] | {id, title, url}'

# curated annotations (use specific terms — broad queries are capped at 50 hits)
curl -s 'https://gateway.toxindex.com/v1/search?db=pubchem-annotations&q=hepatotoxicity' | jq '.items[] | {title, url, summary}'

# toxicity values — database-specific columns come back under .data
curl -s 'https://gateway.toxindex.com/v1/search?db=toxvaldb-update&q=1338-23-4' | jq '.items[] | .data | {CASRN, TOXVAL_TYPE, EXPOSURE_ROUTE}'
```

Each hit is `{db, id, title, url, summary, data}` — `data` carries the raw
database-specific row for databases without a purpose-built shape. Page with
`limit`/`offset` (max 50). Omitting `db` (or using an unknown one) returns the
list of available databases.

## Kiln — datasets

```bash
curl -s 'https://gateway.toxindex.com/v1/datasets?q=epa' | jq '.items[] | {slug, title}'
```

## Full reference

Everything above is documented machine-readably at
`https://gateway.toxindex.com/openapi.json`.
