# Introduction This guide covers our HTTP REST endpoints alongside streaming and realtime interfaces used to fold protein sequences, retrieve structural properties, and orchestrate workflows and agents. You can call the API from any environment that can make HTTPS requests, or use our [first-class SDKs](/quick-start) for Python and JavaScript for a simpler, typed client experience. ## Authentication
Create API Key
You can create an API key in the [Fastfold dashboard](https://cloud.fastfold.ai/api-keys). Once you have an API key, you can use it to authenticate requests to the API. API key authentication is done via the `Authorization` header. ```bash Authorization: Bearer ``` Remember to keep your API key secure, as anyone with your API key can make requests on your behalf. Next, explore the available endpoints and how to use them. ## OpenAPI spec For agents and tooling, you can read the raw OpenAPI YAML directly: * [`/api/openapi.yaml`](/api/openapi.yaml) ## Quota Limits All API requests are subject to quota limits. You can view your quota limits in the [Usage dashboard](https://cloud.fastfold.ai/usage). If you exceed your quota limits, you will receive a 429 error. While on beta, you can upgrade your quota limits by contacting us at [hello@fastfold.ai](mailto:hello@fastfold.ai). ## Next steps Now that you're authenticated and know about quota limits, you can start using the API. # CLI The FastFold CLI is ideal for quick experiments, shell scripts, and CI pipelines. ## Authentication The CLI uses the same API key as the SDK. macOS / Linux Windows ```bash export FASTFOLD_API_KEY="sk-...your-api-key" ``` ```bash setx FASTFOLD_API_KEY "sk-...your-api-key" ``` You can also pass an API key explicitly via `--api-key`. ## Submit a folding job ```bash fastfold fold --sequence "LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES" --model boltz-2 ``` On success, the CLI prints the created job ID to stdout. ## Common flags ```bash fastfold fold \ --sequence "..." \ --model boltz-2 \ --name "My Job" \ --api-key "sk-..." \ --base-url "https://api.fastfold.ai" ``` ## CI-friendly pattern If you want to keep the API key out of shell history, prefer environment variables: ```bash export FASTFOLD_API_KEY="$FASTFOLD_API_KEY" fastfold fold --sequence "$SEQ" --model boltz-2 --name "ci-$GITHUB_RUN_ID" ``` ## Next steps * For "wait for completion", artifacts, and metrics workflows, use the Python SDK examples: [/python-examples](/python-examples) # Fastfold AI
Fastfold Fastfold
Scientists and AI agents doing real science.
Skills PyPI Join Slack
## Why use Fastfold * **Scientists + agents**: collaborate with AI agents to plan, run, and iterate on folding experiments. * **Managed infrastructure**: run jobs on cloud GPUs and containers without handling DevOps yourself. * **Reproducibility first**: keep runs versioned and traceable so results are easy to compare and share. * **Production-ready integrations**: use REST endpoints directly or ship quickly with the Python SDK and CLI. ## Quick start Here is a quick fold using the Python SDK. ```bash pip install fastfold-ai ``` ```python from fastfold import Client client = Client() my_job = client.fold.create( sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES", model="boltz-2", is_public=True, ) results = client.jobs.wait_for_completion(my_job.id, poll_interval=5.0, timeout=900.0) print("Status:", results.job.status) print("CIF URL:", results.cif_url()) print("Viewer:", results.get_viewer_link()) ``` This example creates a fold job, waits for completion, then prints the final job status, a direct CIF artifact URL, and a viewer link you can share publicly if `is_public=True` is set. ## SDK and API examples * Start with the SDK guide: [/python-sdk](/python-sdk) * Explore practical recipes: [/python-examples](/python-examples) * Run from terminal/CI: [/cli](/cli) * Browse endpoint docs: [/api](/api) ## Skills for agents If you use AI agents, install the official Fastfold skills package to help agents run fold workflows end-to-end (create job, wait for completion, fetch CIF/PDB, metrics, and viewer links). ```bash npx skills add fastfold-ai/skills ``` The repository currently includes a `fold` skill focused on Fastfold Jobs API automation, and supports loading `FASTFOLD_API_KEY` from `.env` for local scripting. * Skills repo: [github.com/fastfold-ai/skills](https://github.com/fastfold-ai/skills) * Skills listing: [skills.sh/fastfold-ai/skills](https://skills.sh/fastfold-ai/skills) * Detailed guide: [/skills](/skills) ## `llms.txt` This docs site includes AI-friendly exports: * [`/llms.txt`](/llms.txt): concise index with documentation links. * [`/llms-full.txt`](/llms-full.txt): full combined markdown content. You can also append `.mdx` to docs paths to retrieve markdown content for a specific page (for example, `/python-sdk.mdx`). ## Next steps Create an API key in the dashboard, run a first fold, then choose your integration path: * API-first: [/api](/api) * SDK/CLI-first: [/quick-start](/quick-start) # Recipes & Examples This page collects **reference** workflows for the FastFold Python SDK, grouped by common job types and model usage. ## Quick map (job types -> typical models) * **Single-sequence fold**: common starting point (example uses `boltz-2`) * **Complex with ligand + optional constraints (pockets)**: advanced structure + property prediction (example uses `boltz-2`) * **Non-complex multi-sequence (indexing)**: multiple independent sequences; access artifacts via `results[i]` (example uses `simplefold_100M`) * **Create from library (`from_id`)**: start from a known library entry and override parameters (example uses `boltz-2`) * **Fetch by job id**: resume work in another script/notebook (works for complex and non-complex jobs) ## Minimal SDK usage (single sequence) ```python from fastfold import Client client = Client() # Reads FASTFOLD_API_KEY from env by default myJob = client.fold.create( sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES", model="boltz-2", is_public=True, ) print("Job ID:", myJob.id) results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) print("Status:", results.job.status) print("CIF URL:", results.cif_url()) print("Mean PLDDT:", results.metrics().mean_PLDDT) link = results.get_viewer_link() print("Open in viewer:", link) ``` ## Advanced Boltz-2: affinity prediction + pockets ```python from fastfold import Client client = Client() myJob = client.fold.create( name="Streptococcal protein G with Pocket", model="boltz-2", sequences=[ { "proteinChain": { "sequence": "MTYKLILNGKTLKGETTTEAVDAATAEKVFKQYANDNGVDGEWTYDDATKTFTVTE", "count": 1, "chain_id": "A", "label": "mobile-purple", } }, { "ligandSequence": { "sequence": "ATP", "count": 1, "chain_id": "B", "label": "constitutional-brown", "is_ccd": True, "property_type": "affinity", } }, ], params={ "modelName": "boltz-2", "weightSet": "Boltz-2", "relaxPrediction": True, "method": "Boltz-2", "recyclingSteps": 3, "samplingSteps": 200, "diffusionSample": 1, "stepScale": 1.638, "affinityMwCorrection": False, "samplingStepsAffinity": 200, "diffusionSamplesAffinity": 5, }, 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}, ], } ] }, ) results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) print("Completed CIF URL:", results.cif_url()) metrics = results.metrics() print("Mean PLDDT:", metrics.mean_PLDDT) print("ptm_score:", metrics.ptm_score) print("iptm_score:", metrics.iptm_score) # Boltz-2 affinity metrics (present only if provided by API) print("affinity_pred_value:", metrics.affinity_pred_value) print("affinity_probability_binary:", metrics.affinity_probability_binary) print("affinity_pred_value1:", metrics.affinity_pred_value1) print("affinity_probability_binary1:", metrics.affinity_probability_binary1) print("affinity_pred_value2:", metrics.affinity_pred_value2) print("affinity_probability_binary2:", metrics.affinity_probability_binary2) link = results.get_viewer_link() print("Open in viewer:", link) ``` ## Non-complex multi-sequence artifacts (indexing) Use indexing (`results[0]`, `results[1]`, ...) to access per-sequence artifacts when the job is **not** a complex. ```python from fastfold import Client client = Client() myJob = client.fold.create( name="My Protein List", model="simplefold_100M", sequences=[ { "proteinChain": { "sequence": "MCNTNMSVSTEGAASTSQIPASEQETLVRPKPLLLKLLKSVGAQNDTYTMKEIIFYIGQYIMTKRLYDEKQQHIVYCSNDLLGDVFGVPSFSVKEHRKIYAMIYRNLVAV", "count": 1, "chain_id": "A", "label": "specific-white", } }, { "proteinChain": { "sequence": "SQETFSGLWKLLPPE", "count": 1, "chain_id": "B", "label": "wily-amethyst", } }, ], params={ "modelName": "simplefold_100M", "weightSet": "SimpleFold", "method": "SimpleFold", }, ) results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) cif_url_chain_a = results[0].cif_url() cif_url_chain_b = results[1].cif_url() print("Chain A CIF:", cif_url_chain_a) print("Chain B CIF:", cif_url_chain_b) m0 = results[0].metrics() m1 = results[1].metrics() print("Chain A mean PLDDT:", m0.mean_PLDDT) print("Chain B mean PLDDT:", m1.mean_PLDDT) link = results.get_viewer_link() print("Open in viewer:", link) ``` ## Create with library source (`from_id`) and additional params ```python from fastfold import Client client = Client() myJob = client.fold.create( model="boltz-2", sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES", from_id="770e8400-e29b-41d4-a716-446655440002", params={"relaxPrediction": True, "recyclingSteps": 2}, ) results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) print("Completed:", results.job.status) ``` ## Fetch results and status ```python from fastfold import Client client = Client() results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) status = results.job.status print("Status:", status) ``` Status could be: * PENDING: Job queued but not yet initialized * INITIALIZED: Job created and ready to run * RUNNING: Job is processing * COMPLETED: Job finished successfully * FAILED: Job encountered an error * STOPPED: Job was stopped before completion ## Update visibility ```python client.jobs.set_public(myJob.id, True) # make job publicly accessible ``` ## Get artifact URLs ```python from fastfold import Client client = Client() results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) # Complex jobs (shared artifacts at top level) if results.job.is_complex: cif_url = results.cif_url() pdb_url = results.pdb_url() pae_url = results.pae_plot_url() plddt_url = results.plddt_plot_url() else: # Non-complex: per-sequence artifacts via indexing cif_url = results[0].cif_url() pdb_url = results[0].pdb_url() ``` ## Get metrics ```python from fastfold import Client client = Client() results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) # Complex (boltz-2) jobs: top-level metrics if results.job.is_complex: metrics = results.metrics() print("mean_PLDDT:", metrics.mean_PLDDT) print("ptm_score:", metrics.ptm_score) print("iptm_score:", metrics.iptm_score) print("max_pae_score:", metrics.max_pae_score) # Boltz-2 affinity metrics (present only if provided by API) print("affinity_pred_value:", metrics.affinity_pred_value) print("affinity_probability_binary:", metrics.affinity_probability_binary) print("affinity_pred_value1:", metrics.affinity_pred_value1) print("affinity_probability_binary1:", metrics.affinity_probability_binary1) print("affinity_pred_value2:", metrics.affinity_pred_value2) print("affinity_probability_binary2:", metrics.affinity_probability_binary2) else: # Non-complex: per-sequence metrics via indexing m0 = results[0].metrics() print("Chain A mean PLDDT:", m0.mean_PLDDT) m1 = results[1].metrics() print("Chain B mean PLDDT:", m1.mean_PLDDT) ``` ## Fetch an existing job by ID ```python from fastfold import Client client = Client() job_id = "550e8400-e29b-41d4-a716-446655440000" results = client.jobs.wait_for_completion(job_id, poll_interval=5.0, timeout=900.0) print("Status:", results.job.status) # Complex job example (top-level artifacts) cif_url = results.cif_url() pdb_url = results.pdb_url() pae_url = results.pae_plot_url() plddt_url = results.plddt_plot_url() print("CIF URL:", cif_url) print("PDB URL:", pdb_url) print("PAE URL:", pae_url) print("pLDDT URL:", plddt_url) metrics = results.metrics() print("mean_PLDDT:", metrics.mean_PLDDT) print("ptm_score:", metrics.ptm_score) print("iptm_score:", metrics.iptm_score) print("max_pae_score:", metrics.max_pae_score) link = results.get_viewer_link() print("Open in viewer:", link) ``` ```python # Non-complex example (index into sequences) from fastfold import Client client = Client() job_id = "550e8400-e29b-41d4-a716-446655440000" results = client.jobs.wait_for_completion(job_id, poll_interval=5.0, timeout=900.0) cif_seq0 = results[0].cif_url() pdb_seq0 = results[0].pdb_url() m0 = results[0].metrics() print("Seq0 CIF:", cif_seq0) print("Seq0 PDB:", pdb_seq0) print("Seq0 mean_PLDDT:", m0.mean_PLDDT) ``` ## A practical "safe" wrapper (error handling) If you're running this in a pipeline, you'll usually want a small wrapper so failures are obvious and easy to debug. ```python from fastfold import Client def fold_and_print(sequence: str, model: str = "boltz-2") -> None: client = Client() job = client.fold.create(sequence=sequence, model=model, is_public=True) results = client.jobs.wait_for_completion(job.id, poll_interval=5.0, timeout=900.0) if results.job.status != "COMPLETED": raise RuntimeError(f"FastFold job did not complete: status={results.job.status} job_id={job.id}") print("Job ID:", job.id) print("CIF URL:", results.cif_url()) print("Mean PLDDT:", results.metrics().mean_PLDDT) print("Viewer:", results.get_viewer_link()) ``` # SDK Python client for the FastFold Jobs API. ## Installation Requires **Python 3.8+**. PyPI Local (project root) Development (editable) ```bash pip install fastfold-ai ``` ```bash pip install . ``` ```bash pip install -e . ``` ## Authentication Set your API key in the environment: macOS / Linux Windows ```bash export FASTFOLD_API_KEY="sk-...your-api-key" ``` ```bash setx FASTFOLD_API_KEY "sk-...your-api-key" ``` Then create the client (it reads `FASTFOLD_API_KEY` by default): ```python from fastfold import Client client = Client() ``` You can also pass credentials explicitly (handy in CI or when using multiple keys): ```python from fastfold import Client client = Client(api_key="sk-...your-api-key") ``` ## Base URL (optional) By default, the SDK targets the FastFold API. If you need to override it (self-hosting, proxies, or testing), set a base URL: ```python from fastfold import Client client = Client(base_url="https://api.fastfold.ai") ``` ## Your first fold ```python from fastfold import Client client = Client() # reads FASTFOLD_API_KEY myJob = client.fold.create( sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES", model="boltz-2", is_public=True, ) print("Job ID:", myJob.id) results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) print("Status:", results.job.status) print("CIF URL:", results.cif_url()) print("Mean PLDDT:", results.metrics().mean_PLDDT) link = results.get_viewer_link() print("Open in viewer:", link) ``` ## Polling, timeouts, and scripts In scripts and notebooks, prefer waiting for completion to simplify control flow: ```python results = client.jobs.wait_for_completion( myJob.id, poll_interval=5.0, # seconds between polls timeout=900.0, # seconds until giving up ) ``` If you want to implement your own polling loop, you can treat job status as the source of truth and branch your logic accordingly (see the status list in the Examples page). ## Visibility (public vs private) ```python client.jobs.set_public(myJob.id, True) # make job publicly accessible ``` ## What’s next * Reference examples (Boltz-2 affinity + pockets, indexing, artifacts, metrics): [/python-examples](/python-examples) * CLI usage (submit jobs from the terminal): [/cli](/cli) # Quick Start The FastFold platform provides a simple, production-ready API to fold protein sequences, compute structural properties, run complex workflows, and orchestrate agents. This section focuses on the **Python SDK** and **CLI**. Open In Colab ### Create an API key
Create API Key
Before you can use the API, you need to create an API key. You can do this in the cloud dashboard. Once you have created an API key, you can use to [authenticate](/api/authentication) requests to the API. Make sure to keep your API key secret and do not share it with anyone. You can store in your [environment variables](https://en.wikipedia.org/wiki/Environment_variable) (.zshrc, .bashrc, .env, etc.) to use in your code. macOS / Linux Windows ```bash export FASTFOLD_API_KEY="your_api_key_here" ``` ```bash setx FASTFOLD_API_KEY "your_api_key_here" ``` The Python SDK will automatically pick up the API key from `FASTFOLD_API_KEY` by default. ### Install the FastFold Python SDK Requires **Python 3.8+**. ```bash # Recommended (from PyPI) pip install fastfold-ai ``` ```bash # Local development (from project root) pip install -e . ``` ### Fold a protein sequence With the SDK installed, create a file named `example.py` and run: ```python from fastfold import Client client = Client() myJob = client.fold.create( sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES", model="boltz-2", is_public=True, ) results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) print("Status:", results.job.status) print("CIF URL:", results.cif_url()) print("Mean PLDDT:", results.metrics().mean_PLDDT) link = results.get_viewer_link() print("Open in viewer:", link) ``` ### Run the same flow with the CLI ```bash fastfold fold --sequence "LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES" --model boltz-2 ``` On success, the CLI prints the created job ID to stdout. ### Next steps * Read **Python SDK** details (auth, configuration, patterns): [/python-sdk](/python-sdk) * Browse **reference examples** (Boltz-2 affinity, pockets, indexing, artifacts, metrics): [/python-examples](/python-examples) * Learn **CLI flags and workflows**: [/cli](/cli) * Read the **API Reference** to discover all endpoints: [/api](/api) * Explore available **models** and their capabilities: [cloud.fastfold.ai/models](https://cloud.fastfold.ai/models) You’re ready to fold your own sequences and integrate FastFold into your pipelines. # Skills for Agents Fastfold Skills are packaged instructions and scripts that help AI agents run fold workflows end-to-end with the Fastfold Jobs API. These skills can be used across many agent tools (for example Claude Code, Cursor, Codex, and others). See [skills.sh](https://skills.sh/) for the full list of supported agents. ## Install ```bash npx skills add fastfold-ai/skills ``` Repository: [github.com/fastfold-ai/skills](https://github.com/fastfold-ai/skills)\ Listing: [skills.sh/fastfold-ai/skills](https://skills.sh/fastfold-ai/skills) ## Example After installing, you can ask your agent directly: ```text Use Boltz-2 in Fastfold with affinity property to the ligand. Fold this protein: PQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEEMSLPGRWKPKMIGGIGGFIKVRQYDQILIEICGHKAIGTVLVGPTPVNIIGRNLLTQIGCTLNF and this ligand: CC1CN(CC(C1)NC(=O)C2=CC=CC=C2N)C(=O)NC(C)(C)C ``` ## Usage Once installed, your agent can invoke the skill when requests match folding tasks. Typical flow: * create fold job * wait for completion * fetch results and metrics * get artifact URLs (CIF/PDB) * generate viewer links ## Available skill: `fold` The `fold` skill is designed for Fastfold Jobs API automation. Use it when you need: * protein sequence folding with Fastfold * API or script-based job orchestration * automated create -> wait -> fetch pipelines ## Features * Create Job (`POST /v1/jobs`) with sequences, params, constraints, and optional library `from` ID * Wait for completion with configurable polling and timeout * Fetch results summary (or raw JSON) * Download CIF outputs * Generate 3D viewer links ## Included scripts * `wait_for_completion.py` * `fetch_results.py` * `download_cif.py` * `get_viewer_link.py` ## API key setup Skills/scripts require `FASTFOLD_API_KEY`. ### Option A: `.env` (recommended) Your agent can help you create these files and follow the setup. ```bash cp skills/fold/references/.env.example .env ``` Then edit `.env`: ```dotenv FASTFOLD_API_KEY=sk-your-actual-key-here ``` ### Option B: shell environment ```bash export FASTFOLD_API_KEY="sk-..." ``` Environment variables take precedence over `.env`. ## Security note Keep API keys local and never commit `.env` files. # Troubleshooting ## Authentication errors * **401 / Unauthorized**: your API key is missing, invalid, or not being picked up. * Make sure `FASTFOLD_API_KEY` is set in your shell/session. * If you're running in a notebook, restart the kernel after setting env vars. * Try passing the key explicitly to confirm it works: ```python from fastfold import Client client = Client(api_key="sk-...your-api-key") ``` ## 429 / quota exceeded All API requests are subject to quota limits. Check the [Usage dashboard](https://cloud.fastfold.ai/usage). ## Timeouts while waiting for completion If your script hits the timeout, increase it and/or reduce polling load: ```python results = client.jobs.wait_for_completion( myJob.id, poll_interval=10.0, timeout=3600.0, ) ``` ## Job status is FAILED or STOPPED * **FAILED**: the job encountered an error (invalid input, model constraints, or server error). * **STOPPED**: the job was stopped before completion. Recommended pattern in pipelines: ```python results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0) if results.job.status != "COMPLETED": raise RuntimeError(f"Job did not complete: status={results.job.status} job_id={myJob.id}") ``` ## Artifact URLs are missing Artifacts can differ between: * **Complex jobs**: shared artifacts are available at the top level (e.g. `results.cif_url()`). * **Non-complex jobs**: artifacts are per-sequence; use indexing (e.g. `results[0].cif_url()`). See: [/python-examples](/python-examples) # Create Library Item
Create a new library folder or file record.
# Get Library Item
Fetch a single library item by ID. Folder items include nested children.
# List Library
List root-level library items with filtering and cursor pagination.
# Replace Library Item File
Replace a file on an existing library item by filename.
# Search Library
Search library items by name with optional recent-mode behavior.
# Upload Files to Library Item
Upload one or more files to an existing library item folder.
# Create Job {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
Create a new job to fold protein sequences using AI models. The job will be processed asynchronously and you can track its status using the returned job ID.
# Get Job Results {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
Fetch job + latest job run + sequences for a job ID. * If the job is **public** (`isPublic: true`), authentication is **not required**. * If the job is **not public** (`isPublic: false` or `null`), authentication is required and the caller must own the job.
# Update Job Public Visibility {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
Update a job's `isPublic` flag. Authentication is required and **only the job owner** can change this field.
# Create Workflow Graph
Create a new workflow graph shell. This endpoint supports creating a boltzgen\_v1 workflow.
# Execute Workflow
Start execution for an existing workflow by ID.
# Get Workflow Logs
Get workflow logs. Terminal workflows return stored log file text directly.
# Get Workflow Status
Retrieve workflow-level status and task-level states.
# Get Workflow Task Results
Get task outputs and parsed results for a workflow.
# Get Workflow YAML
Get the current workflow graph serialized as workflow\.yml.
# Set Workflow YAML
Replace the workflow graph from YAML input and sync the canonical workflow\.yml artifact. Reference files and library items in this YAML must be created and managed through the Library API.