Skip to content
Go to Boltz API

Predict small molecule ADME

Predict Tier-1 ADME summary properties (lipophilicity, permeability, and solubility) for a batch of small molecules by SMILES.

ADME prediction scores a batch of small molecules for Tier-1 ADME summary properties (lipophilicity, permeability, and solubility) directly from SMILES. You submit a list of molecules and get back one result object with a per-molecule summary, returned in the same order you submitted them. It runs to completion and cannot be paused or stopped.

run() submits the batch, waits for it to finish, and writes the completed prediction to a local run directory (returning its Path). Use start() + retrieve() to submit now and poll yourself, working with the prediction object in-memory.

import os
import time
from boltz_api import Boltz
client = Boltz(api_key=os.environ["BOLTZ_API_KEY"])
adme_input = {
"molecules": [
{"smiles": "CC(=O)OC1=CC=CC=C1C(=O)O", "id": "aspirin"},
{"smiles": "CC(C)Cc1ccc(cc1)C(C)C(=O)O", "id": "ibuprofen"},
],
} # see Input format for the molecule fields
# One call: submit, poll, and write the finished prediction to a local run directory.
# Returns a Path; the API response is mirrored on disk in `run.json`.
run_dir = client.predictions.adme.run(model="adme-v1", input=adme_input)
# ...or submit now and poll yourself with start() + retrieve():
prediction = client.predictions.adme.start(model="adme-v1", input=adme_input)
while prediction.status not in ("succeeded", "failed"):
time.sleep(5)
prediction = client.predictions.adme.retrieve(prediction.id)
# Read the per-molecule ADME summary from the prediction object (start() + retrieve() branch above;
# for the run() branch the same response is on disk at run_dir / "run.json"):
for m in prediction.output.molecules:
if m.status == "succeeded":
print(f"{m.external_id or m.id} logD={m.adme.lipophilicity:.2f} perm={m.adme.permeability:.2f} sol={m.adme.solubility}")
else:
print(f"{m.external_id or m.id} failed: {m.error.message}")

A prediction takes a batch of molecules to score, given by SMILES, passed as the input body. The model (adme-v1) is a separate argument. The example below is a complete, valid input.

{
  "molecules": [
    # your batch to score; each needs "smiles". optional "id" is returned as
    # "external_id" on the matching result so you can correlate back to your list
    { "smiles": "CC(=O)OC1=CC=CC=C1C(=O)O", "id": "aspirin" },
    { "smiles": "CC(C)Cc1ccc(cc1)C(C)C(=O)O", "id": "ibuprofen" },
    { "smiles": "CN1C=NC2=C1C(=O)N(C(=O)N2C)C" }
  ]
}
FieldRequiredWhat it isLink
moleculesYesThe molecules to score, given by SMILES.Molecules

molecules is the batch you want to score, given inline as an array. Send 1 to 128 molecules per request. Each entry needs a smiles string and may carry an optional id. When you provide an id, it comes back as external_id on the matching result, so you can correlate results to your input. Results are returned in the same order as this list.

A prediction returns a single object; there's no streaming page of results, and nothing to download, since ADME values are returned inline. Poll its status; output is null until the prediction succeeds, then carries a per-molecule summary. Each molecule reports status: "succeeded" with an adme summary, or status: "failed" with a non-null error (the rest of the batch still succeeds).

{
  "id": "adme_pred_8f3a2b",
  "status": "succeeded", # pending | running | succeeded | failed
  "model": "adme-v1",
  "version": "1.0.0", # model version used for this prediction
  "error": None, # { code, message } once status is "failed"
  "output": { # null until status is "succeeded"
    "molecules": [
      # one entry per input molecule, in the same order you submitted them
      {
        "id": "adme_mol_001", # internally generated molecule ID
        "external_id": "aspirin", # the "id" you supplied, if any
        "smiles": "CC(=O)OC1=CC=CC=C1C(=O)O", # echoed from the request
        "status": "succeeded", # succeeded | failed
        "adme": { # Tier-1 ADME summary (null when this molecule failed)
          "lipophilicity": 1.2, # LogD-based lipophilicity score
          "permeability": 0.61, # permeability score
          "solubility": "medium-confidence" # high-confidence | medium-confidence | high-risk
        },
        "error": None
      },
      {
        "id": "adme_mol_003",
        "smiles": "not-a-valid-smiles",
        "status": "failed", # this molecule errored; "adme" is null
        "adme": None,
        "error": { "code": "invalid_smiles", "message": "Could not parse SMILES" }
      }
    ]
  },
  "livemode": True, # false for predictions created with a test key
  "workspace_id": "ws_3a2b",
  "created_at": "2026-02-25T12:00:00Z",
  "started_at": "2026-02-25T12:00:05Z",
  "completed_at": "2026-02-25T12:00:20Z",
  "expires_at": "2026-03-04T12:00:20Z", # when this resource and its data are deleted
  "data_deleted_at": None # set once the data is deleted
  # "input" echoes the request you submitted (null after data deletion)
}
PropertyRange / valuesWhat it measures
lipophilicitynumberLipophilicity from the internal LogD prediction; higher is more lipophilic.
permeabilitynumberPermeability score for the molecule.
solubilityhigh-confidence · medium-confidence · high-riskFlag for triage based on predicted aqueous solubility. high-confidence compounds are likely to be highly soluble with LogS >= -4. high-confidence and medium-confidence compounds are likely to be at least partially soluble with LogS >= -5. The high-risk bin is intended to capture most insoluble compounds with LogS < -5.
StatusMeaning
pendingThe prediction is queued and has not started yet.
runningThe prediction is currently being computed.
succeededThe prediction finished. Read output.molecules; individual molecules may still report status: "failed".
failedThe whole prediction errored. Check the error field.