📖 API Documentation

RESTful API for fast, accurate protein disorder prediction

Base URL

https://api.proteinclassifier.com/v1

Authentication

API Key Authentication (Classification Endpoints)

All classification requests require authentication using an API key passed in the X-API-Key header.

X-API-Key: your_api_key_here

Magic Link Authentication (API Key Management)

To manage your API keys (create, rotate, revoke), use our passwordless magic link authentication system:

Authentication Flow

  1. Request Magic Link: Submit your email to receive a one-time login link (15-minute TTL)
  2. Verify Token: Click the magic link or exchange the token for JWT access/refresh tokens
  3. Access API Keys: Use the access token (1-hour lifetime) to manage your API keys
  4. Refresh Token: Use the refresh token (30-day lifetime) to obtain new access tokens without re-authentication

Step 1: Request Magic Link

curl -X POST https://api.proteinclassifier.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "your.email@example.com"}'

Response:

{
  "message": "Magic link sent to your email",
  "email": "your.email@example.com"
}

Step 2: Verify Magic Link Token

After receiving the email, extract the token from the magic link and verify it:

curl -X POST https://api.proteinclassifier.com/api/v1/auth/verify \
  -H "Content-Type: application/json" \
  -d '{"token": "YOUR_TOKEN_FROM_EMAIL"}'

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "abc123def456...",
  "token_type": "bearer",
  "expires_in": 3600
}

Step 3: Refresh Access Token (Optional)

When your access token expires, use the refresh token to get a new one:

curl -X POST https://api.proteinclassifier.com/api/v1/auth/refresh \
  -H "X-Refresh-Token: YOUR_REFRESH_TOKEN"
Get Started: Visit Getting Started to create your account and get your first API key using magic link authentication.

Rate Limits

Free Tier

  • Daily Limit: 1,000 sequences per day
  • Rate Limit: 100 requests per minute
  • Max Batch Size: 50 sequences per request
  • Response Time: <50ms per sequence

Premium Tier

  • Daily Limit: Unlimited sequences
  • Rate Limit: 1,000 requests per minute
  • Max Batch Size: 100 sequences per request
  • Priority Processing: Guaranteed <30ms per sequence
  • Support: Email support within 24 hours

View Pricing →

API Key Management

Self-service API key management endpoints. All endpoints require JWT Bearer token authentication obtained through the magic link authentication flow.

POST /api/v1/api-keys/register

Create a new API key for accessing classification endpoints.

Request Headers

Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

Request Body

{
  "label": "Production API"  // Optional: Descriptive label for your key
}

Example Request

curl -X POST https://api.proteinclassifier.com/api/v1/api-keys/register \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"label": "Production API"}'

Response

{
  "api_key": "pk_live_abc123def456...",  
  "api_key_id": "key_xyz789",
  "created_at": "2024-01-01T10:00:00Z",
  "label": "Production API"
}
⚠️ IMPORTANT: Save the api_key value immediately! It is only shown once and cannot be retrieved later.

GET /api/v1/api-keys/list

List all your API keys (active and revoked).

Request Headers

Authorization: Bearer YOUR_ACCESS_TOKEN

Example Request

curl -X GET https://api.proteinclassifier.com/api/v1/api-keys/list \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

{
  "keys": [
    {
      "api_key_id": "key_xyz789",
      "label": "Production API",
      "status": "active",
      "created_at": "2024-01-01T10:00:00Z",
      "last_used_at": "2024-01-05T14:30:00Z",
      "tier": "free"
    },
    {
      "api_key_id": "key_old456",
      "label": "Development API",
      "status": "revoked",
      "created_at": "2023-12-01T10:00:00Z",
      "last_used_at": "2024-01-01T09:00:00Z",
      "tier": "free"
    }
  ],
  "total": 2
}

POST /api/v1/api-keys/rotate

Replace an existing API key with a new one. The old key is immediately revoked.

Request Headers

Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

Request Body

{
  "api_key_id": "key_xyz789"
}

Example Request

