← Back to Home

Phonos API Documentation v2.0

The Phonos API provides programmatic access to our protein structure prediction and molecular docking models. Use our API to integrate ESMFold, AlphaFold2, and DiffDock into your applications and workflows.

Base URL: https://app.phonos.bio

Authentication

All API requests (except /v1/health) require authentication using an API key. You can create and manage API keys in your dashboard settings.

Using Your API Key

Include your API key in the Authorization header of each request:

Authorization: Bearer YOUR_API_KEY
⚠️ Keep your API key secure!
Never commit API keys to version control or expose them in client-side code. Treat them like passwords.

Example Request

curl -H "Authorization: Bearer pk_abc123..." \
     https://app.phonos.bio/v1/models

Rate Limiting

API keys have configurable rate limits. When you exceed your rate limit, you'll receive a 429 Too Many Requests response. Rate limits are enforced per API key, not per user.

💡 Rate Limit Best Practices
  • Implement exponential backoff when you receive 429 responses
  • Cache results when possible to reduce API calls
  • Use batch operations if your workflow allows
  • Monitor your rate limit usage in the dashboard
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit of 60 requests per minute"
}

API Endpoints

GET /v1/health

Check API health and status. This endpoint does not require authentication.

Response Example

{
  "status": "operational",
  "version": "v1",
  "message": "PHONOS API is running"
}
GET /v1/models

Retrieve a list of available AI models for protein analysis.

Response Example

{
  "models": [
    {
      "id": "esmfold",
      "name": "ESMFold",
      "description": "Fast protein structure prediction from Meta AI",
      "type": "structure_prediction",
      "cost_credits": 10
    },
    {
      "id": "alphafold2",
      "name": "AlphaFold2",
      "description": "High-accuracy protein structure prediction from DeepMind",
      "type": "structure_prediction",
      "cost_credits": 50
    },
    {
      "id": "diffdock",
      "name": "DiffDock",
      "description": "Molecular docking for protein-ligand interactions",
      "type": "docking",
      "cost_credits": 30
    }
  ]
}
POST /v1/predict

Submit a new prediction job to be processed asynchronously.

Request Body

Parameter Type Required Description
model string REQUIRED Model ID (esmfold, alphafold2, diffdock)
sequence string REQUIRED Protein sequence (amino acids) or SMILES (for diffdock)
name string OPTIONAL Human-readable job name
params object OPTIONAL Model-specific parameters

Request Example

curl -X POST https://app.phonos.bio/v1/predict \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "esmfold",
    "sequence": "MGSSHHHHHHSSGLVPRGSHMASMTGGQQMGRGS",
    "name": "My Protein Structure"
  }'

Response Example

{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "esmfold",
  "status": "pending",
  "credits_used": 10,
  "message": "Job submitted successfully"
}

Model-Specific Parameters

Each model accepts different optional parameters in the params object to customize the prediction.

ESMFold Parameters

Fast protein structure prediction optimized for speed.

Parameter Type Default Description
num_recycles integer 4 Number of recycling iterations (1-24). Higher values may improve accuracy but take longer.
chunk_size integer 128 Controls memory usage. Reduce if running into memory issues.
✓ Best for: Quick predictions, high-throughput screening, sequences up to 400 residues

AlphaFold2 Parameters

High-accuracy predictions with MSA support.

Parameter Type Default Description
max_msa_seqs integer 512 Maximum number of MSA sequences to use
use_templates boolean true Whether to use template structures from PDB
model_preset string monomer Model type: "monomer", "monomer_casp14", "monomer_ptm"
✓ Best for: Maximum accuracy, research publications, complex proteins, multimers

DiffDock Parameters

Molecular docking for protein-ligand binding prediction.

Parameter Type Default Description
protein_pdb string required PDB file content or path to protein structure
ligand_smiles string required SMILES string of the ligand molecule
inference_steps integer 20 Number of diffusion steps (10-40). Higher = more accurate but slower.
samples_per_complex integer 10 Number of binding poses to generate
✓ Best for: Drug discovery, binding site prediction, virtual screening
GET /v1/jobs/{job_id}

Retrieve the status and results of a prediction job.

Path Parameters

Parameter Type Description
job_id string Job ID returned from /v1/predict

Response Example (Pending)

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "My Protein Structure",
  "status": "pending",
  "created_at": "2025-12-17T10:30:00Z",
  "updated_at": "2025-12-17T10:30:00Z"
}

