---
title: Predict structure and binding | Boltz API Docs
description: Submit a prediction job, poll for completion, and download the results.
---

Predictions are single-input, single-output operations. They run to completion and cannot be paused or resumed. Use predictions when you have your own design models and want access to Boltz property predictors, or when integrating Boltz predictions into your own platform.

Each prediction application has its own endpoint with application-specific inputs and outputs. Currently available:

- **Structure and binding** — Predict 3D structure coordinates, per-residue confidence scores, and binding metrics for a molecular complex.

## Predict structure and binding

You can request multiple structure samples by setting `num_samples` in Scientist and Agent input files, or `input.num_samples` in the generated SDKs. Each sample produces an independent structure prediction with its own confidence metrics.

- [Scientist Python](#tab-panel-15)
- [Scientist CLI](#tab-panel-16)
- [Platform Developer Python](#tab-panel-17)
- [Platform Developer Typescript](#tab-panel-18)
- [Agent CLI](#tab-panel-19)

### Submit, wait, and download

`run_structure_and_binding()` submits the prediction, waits for it to finish, downloads the result archive, and returns the local run directory.

```
import os
from boltz_api import Boltz


client = Boltz(api_key=os.environ["BOLTZ_API_KEY"])


run_dir = client.experiments.run_structure_and_binding(
    entities=[
        {"type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"]},
        {
            "type": "ligand_smiles",
            "value": "CC(=O)OC1=CC=CC=C1C(=O)O",
            "chain_ids": ["B"],
        },
    ],
    model="boltz-2.1",
    binding={
        "type": "ligand_protein_binding",
        "binder_chain_id": "B",
    },
    name="structure-and-binding-check",
)
print(run_dir)
```

### Submit now and resume later

Use `start_structure_and_binding()` when you want to persist the run directory without blocking. `wait_and_download()` resumes from that local directory or name.

```
run_dir = client.experiments.start_structure_and_binding(
    entities=[
        {"type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"]},
        {
            "type": "ligand_smiles",
            "value": "CC(=O)OC1=CC=CC=C1C(=O)O",
            "chain_ids": ["B"],
        },
    ],
    model="boltz-2.1",
    binding={"type": "ligand_protein_binding", "binder_chain_id": "B"},
    num_samples=3,
    name="structure-and-binding-check",
)


client.experiments.wait_and_download(name="structure-and-binding-check")
```

Downloaded files are under the returned run directory.

```
print(run_dir / "outputs" / "files")
```

### Submit, wait, and download

`download-results` polls the remote prediction and creates or resumes a local directory under `boltz-experiments/`.

Save your inputs to `structure-input.yaml`:

```
entities:
  - type: protein
    value: MKTIIALSYIFCLVFA
    chain_ids: ["A"]
  - type: ligand_smiles
    value: CC(=O)OC1=CC=CC=C1C(=O)O
    chain_ids: ["B"]
num_samples: 3
binding:
  type: ligand_protein_binding
  binder_chain_id: B
```

Then submit and download:

Terminal window

```
PREDICTION_ID=$(
  boltz-api --format raw predictions:structure-and-binding start \
    --model boltz-2.1 \
    --input @yaml://./structure-input.yaml |
    jq -r '.id'
)


boltz-api download-results --id "$PREDICTION_ID" --name structure-and-binding-check
```

Use `--input @json://./structure-input.json` if your input file is JSON.

### Resume later

Terminal window

```
boltz-api download-results --name structure-and-binding-check
boltz-api --format json download-status --name structure-and-binding-check
```

### Start

```
import os
from boltz_api import Boltz


client = Boltz(api_key=os.environ["BOLTZ_API_KEY"])


prediction = client.predictions.structure_and_binding.start(
    model="boltz-2.1",
    input={
        "entities": [
            {"type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"]},
            {
                "type": "ligand_smiles",
                "value": "CC(=O)OC1=CC=CC=C1C(=O)O",
                "chain_ids": ["B"],
            },
        ],
        "num_samples": 3,
        "binding": {
            "type": "ligand_protein_binding",
            "binder_chain_id": "B",
        },
    },
)
print(f"Prediction ID: {prediction.id}, Status: {prediction.status}")
```

### Poll

```
import time


while prediction.status not in ("succeeded", "failed"):
    time.sleep(5)
    prediction = client.predictions.structure_and_binding.retrieve(prediction.id)
    print(f"Status: {prediction.status}")
```

### Read download URLs

```
if prediction.status == "succeeded":
    for sample in prediction.output.all_sample_results:
        print(f"Structure confidence: {sample.metrics.structure_confidence}")
        print(
            f"Binding confidence: {prediction.output.binding_metrics.binding_confidence}"
        )
        print(f"Download URL: {sample.structure.url}")
```

### Start

```
import Boltz from "boltz-api";


const apiKey = process.env["BOLTZ_API_KEY"];


const client = new Boltz({ apiKey });


let prediction = await client.predictions.structureAndBinding.start({
  model: "boltz-2.1",
  input: {
    entities: [
      { type: "protein", value: "MKTIIALSYIFCLVFA", chain_ids: ["A"] },
      {
        type: "ligand_smiles",
        value: "CC(=O)OC1=CC=CC=C1C(=O)O",
        chain_ids: ["B"],
      },
    ],
    num_samples: 3,
    binding: {
      type: "ligand_protein_binding",
      binder_chain_id: "B",
    },
  },
});
console.log(`Prediction ID: ${prediction.id}, Status: ${prediction.status}`);
```

### Poll

```
while (prediction.status !== "succeeded" && prediction.status !== "failed") {
  await new Promise((r) => setTimeout(r, 5000));
  prediction = await client.predictions.structureAndBinding.retrieve(
    prediction.id,
  );
  console.log(`Status: ${prediction.status}`);
}
```

### Read download URLs

```
if (prediction.status === "succeeded") {
  for (const sample of prediction.output.all_sample_results) {
    console.log(`Structure confidence: ${sample.metrics.structure_confidence}`);
    console.log(
      `Binding confidence: ${prediction.output.binding_metrics.binding_confidence}`,
    );
    console.log(`Download URL: ${sample.structure.url}`);
  }
}
```

### Write an input file

Agent integrations work best when the agent writes a payload file, estimates cost, submits with a stable idempotency key, then downloads with the same run name.

Save your inputs to `structure-input.yaml`:

```
entities:
  - type: protein
    value: MKTIIALSYIFCLVFA
    chain_ids: ["A"]
  - type: ligand_smiles
    value: CC(=O)OC1=CC=CC=C1C(=O)O
    chain_ids: ["B"]
num_samples: 3
binding:
  type: ligand_protein_binding
  binder_chain_id: B
```

### Estimate cost

Terminal window

```
boltz-api predictions:structure-and-binding estimate-cost \
  --model boltz-2.1 \
  --input @yaml://./structure-input.yaml
```

### Submit

Terminal window

```
boltz-api predictions:structure-and-binding start \
  --model boltz-2.1 \
  --idempotency-key "structure-and-binding-check" \
  --input @yaml://./structure-input.yaml \
  --raw-output --transform id
```

### Download

Copy the printed prediction ID into `download-results`. In Claude Code, Codex, or another agent runtime, run this through the managed long-running/background command mode when available.

Terminal window

```
boltz-api download-results \
  --id "<prediction-id-from-start>" \
  --name "structure-and-binding-check" \
  --root-dir "./boltz-experiments" \
  --poll-interval-seconds 10
```

Download URLs expire. Check the `url_expires_at` field and download promptly. See [Data Retention](/docs/guides/data-retention/index.md) for details.

## Status values

| Status      | Meaning                                                       |
| ----------- | ------------------------------------------------------------- |
| `pending`   | The prediction is queued and has not started yet.             |
| `running`   | The prediction is currently being computed.                   |
| `succeeded` | The prediction completed successfully. Results are available. |
| `failed`    | The prediction encountered an error. Check the `error` field. |
