Skip to main content

Nano Helix API – Quick-Start Guide

Welcome to the Nano Helix Control-Plane API. This page walks you through the entire workflow:
  1. Authenticate with an x-api-key
  2. Upload input files (optional)
  3. Submit a simulation job
  4. Track job progress
  5. Download results
Every section includes copy-ready cURL and Python snippets.

1. Base URL & Authentication

Required header
x-api-key: YOUR_LONG_API_KEY
Production base URL:
https://api.nanohelix.ai
A 401 Unauthorized response means the header is missing or the key is invalid/disabled.

2. Uploading Input Files (optional)

If your algorithm takes external files (FASTA, PDB, etc.) you will:
  1. Ask the control plane for a presigned PUT URL.
  2. Upload directly to cloud storage (no size limits from the API layer).
  3. Tell the API once the upload is finished.

3.1 Generate a presigned upload URL

curl -X PUT \
     -H "x-api-key: $API_KEY" \
     "https://api.nanohelix.ai/upload/example.fasta?folder=inputs"
Response (abridged):
{
  "status": "ready",
  "fileId": "file_a1b2c3",
  "uploadUrl": "https://storage.googleapis.com/bucket/…",
  "downloadUrl": "https://storage.googleapis.com/bucket/…",
  "instructions": {
    "upload": "PUT https://storage.googleapis.com/bucket/…",
    "headers": { "Content-Type": "text/plain" },
    "curlExample": "curl -X PUT --data-binary @example.fasta …"
  }
}

2.2 Upload the file

Run the curlExample exactly as returned, or use any S3/GCS-compatible client.

2.3 Mark upload complete

curl -X POST \
     -H "x-api-key: $API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"size": 1048576}' \
     "https://api.nanohelix.ai/upload/file_a1b2c3/complete"

3. Submit a Job

curl -X POST \
     -H "x-api-key: $API_KEY" \
     -H "Content-Type: application/json" \
     -d @job.json \
     https://api.nanohelix.ai/submit-job
job.json example:
job.json
{
  "jobName": "my-protein-job",
  "type": "boltz",
  "settings": {
    "sequences": ["MKLLVL..."],
    "steps": 200
  },
  "version": "2.1.1"
}
Tips
  • jobName must be unique within your organization.
  • Submitting the exact same JSON again is idempotent (you will get the existing job).
  • Changing anything (settings hash) ⇒ 409 JOB_ALREADY_EXISTS.

4. Track Jobs

GET /jobs
Useful query parameters:
ParamExampleDescription
jobNamejobName=my-protein-jobExact name search
algorithmalgorithm=boltzFilter by engine
limit (1-100)limit=50Pagination size
startKeystartKey=opaque_cursorCursor for next page
includeSubjobsincludeSubjobs=trueExpand batch jobs (if applicable)
curl -H "x-api-key: $API_KEY" \
     "https://api.nanohelix.ai/jobs?algorithm=boltz&limit=20"

5. Download Results

Results are available only when status = COMPLETED.
curl -X POST \
     -H "x-api-key: $API_KEY" \
     -H "Content-Type: application/json" \
     -d '{
           "jobName": "my-protein-job",
           "fileName": "results.zip"  // optional
         }' \
     https://api.nanohelix.ai/result
{
  "downloadUrl": "https://storage.googleapis.com/bucket/results.zip?X-Amz-Signed..."
}
The link expires after 1 hour.
curl -o results.zip "https://storage.googleapis.com/…"

6. Python Quick-Start

quickstart.py
import os, requests, json

API_KEY = os.environ["NANOHELIX_API_KEY"]
BASE    = "https://api.nanohelix.ai"
HEADERS = {"x-api-key": API_KEY}

# Submit a job
payload = {
    "jobName": "my-protein-job",
    "type": "boltz",
    "settings": {
        "sequences": ["MKLLVL..."],
        "steps": 200
    }
}
resp = requests.post(f"{BASE}/submit-job", headers=HEADERS, json=payload)
resp.raise_for_status()
print(resp.json())

# Poll status
status = requests.get(f"{BASE}/jobs?jobName=my-protein-job", headers=HEADERS).json()
print(status)

Need help?

Email [email protected] — include your jobName and the full error response (don’t redact error.code).