curl -X POST https://api.proteinclassifier.com/api/v1/api-keys/rotate \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"api_key_id": "key_xyz789"}'

Response

{
  "api_key": "pk_live_new789xyz...",
  "api_key_id": "key_new123",
  "created_at": "2024-01-05T15:00:00Z",
  "label": "Production API (Rotated)"
}
⚠️ IMPORTANT: The old key is immediately revoked. Update your applications with the new key immediately!

POST /api/v1/api-keys/revoke

Permanently deactivate an API key.

Request Headers

Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

Request Body

{
  "api_key_id": "key_xyz789"
}

Example Request

curl -X POST https://api.proteinclassifier.com/api/v1/api-keys/revoke \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"api_key_id": "key_xyz789"}'

Response

{
  "revoked": true,
  "api_key_id": "key_xyz789"
}
⚠️ WARNING: This action cannot be undone. The key will be permanently deactivated within 5 minutes system-wide.

Admin Endpoints

Admin endpoints for monitoring and managing API usage. All endpoints require JWT Bearer token authentication obtained through the magic link authentication flow.

GET /admin/audit-logs

Query API usage audit logs for compliance monitoring, troubleshooting, and usage tracking.

Request Headers

Authorization: ******

Query Parameters

  • start_time (required) - ISO 8601 timestamp for start of query window
  • end_time (required) - ISO 8601 timestamp for end of query window
  • api_key (optional) - Filter by specific API key ID
  • status (optional) - Filter by 'success' or 'error'
  • limit (optional) - Results per page (default: 100, max: 1000)
  • next_token (optional) - For pagination

Example Request

curl -X GET "https://api.proteinclassifier.com/admin/audit-logs?start_time=2024-01-01T00:00:00Z&end_time=2024-01-02T00:00:00Z&status=success&limit=50" \
  -H "Authorization: ******"

Response

{
  "logs": [
    {
      "timestamp": "2024-01-01T10:00:00Z",
      "api_key": "****1234",
      "sequence_length": 0,
      "processing_time_ms": 45.5,
      "status": "success",
      "error_code": null,
      "ip_address": "192.168.1.0/24"
    }
  ],
  "total": 1,
  "next_token": null
}

Response Fields

  • timestamp - Request timestamp (ISO 8601)
  • api_key - Masked API key (last 4 chars visible)
  • sequence_length - Total length of sequences processed
  • processing_time_ms - Processing time in milliseconds
  • status - Request status ('success' or 'error')
  • error_code - Error code if request failed
  • ip_address - Masked IP address (privacy-protected)

Security & Privacy

  • API keys masked (only last 4 characters visible)
  • IP addresses masked for privacy (first 3 octets only)
  • No sequence content ever exposed
  • 30-day retention window (older records not available)
  • Audit log access is itself logged for security
  • Rate limited to 10 queries/minute per admin
Use Cases:
  • Monitor API usage patterns and trends
  • Troubleshoot API errors and performance issues
  • Generate compliance reports and audits
  • Track usage for billing and analytics

Classification Endpoints

POST /v1/classify

Classify one or more protein sequences as disordered or structured.

Request Headers

Content-Type: application/json
X-API-Key: your_api_key_here

Request Body

{
  "sequences": [
    {
      "id": "string",      // Unique identifier for the sequence
      "sequence": "string" // Amino acid sequence (single-letter codes)
    }
  ]
}

Example Request

curl -X POST https://api.proteinclassifier.com/v1/classify \
  -H "X-API-Key: your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "sequences": [
      {
        "id": "protein1",
        "sequence": "MKVLWAASLLLLASAARA"
      },
      {
        "id": "protein2",
        "sequence": "GSQEVHPNSPSDEAGPLGEGL"
      }
    ]
  }'

Response

