SeqChem API
A free JSON API over OpenBabel, OPSIN and a set of native sequence tools. Convert between 190+ chemical formats, compute descriptors, draw structures, resolve IUPAC names and process FASTA/FASTQ — no API key, no sign-up, CORS enabled.
Calls are free. Please do not hammer the service — it is a single small server, and heavy endpoints are serialised.
Quick start
Convert a SMILES string to InChI:
curl -s https://seqandchem.com/api/v1/convert \
-H 'Content-Type: application/json' \
-d '{"from":"smi","to":"inchi","data":"CC(=O)Oc1ccccc1C(=O)O"}'
Same call from Python:
import requests
r = requests.post("https://seqandchem.com/api/v1/convert", json={
"from": "smi",
"to": "inchi",
"data": "CC(=O)Oc1ccccc1C(=O)O",
})
r.raise_for_status()
print(r.json()["result"])
# InChI=1S/C9H8O4/c1-6(10)13-8-5-3-2-4-7(8)9(11)12/h2-5H,1H3,(H,11,12)
Or use the official client — standard library only, no dependencies:
pip install seqchem
from seqchem import Client
c = Client()
print(c.convert("CC(=O)Oc1ccccc1C(=O)O", to="inchi")["result"])
print(c.properties("CCO")[0]["props"]["MW"]) # 46.069
print(c.similarity("CCO", "CCCO")) # Tanimoto
And from the browser — CORS is enabled, so this works from any origin:
const res = await fetch("https://seqandchem.com/api/v1/properties", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ from: "smi", data: "CC(=O)Oc1ccccc1C(=O)O" }),
});
const data = await res.json();
console.log(data.rows[0].props.MW); // 180.159
Format identifiers
Every format is referred to by its OpenBabel id: smi, can,
inchi, inchikey, mol, sdf,
mol2, pdb, xyz, cml, smi,
png, svg, pdf and roughly 180 more. Get the full list
with GET /api/v1/formats — it also tells you which
formats can be read and which can be written.
curl -s https://seqandchem.com/api/v1/formats | python3 -m json.tool | head -20
Endpoints
All paths below are relative to https://seqandchem.com. Every POST endpoint
accepts a JSON body and returns JSON.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/formats | List supported formats |
| GET | /api/v1/example | Example molecule in any format |
| POST | /api/v1/convert | Convert between formats |
| POST | /api/v1/properties | Molecular descriptors |
| POST | /api/v1/depict | 2D structure as SVG |
| POST | /api/v1/gen3d | 3D conformer as SDF |
| POST | /api/v1/substructure | SMARTS substructure filter |
| POST | /api/v1/fingerprint | FP2/FP3/FP4/MACCS fingerprint |
| POST | /api/v1/similarity | Tanimoto similarity |
| POST | /api/v1/iupac | IUPAC name → structure |
| POST | /api/v1/batch | Bulk file conversion |
| POST | /api/v1/formula | Formula ↔ structure |
| POST | /api/v1/bio | FASTA / FASTQ operations |
GET /api/v1/formats
Lists every format with a description and whether it can be read, written, or both.
| Query | Type | Description |
|---|---|---|
dir | string | Optional filter: read or write |
{
"ok": true,
"items": [
{"id": "smi", "desc": "SMILES format", "read": true, "write": true},
{"id": "inchi", "desc": "InChI format", "read": true, "write": true}
]
}
GET /api/v1/example
Returns aspirin in the requested format. Useful to check what a format looks like before writing a parser.
| Query | Type | Description |
|---|---|---|
format | string | Format id, default smi |
{"ok": true, "format": "mol", "data": " aspirin\n ..."}
POST /api/v1/convert
Converts one or more records between any two readable/writable formats. Text output comes back
in result; binary output (PNG, PDF, STL) comes back base64-encoded in
data_url.
| Field | Type | Description |
|---|---|---|
data | string | Required. Molecule data in the source format |
from | string | Input format id, default smi |
to | string | Output format id, default mol |
opts | string[] | Optional OpenBabel flags: --gen3d, --canonical,
--addhydrogens, --deletehydrogens, --unique, --separate |
{
"ok": true,
"binary": false,
"result": "InChI=1S/C9H8O4/c1-6(10)13-8-5-3-2-4-7(8)9(11)12/h2-5H,1H3,(H,11,12)",
"mime": "text/plain",
"is_image": false,
"log": "1 molecule converted"
}
Requesting a 3D format (sdf, mol2, xyz,
pdb) adds --gen3d automatically if you do not pass it.
POST /api/v1/properties
Computes descriptors for every record in data. One row per molecule.
| Field | Type | Description |
|---|---|---|
data | string | Required. One or more molecules |
from | string | Input format id, default smi |
{
"ok": true,
"rows": [{
"smiles": "CC(=O)Oc1ccccc1C(=O)O",
"props": {
"formula": "C9H8O4", "MW": "180.159", "logP": "1.3101",
"TPSA": "63.6", "HBD": "1", "HBA1": "4", "rotors": "3",
"atoms": "21", "bonds": "21", "MR": "44.691",
"cansmi": "CC(=O)Oc1ccccc1C(=O)O",
"InChI": "InChI=1S/C9H8O4/c1-6(10)...",
"InChIKey": "BSYNRYMUTXBXSQ-UHFFFAOYSA-N"
}
}],
"labels": {"formula": "Formula", "MW": "Molecular weight"}
}
POST /api/v1/depict
Renders a 2D depiction and returns the raw SVG markup in svg. The SVG is
self-contained — embed it directly in a page.
| Field | Type | Description |
|---|---|---|
data | string | Required. Molecules to draw |
from | string | Input format id, default smi |
{"ok": true, "svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" ...></svg>"}
POST /api/v1/gen3d
Generates a force-field optimised 3D conformer and returns an SDF block. This is a heavy
operation: it is serialised across the whole server, so under load you may get
429 with a retry hint.
| Field | Type | Description |
|---|---|---|
data | string | Required. Molecules |
from | string | Input format id, default smi |
{"ok": true, "result": " aspirin\n RDKit 3D\n..."}
POST /api/v1/substructure
Filters molecules by a SMARTS pattern and returns the matching ones.
| Field | Type | Description |
|---|---|---|
data | string | Required. Molecules to search |
smarts | string | Required. SMARTS pattern, max 500 chars |
from | string | Input format id, default smi |
{"ok": true, "count": 2, "matches": ["CC(=O)Oc1ccccc1C(=O)O", "CC(=O)Nc1ccc(O)cc1"]}
POST /api/v1/fingerprint
Returns the raw fingerprint bit string for each molecule.
| Field | Type | Description |
|---|---|---|
data | string | Required. Molecules |
fp | string | FP2 (default), FP3, FP4,
MACCS, ECFP2, ECFP4, ECFP6 |
from | string | Input format id, default smi |
{"ok": true, "result": "00000000 00000000 00000001 ...", "words": 18}
POST /api/v1/similarity
Tanimoto coefficient between two molecules.
| Field | Type | Description |
|---|---|---|
a | string | Required. First molecule |
b | string | Required. Second molecule |
fp | string | FP2 (default), FP3, FP4, MACCS |
from | string | Input format id, default smi |
{"ok": true, "tanimoto": 0.4815, "bits_a": 54, "bits_b": 52, "common": 25, "union": 81}
POST /api/v1/iupac
Parses an IUPAC name with OPSIN (Cambridge) and returns the structure identifiers.
| Field | Type | Description |
|---|---|---|
name | string | Required. IUPAC name, max 300 chars |
{
"ok": true,
"resolved": true,
"source": "opsin",
"smiles": "CC(=O)Oc1ccccc1C(=O)O",
"inchi": "InChI=1S/C9H8O4/c1-6(10)...",
"inchikey": "BSYNRYMUTXBXSQ-UHFFFAOYSA-N"
}
If the name cannot be interpreted you get ok: true, resolved: false with a
message — this is not an error, just a miss.
POST /api/v1/batch
Bulk conversion of a whole file. Returns result for text formats; for image
formats it returns a per-molecule preview list and, when there is more than one record, a
ZIP as a zip_url data URL. Limits: 64 MB input, 5,000 records per run
(500 for image output).
| Field | Type | Description |
|---|---|---|
data | string | Required. Multi-record file |
from | string | Input format id, default sdf |
to | string | Output format id, default smi |
opts | string[] | --canonical, --unique,
--deletehydrogens, --addhydrogens |
{"ok": true, "binary": false, "result": "CC(=O)Oc1ccccc1C(=O)O\n...", "converted": 250}
POST /api/v1/formula
Two modes: parse a formula string, or compute formula and weight from a structure.
| Field | Type | Description |
|---|---|---|
mode | string | formula (default) or structure |
formula | string | Used when mode is formula, e.g. C9H8O4 |
data | string | Used when mode is structure |
from | string | Input format id for structure mode |
{"ok": true, "formula": "C9H8O4", "mw": 180.159,
"composition": {"C": 9, "H": 8, "O": 4}, "atoms": 21}
POST /api/v1/bio
Sequence operations, all implemented natively in Python.
| Field | Type | Description |
|---|---|---|
op | string | Required. fasta2fastq,
fastq2fasta, revcomp, translate, stats |
data | string | Required. FASTA, FASTQ or a bare sequence |
frame | integer | Reading frame for translate, 0–2 |
{"ok": true, "result": "ATGGCC...", "count": 3}
Errors
Failures always return the same shape, with an HTTP status of 400, 422 or 429:
{"ok": false, "error": "Conversion failed", "detail": "1 molecule converted"}
| Status | Meaning |
|---|---|
400 | Bad request — missing field, unknown format, input too large |
422 | OpenBabel or OPSIN could not process the input |
429 | Rate limit or a heavy job already running; see Retry-After |
502 | Upstream name-resolution service unavailable |
Limits and fair use
- 120 requests per minute per client, 300 per minute across the whole service.
- 8 MB maximum input per request; 64 MB for
/api/v1/batch. - 5,000 records per batch run, or 500 when the output is an image
(PNG, SVG, PDF…). Requests over the limit return
400with the actual count and the maximum. - 3D conformer generation is serialised — one at a time across all users. Plan for a few seconds per molecule.
- If you need sustained bulk throughput, generate 3D conformers locally with OpenBabel or RDKit; this API is meant for interactive and small-batch use.
Attribution
The service is free to use. Chemistry is powered by OpenBabel 3.1.1 and name parsing by OPSIN; if you publish something built on this API, a link back to seqandchem.com is appreciated but not required.
Machine-readable specification: /api/openapi.json — import it into Postman, Insomnia, or any OpenAPI client generator.
Questions, bug reports or a use case the API does not cover: devin2xing@gmail.com.