Response Example (Completed)

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "My Protein Structure",
  "status": "completed",
  "created_at": "2025-12-17T10:30:00Z",
  "updated_at": "2025-12-17T10:32:00Z",
  "output_file": "550e8400-e29b-41d4-a716-446655440000.pdb",
  "download_url": "/v1/jobs/550e8400-e29b-41d4-a716-446655440000/download"
}
GET /v1/jobs/{job_id}/download

Download the output file (PDB format) for a completed job.

Path Parameters

Parameter Type Description
job_id string Job ID of completed job

Example

curl -H "Authorization: Bearer YOUR_API_KEY" \
     https://app.phonos.bio/v1/jobs/550e8400.../download \
     -o structure.pdb
GET /v1/account

Get your account information including credit balance and job statistics.

Response Example

{
  "account": {
    "id": 123,
    "username": "researcher",
    "email": "user@example.com",
    "created_at": "2024-01-15T08:30:00Z"
  },
  "credits": {
    "balance": 5000,
    "currency": "credits"
  },
  "jobs": {
    "total": 150,
    "completed": 142,
    "active": 3,
    "failed": 5
  }
}
GET /v1/jobs

List all your jobs with optional filtering by status or model.

Query Parameters

Parameter Type Default Description
status string all Filter by status: pending, running, completed, failed
model string all Filter by model: esmfold, alphafold2, diffdock
limit integer 50 Max results per page (max: 100)
offset integer 0 Number of results to skip for pagination

Response Example

{
  "jobs": [
    {
      "job_id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Insulin Structure",
      "status": "completed",
      "model": "esmfold",
      "created_at": "2025-12-17T10:30:00Z",
      "download_url": "/v1/jobs/550e8400.../download"
    }
  ],
  "pagination": {
    "total": 150,
    "limit": 50,
    "offset": 0,
    "has_more": true
  }
}
POST /v1/predict/batch

Submit multiple prediction jobs in a single request (max 10 jobs per batch).

Request Body

{
  "jobs": [
    {
      "model": "esmfold",
      "sequence": "MGSSHHHHHHSSGLVPRGSHMASMTGGQQMGRGS",
      "name": "Protein 1"
    },
    {
      "model": "esmfold",
      "sequence": "MKTVRQERLKSIVRILERSKEPVSGAQLAEELSVSRQVIVQDIAYLRSLGYNIVATPRGYVLAGG",
      "name": "Protein 2"
    }
  ]
}

Response Example

{
  "success": true,
  "summary": {
    "total": 2,
    "successful": 2,
    "failed": 0,
    "total_credits_used": 20
  },
  "results": [
    {"index": 0, "success": true, "job_id": "550e8400...", "model": "esmfold", "credits_used": 10},
    {"index": 1, "success": true, "job_id": "550e8401...", "model": "esmfold", "credits_used": 10}
  ]
}
POST /v1/jobs/{job_id}/cancel

Cancel a pending or running job.

Response Example

{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "cancelled",
  "message": "Job cancelled successfully"
}
GET /v1/usage

Get detailed API usage statistics including requests by endpoint, model, and daily breakdown.

Query Parameters

Parameter Type Default Description
days integer 30 Number of days to include (max: 90)

Response Example

{
  "period": {"days": 30, "start_date": "...", "end_date": "..."},
  "totals": {"requests": 1250, "credits_used": 15000, "avg_response_time_ms": 45.2},
  "by_endpoint": [{"endpoint": "/v1/predict", "requests": 1000, "credits_used": 15000}],
  "by_model": [{"model": "esmfold", "requests": 800, "credits_used": 8000}],
  "daily": [{"date": "2025-12-17", "requests": 50, "credits_used": 500}]
}

Webhooks

Webhooks allow you to receive real-time notifications when jobs complete or fail, eliminating the need to poll for status updates.

GET /v1/webhooks

List all configured webhooks for your account.

POST /v1/webhooks

Create a new webhook to receive job status notifications (max 5 per account).

Request Body

Parameter Type Required Description
url string REQUIRED HTTPS URL to receive webhook events
events array optional Events to subscribe to: job.completed, job.failed, job.started

Webhook Payload Example

{
  "event": "job.completed",
  "timestamp": "2025-12-17T10:32:00Z",
  "data": {
    "job_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "model": "esmfold",
    "download_url": "/v1/jobs/550e8400.../download"
  }
}
DELETE /v1/webhooks/{webhook_id}

Delete a webhook by its ID.

POST /v1/webhooks/{webhook_id}/test

