Fold
Structure prediction on Fastfold—models, artifacts, and SDK recipes from minimal submit to YAML and Boltz-2.
Fold is Fastfold’s structure prediction path: you submit sequences and, where the model allows, additional chains, ligands, nucleic acids, or constraints. The job returns mmCIF/PDB, confidence metrics (pLDDT, PAE, pTM/ipTM when emitted), and plot URLs you can use in a structure viewer or hand off to workflows (for example MD, protein design, or structure Q&A). Each model is backed by a published container on Docker Hub; POST /v1/jobs and GET /v1/jobs/{job_id}/results are the same whether you use this page’s Python examples, the CLI, or raw HTTP.
- API
- Fold jobs —
POST /v1/jobs,GET /v1/jobs/{jobId}/results - CLI
fastfold-cli fold,fastfold-cli jobs— SDK CLI- Cloud
cloud.fastfold.ai/fold/new — create fold jobs in the Fastfold web app (presets, constraints, ligands)
- Docker Hub
- hub.docker.com/u/fastfold — container image per
modelNameand deployment settings (Boltz-2, OpenFold 3, ColabFold, etc.)
Models
Fold jobs set params.modelName (Python/YAML model) to one of the values below. Runtime images are published on Docker Hub — Fastfold; tags are deployment-specific (often :latest or a pinned version).
| Family | API model | Docker Hub |
|---|---|---|
| AlphaFold2 (ColabFold) | monomer, multimer | fastfold/colabfold |
| OpenFold (ESM-1b) | esm1b | fastfold/openfold |
| Boltz-1 | boltz | fastfold/boltz-1 |
| Boltz-2 | boltz-2 | fastfold/boltz-2 |
| OpenFold 3 | openfold3 | fastfold/openfold-3 |
| Chai-1 | chai1 | fastfold/chai-1 |
| IntelliFold | intellifold | fastfold/intellifold |
| SimpleFold | see family models below | fastfold/simple-fold |
SimpleFold family models
Same payload shape across variants; only the model string changes. Supported sizes:
simplefold_100Msimplefold_360Msimplefold_700Msimplefold_1.1Bsimplefold_1.6Bsimplefold_3B
Note: The Examples section includes at least one recipe per family above.
Metrics and Artifacts
Read completed fold outputs with GET /v1/jobs/<job_id>/results.
The response includes job, parameters, sequences[], optional top-level predictionPayload for complexes, and optional constraints. Each sequence row uses predictionPayload, which matches the backend PredictionPayload shape:
| Field | Type | Role |
|---|---|---|
predictionStatus | enum | Prediction lifecycle status |
jobRunStatus | enum | Run lifecycle status |
msaStatus | enum | MSA lifecycle status |
prediction | bool | null | Whether a prediction artifact exists |
error | string | null | Error message when failed |
meanPLLDT | float | null | Mean pLDDT |
executionTimeInMinutes | float | null | Wall time (minutes) |
pdb_url | string | null | PDB artifact URL |
cif_url | string | null | mmCIF artifact URL |
msa_coverage_plot_url | string | null | MSA coverage plot |
pae_plot_url | string | null | PAE plot |
plddt_plot_url | string | null | pLDDT plot |
metrics_json_url | string | null | Extended metrics JSON |
config_json_url | string | null | Run config JSON |
citations_bibtex_url | string | null | Citations (BibTeX) |
plots_url | string | null | Plots bundle |
ptm_score | float | null | pTM-style score (when the model emits it) |
iptm_score | float | null | ipTM (complexes when the model emits it) |
max_pae_score | float | null | Max PAE summary |
seed | string | null | Seed identifier |
execution_time_in_minutes | float | null | Duplicate wall time field (legacy naming) |
affinity_result_raw_json | object | null | Raw affinity payload (e.g. Boltz affinity runs) |
Which URLs and scores are present depends on modelName and run state.
SDK
from fastfold import Client
client = Client()
results = client.jobs.wait_for_completion(job.id, poll_interval=5.0, timeout=900.0)
print(results.cif_url())
print(results.metrics().mean_PLDDT)
# Full payload: results.rawYou can also call client.jobs.get_results(job_id) if you already know the job finished.
CLI
fastfold-cli jobs results <job_id>
fastfold-cli jobs results <job_id> --jsonMinimal fold job
from fastfold import Client
client = Client()
job = client.fold.create(
sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES",
model="boltz-2",
is_public=True,
)
results = client.jobs.wait_for_completion(job.id, poll_interval=5.0, timeout=900.0)
print("Job:", job.id)
print("Status:", results.job.status)
print("CIF:", results.cif_url())
print("mean_PLDDT:", results.metrics().mean_PLDDT)Examples
ESM-1b single-chain fold
Fold one protein chain with esm1b using the short form: pass a single sequence string (here a myoglobin-length sequence) plus an optional name—no sequences array.
from fastfold import Client
client = Client()
job = client.fold.create(
model="esm1b",
sequence="MGLSDGEWQLVLNVWGKVEADIPGHGQEVLIRLFKGHPETLERFDKFKHLKSEDEMKASEDLKKHGATVLTALGGILKKKGHHEAEIKPLAQSHATKHKIPVKYLEFISECIIQVLQSKHPGDFGADAQRAMNKALELFRKDMASNYKELGFQG",
name="ESM1b OpenFold",
)
print(job.id)AlphaFold2 monomer
Predict one protein chain with monomer (AlphaFold2 / ColabFold path): same short sequence-only payload as ESM-1b, different model.
from fastfold import Client
client = Client()
job = client.fold.create(
model="monomer",
sequence="MGLSDGEWQLVLNVWGKVEADIPGHGQEVLIRLFKGHPETLERFDKFKHLKSEDEMKASEDLKKHGATVLTALGGILKKKGHHEAEIKPLAQSHATKHKIPVKYLEFISECIIQVLQSKHPGDFGADAQRAMNKALELFRKDMASNYKELGFQG",
name="Monomer AlphaFold2",
)
print(job.id)AlphaFold2 multimer
Model a two-chain protein complex with multimer: sequences holds two proteinChain objects with chain_id A and B and their amino-acid strings.
from fastfold import Client
client = Client()
job = client.fold.create(
model="multimer",
name="Multimer AlphaFold2",
sequences=[
{
"proteinChain": {
"sequence": "MCNTNMSVSTEGAASTSQIPASEQETLVRPKPLLLKLLKSVGAQNDTYTMKEIIFYIGQYIMTKRLYDEKQQHIVYCSNDLLGDVFGVPSFSVKEHRKIYAMIYRNLVAV",
"chain_id": "A",
}
},
{
"proteinChain": {
"sequence": "SQETFSGLWKLLPPE",
"chain_id": "B",
}
},
],
)
print(job.id)Boltz protein-DNA complex
Run Boltz-1 with model="boltz" on a protein + DNA assembly: one proteinChain (A) plus two complementary dnaSequence chains (B / C) that form the duplex.
from fastfold import Client
client = Client()
job = client.fold.create(
model="boltz",
name="Boltz Protein DNA Complex",
sequences=[
{
"proteinChain": {
"sequence": "MASSRRESINPWILTGFADAEGSFGLSILNRNRGTARYHTRLSFTIMLHNKDKSILENIQSTWKVGSILNNGDHYVSLVVYRFEDLKVIIDHFEKYPLITQKLGDYKLFKQAFSVMENKEHLKENGIKELVRIKAKMNWGLNDELKKAFPENISKERPLINKNIPNFKWLAGFTSGDGSFFVRLRKSNVNARVRVQLVFEISQHIRDKNLMNSLITYLGCGHIYEGNKSERSWLQFRVEKFSDINDKIIPVFQENTLIGVKLEDFEDWCKVAKLIEEKKHLTESGLDEIKKIKLNMNKGR",
"chain_id": "A",
}
},
{"dnaSequence": {"sequence": "GGGGGCATGCAGATCCCACAGGCGCG", "chain_id": "B"}},
{"dnaSequence": {"sequence": "CCGCGCCTGTGGGATCTGCATGCCCC", "chain_id": "C"}},
],
)
print(job.id)SimpleFold family
Fold a long single-chain protein with simplefold_100M. The call shape is the same for other sizes—swap model to simplefold_360M, simplefold_700M, simplefold_1.1B, simplefold_1.6B, or simplefold_3B.
from fastfold import Client
client = Client()
job = client.fold.create(
model="simplefold_100M",
sequence="GASKLRAVLEKLKLSRDDISTAAGMVKGVVDHLLLRLKCDSAFRGVGLLNTGSYYEHVKISAPNEFDVMFKLEVPRIQLEEYSNTRAYYFVKFKRNPKENPLSQFLEGEILSASKMLSKFRKIIKEEINDDTDVIMKRKRGGSPAVTLLISEKISVDITLALESKSSWPASTQEGLRIQNWLSAKVRKQLRLKPFYLVPKHAEETWRLSFSHIEKEILNNHGKSKTCCENKEEKCCRKDCLKLMKYLLEQLKERFKDKKHLDKFSSYHVKTAFFHVCTQNPQDSQWDRKDLGLCFDNCVTYFLQCLRTEKLENYFIPEFNLFSSNLIDKRSKEFLTKQIEYERNNEFPVFD",
name="SimpleFold 100M",
)
print(job.id)OpenFold 3 with ligand
Build an OpenFold 3 heteromer: a protein chain (A, truncated sequence in the snippet) plus a small-molecule ligand as CCD ATP on chain B (is_ccd: True). params sets diffusionSample and numModelSeeds; the code waits on the job and prints a CIF URL.
from fastfold import Client
client = Client()
job = client.fold.create(
model="openfold3",
sequences=[
{"proteinChain": {"sequence": "MTEYKLVVVGACGVGKSALTIQLIQNHF...", "chain_id": "A"}},
{"ligandSequence": {"sequence": "ATP", "is_ccd": True, "chain_id": "B"}},
],
params={"modelName": "openfold3", "diffusionSample": 5, "numModelSeeds": 1},
)
print(client.jobs.wait_for_completion(job.id).cif_url())Chai-1 Trimer 7SYZ with restraints
Fold a three-protein complex with chai1 (chains A, B, C) and steer the packing with constraints.contact: two entries that enforce maximum distance (Å) between pairs of residues on different chains (chainA / res_idxA vs chainB / res_idxB).
from fastfold import Client
client = Client()
job = client.fold.create(
model="chai1",
name="Chai-1 Trimer 7SYZ with restraints",
sequences=[
{"proteinChain": {"sequence": "MMADSKLVSLNNNLSGKIKDQGKVIKNYYGTMDIKKINDGLLDSKILGAFNTVIALLGSIIIIVMNIMIIQNYTRTTDNQALIKESLQSVQQQIKALTDKIGTEIGPKVSLIDTSSTITIPANIGLLGSKISQSTSSINENVNDKCKFTLPPLKIHECNISCPNPLPFREYRPISQGVSDLVGLPNQICLQKTTSTILKPRLISYTLPINTREGVCITDPLLAVDNGFFAYSHLEKIGSCTRGIAKQRIIGVGEVLDRGDKVPSMFMTNVWTPPNPSTIHHCSSTYHEDFYYTLCAVSHVGDPILNSTSWTESLSLIRLAVRPKSDSGDYNQKYIAITKVERGKYDKVMPYGPSGIKQGDTLYFPAVGFLPRTEFQYNDSNCPIIHCKYSKAENCRLSMGVNSKSHYILRSGLLKYNLSLGGDIILQFIEIADNRLTIGSPSKIYNSLGQPVFYQASYSWDTMIKLGDVDTVDPLRVQWRNNSVISRPGQSQCPRFNVCPEVCWEGTYNDAFLIDRLNWVSAGVYLNSNQTAENPVFAVFKDNEILYQVPLAEDDTNAQKTITDCFLLENVIWCISLVEIYDTGDSVIRPKLFAVKIPAQCSES", "chain_id": "A"}},
{"proteinChain": {"sequence": "QIQLVQSGPELKKPGETVKISCTTSGYTFTNYGLNWVKQAPGKGFKWMAWINTYTGEPTYADDFKGRFAFSLETSASTTYLQINNLKNEDMSTYFCARSGYYDGLKAMDYWGQGTSVTVSSAKTTPPSVYPLAPGSAAQTNSMVTLGCLVKGYFPEPVTVTWNSGSLSSGVHTFPAVLQSDLYTLSSSVTVPSSTWPSETVTCNVAHPASSTKVDKKIVPRDC", "chain_id": "B"}},
{"proteinChain": {"sequence": "DVLMIQTPLSLPVSLGDQASISCRSSQSLIHINGNTYLEWYLQKPGQSPKLLIYKVSNRFSGVPDRFSGSGSGTDFTLKISRVEAEDLGVYYCFQGSHVPFTFGAGTKLELKRADAAPTVSIFPPSSEQLTSGGASVVCFLNNFYPKDINVKWKIDGSERQNGVLNSWTDQDSKDSTYSMSSTLTLTKDEYERHNSYTCEATHKTSTSPIVKSFNRNECVY", "chain_id": "C"}},
],
constraints={
"contact": [
{"chainA": "A", "res_idxA": 387, "chainB": "B", "res_idxB": 101, "distance": 5},
{"chainA": "C", "res_idxA": 32, "chainB": "A", "res_idxB": 483, "distance": 5},
]
},
)
print(job.id)DNA with non-canonical residues
Submit a DNA-only structure with openfold3: one chain (chain_id A) whose sequence includes a nonstandard base (U in the string), plus explicit modifications entries that map residue indices to CCD chem-comp ids—in this case pseudouridine (PSU) at position 3 and 5-methylcytosine (5MC) at position 4.
from fastfold import Client
client = Client()
job = client.fold.create(
model="openfold3",
name="DNA with Non-Canonical Residues",
sequences=[
{
"dnaSequence": {
"sequence": "ATUCGTATTCGAT",
"chain_id": "A",
"modifications": [
{"res_idx": 3, "ccd": "PSU"},
{"res_idx": 4, "ccd": "5MC"},
],
}
}
],
)
print(job.id)IntelliFold protein-ion complex
Run intellifold on a protein + ligand layout: a long proteinChain (A) paired with a calcium ion as CCD CA on B. params tunes recyclingSteps, samplingSteps, diffusionSample, and modelName for the IntelliFold runtime.
from fastfold import Client
client = Client()
job = client.fold.create(
model="intellifold",
name="Protein Calcium Complex",
sequences=[
{
"proteinChain": {
"sequence": "TPTPTIQEDGSPALIAKRASVTESCNIGYASTNGGTTGGKGGATTTVSTLAQFTKAAESSGKLNIVVKGKISGGAKVRVQSDKTIIGQKGSELVGTGLYINKVKNVIVRNMKISKVKDSNGDAIGIQASKNVWVDHCDLSSDLKSGKDYYDGLLDITHGSDWVTVSNTFLHDHFKASLIGHTDSNAKEDKGKLHVTYANNYWYNVNSRNPSVRFGTVHIYNNYYLEVGSSAVNTRMGAQVRVESTVFDKSTKNGIISVDSKEKGYATVGDISWGSSTNTAPKGTLGSSNIPYSYNLYGKNNVKARVYGTAGQTLGFAAASFLEQKLISEEDLNSAVDHHHHHH",
"chain_id": "A",
}
},
{"ligandSequence": {"sequence": "CA", "is_ccd": True, "chain_id": "B"}},
],
params={"modelName": "intellifold", "recyclingSteps": 3, "samplingSteps": 200, "diffusionSample": 1},
)
print(job.id)Streptococcal protein G with pocket
Predict Boltz-2 binding geometry for a short protein (A) and ATP (B, CCD) using a pocket constraint: the ligand binder is chain B, and contacts pin it near protein residues 12, 15, and 18 on A.
from fastfold import Client
client = Client()
job = client.fold.create(
model="boltz-2",
name="Streptococcal protein G with Pocket",
sequences=[
{"proteinChain": {"sequence": "MTYKLILNGKTLKGETTTEAVDAATAEKVFKQYANDNGVDGEWTYDDATKTFTVTE", "chain_id": "A"}},
{"ligandSequence": {"sequence": "ATP", "is_ccd": True, "chain_id": "B"}},
],
constraints={
"pocket": [
{
"binder": {"chain_id": "B"},
"contacts": [
{"chain_id": "A", "res_idx": 12},
{"chain_id": "A", "res_idx": 15},
{"chain_id": "A", "res_idx": 18},
],
}
]
},
)
print(job.id)Human KRAS G12C protein with covalent ligand
Model KRAS (A) with covalent inhibitor U4U (B, CCD) under Boltz-2: the ligand carries property_type: affinity, and a bond constraint links SG on Cys 12 to ligand atom C22 (residue 1 on B).
from fastfold import Client
client = Client()
job = client.fold.create(
model="boltz-2",
name="Human KRAS G12C protein with covalent ligand",
sequences=[
{"proteinChain": {"sequence": "MTEYKLVVVGACGVGKSALTIQLIQNHFVDEYDPTIEDSYRKQVVIDGETCLLDILDTAGQEEYSAMRDQYMRTGEGFLCVFAINNTKSFEDIHHYREQIKRVKDSEDVPMVLVGNKCDLPSRTVDTKQAQDLARSYGIPFIETSAKTRQGVDDAFYTLVREIRKHKE", "chain_id": "A"}},
{"ligandSequence": {"sequence": "U4U", "is_ccd": True, "chain_id": "B", "property_type": "affinity"}},
],
constraints={
"bond": [
{
"atom1": {"chain_id": "A", "res_idx": 12, "atom_name": "SG"},
"atom2": {"chain_id": "B", "res_idx": 1, "atom_name": "C22"},
}
]
},
)
print(job.id)Boltz-2 affinity with ligand SMILES
Score ligand affinity with Boltz-2 when the binder is not a CCD code: chain B is a SMILES string in ligandSequence.sequence, with property_type: affinity—here an HIV-protease-like peptide (A) plus a small organic ligand.
from fastfold import Client
client = Client()
job = client.fold.create(
model="boltz-2",
name="Boltz-2 Affinity Ligand Smiles",
sequences=[
{"proteinChain": {"sequence": "PQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEEMSLPGRWKPKMIGGIGGFIKVRQYDQILIEICGHKAIGTVLVGPTPVNIIGRNLLTQIGCTLNF", "chain_id": "A"}},
{
"ligandSequence": {
"sequence": "CC1CN(CC(C1)NC(=O)C2=CC=CC=C2N)C(=O)NC(C)(C)C",
"chain_id": "B",
"property_type": "affinity",
}
},
],
)
print(job.id)Full job payload from file
Load a complete Jobs API object from JSON—name, sequences, and params (here modelName: boltz-2)—and submit it with client.jobs.create. The packaged file is a minimal single-chain boltz-2 job you can edit or swap for your own payload.
The packaged example file contains this JSON payload:
{
"name": "Example Fold Job",
"sequences": [
{
"proteinChain": {
"sequence": "MKTIIALSYIFCLVFA",
"chain_id": "A"
}
}
],
"params": {
"modelName": "boltz-2"
}
}import json
from pathlib import Path
from fastfold import Client
client = Client()
payload = json.loads(Path("fastfold/examples/fold/job_payload.json").read_text())
job = client.jobs.create(payload)
print(job.id)fastfold-cli jobs create --payload-file fastfold/examples/fold/job_payload.jsonSubmit Boltz-style YAML directly
Send Boltz-style YAML ( version, sequences with protein / ligand blocks, optional properties and constraints) through client.jobs.create_from_yaml, passing model_name and a display name. The sample file matches the KRAS + U4U covalent example: affinity on the ligand and a bond between A:12:SG and B:1:C22.
Note: Keep notebooks or shared YAML fixtures as-is and avoid hand-converting to JSON when this ingress path is enough.
The packaged YAML example looks like this:
version: 1
sequences:
- protein:
id: A
sequence: MTEYKLVVVGACGVGKSALTIQLIQNHFVDEYDPTIEDSYRKQVVIDGETCLLDILDTAGQEEYSAMRDQYMRTGEGFLCVFAINNTKSFEDIHHYREQIKRVKDSEDVPMVLVGNKCDLPSRTVDTKQAQDLARSYGIPFIETSAKTRQGVDDAFYTLVREIRKHKE
- ligand:
id: B
ccd: U4U
properties:
- affinity:
binder: B
constraints:
- bond:
atom1: [A, 12, SG]
atom2: [B, 1, C22]from pathlib import Path
from fastfold import Client
client = Client()
job = client.jobs.create_from_yaml(
Path("fastfold/examples/fold/boltz2_affinity_input.yaml").read_text(),
model_name="boltz-2",
name="yaml-demo",
)
print(job.id)fastfold-cli jobs from-yaml --file fastfold/examples/fold/boltz2_affinity_input.yaml --model boltz-2Read persisted constraints from the raw response
After client.jobs.get_results, inspect results.raw["constraints"] when you need the contact / pocket / bond lists the API echoed back—fields not yet wrapped by a typed accessor.
Prefer helpers like cif_url() and metrics() first; use .raw for full-fidelity or rare keys.
from fastfold import Client
job_id = "550e8400-e29b-41d4-a716-446655440000"
client = Client()
results = client.jobs.get_results(job_id)
constraints = (results.raw or {}).get("constraints") or {}
print("contact:", len(constraints.get("contact") or []))
print("pocket:", len(constraints.get("pocket") or []))
print("bond:", len(constraints.get("bond") or []))Last updated on