{
  "results": [
    {
      "id": "protein1",
      "sequence": "MKVLWAASLLLLASAARA",
      "classification": "structured",
      "confidence": 0.87,
      "conditions_met": 6,
      "threshold": 5,
      "features": {
        "hydrophobicity": 0.72,
        "flexibility": 0.31,
        "h_bond_potential": 0.58,
        "net_charge": 0.11,
        "shannon_entropy": 2.45,
        "proline_freq": 0.0,
        "bulky_hydrophobic_freq": 0.44
      },
      "processing_time_ms": 12.3
    },
    {
      "id": "protein2",
      "sequence": "GSQEVHPNSPSDEAGPLGEGL",
      "classification": "disordered",
      "confidence": 0.73,
      "conditions_met": 3,
      "threshold": 5,
      "features": {
        "hydrophobicity": 0.18,
        "flexibility": 0.67,
        "h_bond_potential": 0.42,
        "net_charge": 0.19,
        "shannon_entropy": 2.89,
        "proline_freq": 0.14,
        "bulky_hydrophobic_freq": 0.09
      },
      "processing_time_ms": 11.8
    }
  ],
  "total_sequences": 2,
  "total_time_ms": 24.1,
  "api_version": "1.0.0"
}

Response Fields

  • id - Your provided sequence identifier
  • sequence - The input amino acid sequence
  • classification - Either "structured" or "disordered"
  • confidence - Classification confidence (0.0-1.0)
  • conditions_met - Number of biophysical conditions satisfied (0-7)
  • threshold - Threshold for structured classification (default: 5)
  • features - Computed biophysical features (normalized 0-1)
  • processing_time_ms - Time to process this sequence in milliseconds

HTTP Status Codes

  • 200 OK - Successful classification
  • 400 Bad Request - Invalid request format or sequence
  • 401 Unauthorized - Missing or invalid API key
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

GET /v1/health

Check API service health and status.

Example Request

curl -X GET https://api.proteinclassifier.com/v1/health

Response

{
  "status": "healthy",
  "version": "1.0.0",
  "uptime_seconds": 3456789,
  "timestamp": "2025-12-30T00:56:51Z"
}

GET /v1/stats

Retrieve your API usage statistics (requires authentication).

Request Headers

X-API-Key: your_api_key_here

Example Request

curl -X GET https://api.proteinclassifier.com/v1/stats \
  -H "X-API-Key: your_key_here"

Response

{
  "user_id": "user_abc123",
  "tier": "free",
  "usage": {
    "sequences_today": 347,
    "sequences_this_month": 12450,
    "requests_today": 89,
    "requests_this_month": 3201
  },
  "limits": {
    "daily_sequences": 1000,
    "requests_per_minute": 100,
    "max_batch_size": 50
  },
  "remaining": {
    "sequences_today": 653,
    "requests_this_minute": 98
  }
}

Code Examples

Python

import requests
import json

API_KEY = "your_api_key_here"
BASE_URL = "https://api.proteinclassifier.com/v1"

def classify_sequences(sequences):
    """
    Classify protein sequences.
    
    Args:
        sequences: List of dicts with 'id' and 'sequence' keys
    
    Returns:
        API response with classification results
    """
    headers = {
        "X-API-Key": API_KEY,
        "Content-Type": "application/json"
    }
    
    payload = {"sequences": sequences}
    
    response = requests.post(
        f"{BASE_URL}/classify",
        headers=headers,
        json=payload
    )
    
    response.raise_for_status()
    return response.json()

# Example usage
sequences = [
    {"id": "protein1", "sequence": "MKVLWAASLLLLASAARA"},
    {"id": "protein2", "sequence": "GSQEVHPNSPSDEAGPLGEGL"}
]

results = classify_sequences(sequences)

for result in results["results"]:
    print(f"{result['id']}: {result['classification']} "
          f"(confidence: {result['confidence']:.2f})")

JavaScript (Node.js)

const axios = require('axios');

const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.proteinclassifier.com/v1';

async function classifySequences(sequences) {
  try {
    const response = await axios.post(
      `${BASE_URL}/classify`,
      { sequences },
      {
        headers: {
          'X-API-Key': API_KEY,
          'Content-Type': 'application/json'
        }
      }
    );
    
    return response.data;
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
    throw error;
  }
}

