Design proteins
Generate novel protein binders against a target, monitor progress, fetch results, and stop early if needed.
Protein design generates novel protein binders optimized for binding confidence and structure confidence. Results stream in as they’re generated — you can fetch them before the run finishes and stop early.
Results and artifacts
Section titled “Results and artifacts”Design runs generate protein results over time. As soon as a protein is computed, you can read and download the result without waiting for the full design run to finish.
Each generated protein result includes scoring metrics such as binding confidence, structure confidence, and interaction PAE. Each result also includes downloadable artifacts for the predicted bound structure and PAE.
Define a target
Section titled “Define a target”There are two ways to define the target.
Structure template target
Provide a CIF file and select which chains and residues to include. The file can be provided as a URL or base64-encoded content. Each chain gets a crop_residues field (an array of 0-indexed residue indices, or "all" to keep the entire chain). You can optionally specify epitope_residues (residues the binder should contact) and flexible_residues (residues allowed to move during design).
{ "target": { "type": "structure_template", "structure": { "type": "base64", "media_type": "chemical/x-cif", "data": "ZGF0YV90YXJnZXQK..." }, "chain_selection": { "A": { "chain_type": "polymer", "crop_residues": "all", "epitope_residues": [45, 46, 47, 48, 49], "flexible_residues": [44, 50] }, "B": { "chain_type": "polymer", "crop_residues": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] } } }}No-template target
Define the target from an entity list when you don’t have a structure file. Optionally add epitope_residues (keyed by chain ID), constraints, and bonds.
{ "target": { "type": "no_template", "entities": [ { "type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"] } ], "epitope_residues": { "A": [45, 46, 47, 48, 49] } }}Specify the binder
Section titled “Specify the binder”The binder specification is independent of the target type — you can combine either target mode with either binder mode.
Structure template binder
Section titled “Structure template binder”Provide a CIF file with the binder scaffold. For each chain, define crop_residues and design_motifs — the regions to redesign. There are two motif types:
- Replacement: Replace residues from
start_indextoend_index(inclusive, 0-indexed) with a designed region ofdesign_length_range{min, max}. - Insertion: Insert a designed region after
after_residue_indexwith adesign_length_range{min, max}. Use-1to insert at the beginning.
Set the modality to peptide, antibody, nanobody, or custom_protein. Optionally exclude specific amino acids via rules.excluded_amino_acids.
{ "binder_specification": { "type": "structure_template", "modality": "nanobody", "structure": { "type": "base64", "media_type": "chemical/x-cif", "data": "ZGF0YV9iaW5kZXIK..." }, "chain_selection": { "B": { "chain_type": "polymer", "crop_residues": "all", "design_motifs": [ { "type": "replacement", "start_index": 26, "end_index": 32, "design_length_range": { "min": 5, "max": 15 } }, { "type": "insertion", "after_residue_index": 50, "design_length_range": { "min": 3, "max": 8 } } ] } }, "rules": { "excluded_amino_acids": ["C", "M"] } }}No-template binder
Section titled “No-template binder”Define the binder from entities when you don’t have a scaffold file. At least one entity must be a designed_protein — use a sequence pattern where uppercase letters are fixed residues and numbers (or ranges like 5..10) represent designed regions of that length.
Examples:
"MKTAYI5..10VKSHFSRQ"— fixedMKTAYI, then 5–10 designed residues, then fixedVKSHFSRQ"20"— 20 fully designed residues"ACDE8GHI"— fixedACDE, 8 designed residues, fixedGHI
You can include additional fixed entities (protein, RNA, DNA, ligand) in the binder. Same modality and rules options apply.
{ "binder_specification": { "type": "no_template", "modality": "custom_protein", "entities": [ { "type": "designed_protein", "chain_ids": ["B"], "value": "MKTAYI10..20VKSHFSRQ" } ], "rules": { "excluded_amino_acids": ["C"] } }}Run a design and download results
Section titled “Run a design and download results”run_protein_design() submits the design run, waits for generated binders, downloads result archives, and returns a local run directory.
import osfrom boltz_api import Boltz
client = Boltz(api_key=os.environ["BOLTZ_API_KEY"])
run_dir = client.experiments.run_protein_design( target={ "type": "no_template", "entities": [ {"type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"]}, ], "epitope_residues": {"A": [10, 11, 12]}, }, binder_specification={ "type": "no_template", "modality": "custom_protein", "entities": [ {"type": "designed_protein", "chain_ids": ["B"], "value": "10..20"}, ], }, num_proteins=10, name="protein-design-hotspots",)print(run_dir)The run directory contains the sanitized run record, resumable download state, a result manifest, and downloaded files for each designed binder:
boltz-experiments/protein-design-hotspots/ .boltz-run.json run.json results/ index.jsonl prot_des_result_.../ metadata.json archive.tar.gz files/ result/ metrics.json predicted_structure.cif pae.npzRun a design and download results
Section titled “Run a design and download results”The CLI starts the remote run, then download-results waits, resumes if interrupted, and writes results under boltz-experiments/protein-design-hotspots/.
Save your inputs to protein-design.yaml:
target: type: no_template entities: - type: protein value: MKTIIALSYIFCLVFA chain_ids: ["A"]binder_specification: type: no_template modality: custom_protein entities: - type: designed_protein chain_ids: ["B"] value: 10..20num_proteins: 10Then start the run and download:
RUN_ID=$( boltz-api --format raw protein:design start \ --input @yaml://./protein-design.yaml | jq -r '.id')
run_dir=$(boltz-api download-results --id "$RUN_ID" --name protein-design-hotspots)echo "$run_dir"Use --input @json://./protein-design.json if your input file is JSON.
The run directory contains the sanitized run record, resumable download state, a result manifest, and downloaded files for each designed binder:
boltz-experiments/protein-design-hotspots/ .boltz-run.json run.json results/ index.jsonl prot_des_result_.../ metadata.json archive.tar.gz files/ result/ metrics.json predicted_structure.cif pae.npzStart a design run
Section titled “Start a design run”Structure template
import osfrom boltz_api import Boltz
client = Boltz(api_key=os.environ["BOLTZ_API_KEY"])
design = client.protein.design.start( target={ "type": "structure_template", "structure": { "type": "base64", "media_type": "chemical/x-cif", "data": target_cif_b64, }, "chain_selection": { "A": { "chain_type": "polymer", "crop_residues": "all", "epitope_residues": [45, 46, 47, 48, 49], }, }, }, binder_specification={ "type": "structure_template", "modality": "nanobody", "structure": { "type": "base64", "media_type": "chemical/x-cif", "data": binder_cif_b64, }, "chain_selection": { "B": { "chain_type": "polymer", "crop_residues": "all", "design_motifs": [ { "type": "replacement", "start_index": 26, "end_index": 32, "design_length_range": {"min": 5, "max": 15}, }, ], }, }, }, num_proteins=10,)print(f"Design run ID: {design.id}, Status: {design.status}")No template
import osfrom boltz_api import Boltz
client = Boltz(api_key=os.environ["BOLTZ_API_KEY"])
design = client.protein.design.start( target={ "type": "no_template", "entities": [ {"type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"]}, ], }, binder_specification={ "type": "no_template", "modality": "custom_protein", "entities": [ {"type": "designed_protein", "chain_ids": ["B"], "value": "10..20"}, ], }, num_proteins=10,)print(f"Design run ID: {design.id}, Status: {design.status}")Start a design run
Section titled “Start a design run”import Boltz from "boltz-api";
const apiKey = process.env["BOLTZ_API_KEY"];
const client = new Boltz({ apiKey });
let design = await client.protein.design.start({ target: { type: "no_template", entities: [ { type: "protein", value: "MKTIIALSYIFCLVFA", chain_ids: ["A"] }, ], }, binder_specification: { type: "no_template", modality: "custom_protein", entities: [ { type: "designed_protein", chain_ids: ["B"], value: "10..20" }, ], }, num_proteins: 10,});console.log(`Design run ID: ${design.id}, Status: ${design.status}`);Run a design and download results
Section titled “Run a design and download results”Ask the agent to save the payload to protein-design.yaml, estimate cost, then submit with a stable idempotency key.
target: type: no_template entities: - type: protein value: MKTIIALSYIFCLVFA chain_ids: ["A"]binder_specification: type: no_template modality: custom_protein entities: - type: designed_protein chain_ids: ["B"] value: 10..20num_proteins: 10boltz-api protein:design estimate-cost \ --input @yaml://./protein-design.yaml
RUN_ID=$( boltz-api protein:design start \ --idempotency-key "protein-design-hotspots" \ --input @yaml://./protein-design.yaml \ --raw-output --transform id)
boltz-api download-results \ --id "$RUN_ID" \ --name "protein-design-hotspots" \ --root-dir "./boltz-experiments" \ --poll-interval-seconds 10Start now, download later
Section titled “Start now, download later”The main run_protein_design() example already waits and downloads. To submit now and download later, use start_protein_design() and resume with wait_and_download().
run_dir = client.experiments.start_protein_design( target={ "type": "no_template", "entities": [ {"type": "protein", "value": "MKTIIALSYIFCLVFA", "chain_ids": ["A"]}, ], "epitope_residues": {"A": [10, 11, 12]}, }, binder_specification={ "type": "no_template", "modality": "custom_protein", "entities": [ {"type": "designed_protein", "chain_ids": ["B"], "value": "10..20"}, ], }, num_proteins=10, name="submit-now-finish-later",)
client.experiments.wait_and_download(run_dir=run_dir)Resume downloads
Section titled “Resume downloads”download-results is the progress monitor and downloader. It can be rerun with the same name to resume from local checkpoint state.
boltz-api download-results --name protein-design-hotspotsboltz-api --format json download-status --name protein-design-hotspotsMonitor progress
Section titled “Monitor progress”import time
while design.status not in ("succeeded", "failed", "stopped"): time.sleep(10) design = client.protein.design.retrieve(design.id) progress = design.progress print( f"Status: {design.status}, Generated: {progress.num_proteins_generated}/{progress.total_proteins_to_generate}" )Monitor progress
Section titled “Monitor progress”while (!["succeeded", "failed", "stopped"].includes(design.status)) { await new Promise((r) => setTimeout(r, 10000)); design = await client.protein.design.retrieve(design.id); const progress = design.progress; console.log( `Status: ${design.status}, Generated: ${progress.num_proteins_generated}/${progress.total_proteins_to_generate}`, );}Resume downloads
Section titled “Resume downloads”Agents can rerun download-results with the same name and root directory to resume from local checkpoint state.
boltz-api download-results \ --name "protein-design-hotspots" \ --root-dir "./boltz-experiments" \ --poll-interval-seconds 10
boltz-api --format json download-status \ --name "protein-design-hotspots" \ --root-dir "./boltz-experiments"Inspect downloaded results
Section titled “Inspect downloaded results”Result pages and artifact archives are already downloaded into the run directory.
print(run_dir)for result_dir in (run_dir / "results").iterdir(): print(result_dir)Inspect downloaded results
Section titled “Inspect downloaded results”Result pages and artifact archives are already downloaded into the run directory.
ls boltz-experiments/protein-design-hotspots/resultsFetch paginated results
Section titled “Fetch paginated results”for result in client.protein.design.list_results(design.id): print(f"Result {result.id}:") print(f" Binding confidence: {result.metrics.binding_confidence}") print(f" Structure confidence: {result.metrics.structure_confidence}") print(f" Min interaction PAE: {result.metrics.min_interaction_pae}") print(f" Archive URL: {result.artifacts.archive.url}")Fetch paginated results
Section titled “Fetch paginated results”for await (const result of client.protein.design.listResults(design.id)) { console.log(`Result ${result.id}:`); console.log(` Binding confidence: ${result.metrics.binding_confidence}`); console.log(` Structure confidence: ${result.metrics.structure_confidence}`); console.log(` Min interaction PAE: ${result.metrics.min_interaction_pae}`); console.log(` Archive URL: ${result.artifacts.archive.url}`);}Inspect downloaded results
Section titled “Inspect downloaded results”Use the local result manifest and downloaded artifact directories after download-results completes or while it is resuming.
ls ./boltz-experiments/protein-design-hotspots/resultshead -n 5 ./boltz-experiments/protein-design-hotspots/results/index.jsonlStop early
Section titled “Stop early”client.experiments.stop(run_dir=run_dir)boltz-api protein:design stop --id "$RUN_ID"client.protein.design.stop(design.id)await client.protein.design.stop(design.id);boltz-api protein:design stop --id "<run-id-from-start>"Metrics
Section titled “Metrics”| Metric | Range | What it measures |
|---|---|---|
binding_confidence | 0–1 | Confidence that binding occurs. |
structure_confidence | 0–1 | Overall confidence in the predicted structure. |
iptm | 0–1 | Interface predicted TM-score. |
min_interaction_pae | Angstroms | Minimum predicted aligned error at the interface. Lower is better. |
helix_fraction | 0–1 | Fraction of designed residues in helices. |
sheet_fraction | 0–1 | Fraction of designed residues in sheets. |
loop_fraction | 0–1 | Fraction of designed residues in loops. |
Status values
Section titled “Status values”| Status | Meaning |
|---|---|
pending | The run is queued and has not started yet. |
running | The run is actively generating protein binders. Results may already be available. |
succeeded | The run completed all requested proteins. |
failed | The run encountered an error. Check the error field. |
stopped | The run was stopped early. Partial results are available. |