Send a test event to verify your webhook endpoint is working correctly.

Error Responses

The API uses standard HTTP status codes and returns JSON error objects with helpful messages.

Status Code Meaning
400 Bad Request - Invalid parameters
401 Unauthorized - Invalid or missing API key
404 Not Found - Resource doesn't exist
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Server issue

Error Response Format

{
  "error": "Error type",
  "message": "Detailed error message explaining what went wrong"
}

Best Practices

⚡ Performance Optimization

  • Poll efficiently: Use 5-10 second intervals when checking job status. Don't poll more frequently than necessary.
  • Batch predictions: Submit multiple jobs in parallel rather than waiting for each to complete.
  • Choose the right model: Use ESMFold for speed, AlphaFold2 for accuracy. Don't over-engineer simple tasks.
  • Cache results: Store predictions locally to avoid re-computing identical sequences.

🔒 Security

  • Environment variables: Store API keys in environment variables, never hardcode them.
  • Server-side only: Never expose API keys in client-side JavaScript or mobile apps.
  • Rotate keys: Periodically rotate your API keys, especially after team member changes.
  • Use separate keys: Create different API keys for development and production environments.

🎯 Error Handling

  • Implement retries: Use exponential backoff for transient errors (500, 503).
  • Handle rate limits: Catch 429 responses and wait before retrying.
  • Validate inputs: Check sequence formats and parameters before submitting to avoid 400 errors.
  • Log errors: Keep detailed logs of API errors for debugging and monitoring.
  • Graceful degradation: Have fallback mechanisms when the API is unavailable.

📊 Monitoring & Debugging

  • Track usage: Monitor your API usage and credit consumption in the dashboard.
  • Request IDs: Log job IDs for all predictions to trace issues.
  • Health checks: Implement regular health checks using /v1/health endpoint.
  • Alert on failures: Set up alerts for consecutive failures or unusual error rates.
💡 Pro Tip: Start with small test batches to validate your integration before scaling up to production workloads.

Code Examples

Python

import requests
import time

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://app.phonos.bio"

# Submit a job
response = requests.post(
    f"{BASE_URL}/v1/predict",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "esmfold",
        "sequence": "MGSSHHHHHHSSGLVPRGSHMASMTGGQQMGRGS",
        "name": "Test Protein"
    }
)

job = response.json()
job_id = job["job_id"]
print(f"Job submitted: {job_id}")

# Poll for completion
while True:
    status = requests.get(
        f"{BASE_URL}/v1/jobs/{job_id}",
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()

    if status["status"] == "completed":
        print("Job completed!")
        break
    elif status["status"] == "failed":
        print(f"Job failed: {status.get('error')}")
        break

    time.sleep(5)

# Download results
result = requests.get(
    f"{BASE_URL}/v1/jobs/{job_id}/download",
    headers={"Authorization": f"Bearer {API_KEY}"}
)

with open("output.pdb", "wb") as f:
    f.write(result.content)

print("Structure saved to output.pdb")

JavaScript (Node.js)

const axios = require('axios');
const fs = require('fs');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://app.phonos.bio';

async function runPrediction() {
    // Submit job
    const submitResponse = await axios.post(
        `${BASE_URL}/v1/predict`,
        {
            model: 'esmfold',
            sequence: 'MGSSHHHHHHSSGLVPRGSHMASMTGGQQMGRGS',
            name: 'Test Protein'
        },
        { headers: { Authorization: `Bearer ${API_KEY}` } }
    );

    const jobId = submitResponse.data.job_id;
    console.log(`Job submitted: ${jobId}`);

    // Poll for completion
    while (true) {
        const statusResponse = await axios.get(
            `${BASE_URL}/v1/jobs/${jobId}`,
            { headers: { Authorization: `Bearer ${API_KEY}` } }
        );

        const status = statusResponse.data.status;

        if (status === 'completed') {
            console.log('Job completed!');
            break;
        } else if (status === 'failed') {
            console.log(`Job failed: ${statusResponse.data.error}`);
            return;
        }

        await new Promise(resolve => setTimeout(resolve, 5000));
    }

    // Download results
    const downloadResponse = await axios.get(
        `${BASE_URL}/v1/jobs/${jobId}/download`,
        {
            headers: { Authorization: `Bearer ${API_KEY}` },
            responseType: 'arraybuffer'
        }
    );

    fs.writeFileSync('output.pdb', downloadResponse.data);
    console.log('Structure saved to output.pdb');
}

runPrediction().catch(console.error);