// Example usage
const sequences = [
  { id: 'protein1', sequence: 'MKVLWAASLLLLASAARA' },
  { id: 'protein2', sequence: 'GSQEVHPNSPSDEAGPLGEGL' }
];

classifySequences(sequences)
  .then(results => {
    results.results.forEach(result => {
      console.log(`${result.id}: ${result.classification} ` +
                  `(confidence: ${result.confidence.toFixed(2)})`);
    });
  });

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

const (
    APIKey  = "your_api_key_here"
    BaseURL = "https://api.proteinclassifier.com/v1"
)

type Sequence struct {
    ID       string `json:"id"`
    Sequence string `json:"sequence"`
}

type ClassifyRequest struct {
    Sequences []Sequence `json:"sequences"`
}

type ClassifyResponse struct {
    Results []struct {
        ID             string             `json:"id"`
        Sequence       string             `json:"sequence"`
        Classification string             `json:"classification"`
        Confidence     float64            `json:"confidence"`
        ConditionsMet  int                `json:"conditions_met"`
        Features       map[string]float64 `json:"features"`
    } `json:"results"`
}

func classifySequences(sequences []Sequence) (*ClassifyResponse, error) {
    reqBody := ClassifyRequest{Sequences: sequences}
    jsonData, err := json.Marshal(reqBody)
    if err != nil {
        return nil, err
    }

    req, err := http.NewRequest("POST", BaseURL+"/classify", bytes.NewBuffer(jsonData))
    if err != nil {
        return nil, err
    }

    req.Header.Set("X-API-Key", APIKey)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }

    var result ClassifyResponse
    err = json.Unmarshal(body, &result)
    return &result, err
}

func main() {
    sequences := []Sequence{
        {ID: "protein1", Sequence: "MKVLWAASLLLLASAARA"},
        {ID: "protein2", Sequence: "GSQEVHPNSPSDEAGPLGEGL"},
    }

    results, err := classifySequences(sequences)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }

    for _, result := range results.Results {
        fmt.Printf("%s: %s (confidence: %.2f)\n",
            result.ID, result.Classification, result.Confidence)
    }
}

cURL

# Single sequence
curl -X POST https://api.proteinclassifier.com/v1/classify \
  -H "X-API-Key: your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "sequences": [
      {"id": "test1", "sequence": "MKVLWAASLLLLASAARA"}
    ]
  }'

# Multiple sequences
curl -X POST https://api.proteinclassifier.com/v1/classify \
  -H "X-API-Key: your_key_here" \
  -H "Content-Type: application/json" \
  -d @sequences.json

# Check usage stats
curl -X GET https://api.proteinclassifier.com/v1/stats \
  -H "X-API-Key: your_key_here"

Error Handling

Error Response Format

{
  "error": {
    "code": "INVALID_SEQUENCE",
    "message": "Sequence contains invalid amino acid characters",
    "details": {
      "sequence_id": "protein1",
      "invalid_characters": ["X", "Z"]
    }
  }
}

Common Error Codes

Code HTTP Status Description
INVALID_API_KEY 401 API key is missing, invalid, or expired
INVALID_TOKEN 401 JWT access token is missing, invalid, or expired
INVALID_REFRESH_TOKEN 401 Refresh token is missing, invalid, or expired
INVALID_MAGIC_LINK 401 Magic link token is invalid, expired, or already used
RATE_LIMIT_EXCEEDED 429 Too many requests, slow down
INVALID_SEQUENCE 400 Sequence contains invalid characters
BATCH_SIZE_EXCEEDED 400 Too many sequences in single request
QUOTA_EXCEEDED 429 Daily sequence limit reached
SERVER_ERROR 500 Internal server error, try again later

Best Practices

  • Implement exponential backoff for rate limit errors (429)
  • Validate sequences before sending (only standard 20 amino acids)
  • Use batch processing to minimize API calls and improve efficiency
  • Cache results for identical sequences to reduce API usage
  • Monitor usage via the /stats endpoint
  • Handle errors gracefully with appropriate user feedback

Ready to Start?

Get your free API key and start classifying proteins today

Get API Key Compare Performance