📖 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
- Request Magic Link: Submit your email to receive a one-time login link (15-minute TTL)
- Verify Token: Click the magic link or exchange the token for JWT access/refresh tokens
- Access API Keys: Use the access token (1-hour lifetime) to manage your API keys
- 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"
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
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"
}
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)"
}
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"
}
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 windowend_time(required) - ISO 8601 timestamp for end of query windowapi_key(optional) - Filter by specific API key IDstatus(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 processedprocessing_time_ms- Processing time in millisecondsstatus- Request status ('success' or 'error')error_code- Error code if request failedip_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
- 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 identifiersequence- The input amino acid sequenceclassification- 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 classification400 Bad Request- Invalid request format or sequence401 Unauthorized- Missing or invalid API key429 Too Many Requests- Rate limit exceeded500 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
/statsendpoint - 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