cfy ChemOnt classifier
Classify chemical structures given as SMILES into the ChemOnt taxonomy (ClassyFire-style). JSON over HTTP, no authentication, no rate limit.
Try it
One SMILES per line. One line sends a single request; several lines send a batch.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /classify | Classify one SMILES or a batch |
GET | /version | Service, engine and rule versions, and the live limits |
GET | /healthz | Liveness: {"status": "ok"} |
GET | /openapi.json | OpenAPI 3.1 description of this API |
GET | /llms.txt | Short Markdown guide for LLM agents |
POST /classify
Send Content-Type: application/json and a body with exactly one field, smiles: a string for one compound, or an array of 1 to 1000 strings for a batch.
Single
curl -s https://HOST/classify -H 'Content-Type: application/json' \
-d '{"smiles": "CN1C=NC2=C1C(=O)N(C)C(=O)N2C"}'
Returns one classification object:
{
"smiles": "CN1C=NC2=C1C(=O)N(C)C(=O)N2C",
"inchikey": null,
"kingdom": {"name": "Organic compounds", "chemont_id": "CHEMONTID:0000000"},
"superclass": {"name": "Organoheterocyclic compounds", "chemont_id": "CHEMONTID:0000002"},
"class": {"name": "Imidazopyrimidines", "chemont_id": "CHEMONTID:0001797"},
"subclass": {"name": "Purines and purine derivatives", "chemont_id": "CHEMONTID:0000245"},
"intermediate_nodes": [],
"direct_parent": {"name": "Xanthines", "chemont_id": "CHEMONTID:0000247"},
"alternative_parents": [ ... ]
}
Batch
curl -s https://HOST/classify -H 'Content-Type: application/json' \
-d '{"smiles": ["CCO", "not a smiles", "c1ccccc1O"]}'
{"count": 3, "results": [
{"smiles": "CCO", "inchikey": null, "kingdom": {...}, ...},
{"smiles": "not a smiles", "error": {"code": "invalid_smiles", "message": "the SMILES could not be parsed"}},
{"smiles": "c1ccccc1O", ...}
]}
results has one entry per input, in input order. A bad SMILES becomes an item error and never fails the batch, so check each entry for an error key.
Classification fields
| Field | Type | Meaning |
|---|---|---|
smiles | string | The input, echoed as sent |
inchikey | null | Reserved; always null in this build |
kingdom, superclass, class, subclass | node or null | ChemOnt levels 1 to 4 of the direct parent's lineage |
intermediate_nodes | node[] | Lineage nodes between subclass and direct parent |
direct_parent | node or null | The most specific category chosen |
alternative_parents | node[] | Other most-specific categories the compound matches |
A node is {"name": "Xanthines", "chemont_id": "CHEMONTID:0000247"}. Levels are null when the lineage is shorter; all are null when nothing matched.
Limits
| Limit | Default | When exceeded |
|---|---|---|
| Request body | 1 MiB | 413 body_too_large |
| SMILES per request | 1000 | 413 batch_too_large |
| SMILES length | 2000 bytes | item error smiles_too_long |
| Atoms per molecule | 1000 | item error molecule_too_large |
| Request deadline | 30 s | 504 request_timeout, no partial results |
Live values are in /version.
Errors
Every error has the body {"error": {"code": "...", "message": "..."}}. Match on code; the message text may change.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_json | Body is not JSON |
| 404 | not_found | Unknown path |
| 405 | method_not_allowed | Wrong method for the path |
| 413 | body_too_large, batch_too_large | Over a size limit |
| 415 | unsupported_media_type | Not application/json, or compressed |
| 422 | invalid_request | Wrong JSON shape (missing smiles, unknown field, empty list) |
| 422 | invalid_smiles, smiles_too_long, molecule_too_large | Single request: the SMILES was refused |
| 500 | internal_error | Unexpected failure |
| 503 | overloaded | Busy; retry after about 1 s |
| 504 | request_timeout | Past the deadline; send smaller batches |
For agents and tools
/openapi.jsonis an OpenAPI 3.1 spec; load it into any OpenAPI client, or turn theclassifyoperation into a function or tool definition./llms.txtis a short Markdown guide written for LLM agents.- Prefer one batch of up to 1000 SMILES over many single calls.
- Store
rules_git_shafrom/versionwith results: classifications can change when the rules do.
Versioning
This is API version 1. Within version 1, fields and error codes may be added but not removed or changed in meaning, so ignore unknown fields. A breaking change would be served under /v2/.