Skip to content

API Reference

API documentation for the SPOT Platform.

Full OpenAPI specification is available here.

System Requirements

  • RabbitMQ: Required for analysis submission (/api/v1/analyze) and status queries
  • Workflow management: HTTP-only (no RabbitMQ dependency)

Base URL

  • Development: http://localhost:8001/api/v1
  • Production: https://your-domain.com/api/v1

Authentication

All API endpoints require authentication. OAuth2 with JWT tokens:

# Get token
curl -X POST http://localhost:8001/auth/token \
  -d "username=user&password=pass&grant_type=password"

# Use token
curl -H "Authorization: Bearer <token>" \
  http://localhost:8001/api/v1/analyze

Core Endpoints

Email Analysis

Submit Analysis

POST /api/v1/analyze

Request:

{
  "email": {
    "headers": {
      "subject": "Email subject",
      "sender": "sender@domain.com",
      "recipients": ["recipient@domain.com"],
      "date": "2024-01-15T14:30:00Z"
    },
    "body_text": "Email body"
  },
  "workflow_id": "default-workflow"
}

Response:

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "email_id": "email-172af91a",
  "status": "queued",
  "workflow": "default-workflow",
  "message": "Email analysis job queued successfully"
}

Check Status

GET /api/v1/analyze/{job_id}

Response:

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "email_id": "email-172af91a",
  "status": "completed",
  "result": {
    "is_phishing": false,
    "threat_level": "none",
    "confidence": 0.15,
    "summary": "Email appears legitimate",
    "recommended_action": "allow",
    "indicators": []
  }
}

Status values:

  • queued: Waiting to be processed
  • processing: Analysis running
  • completed: Finished successfully
  • failed: Analysis encountered error

Health Checks

Platform Health

GET /health

Response:

{
  "status": "healthy",
  "service": "api-gateway",
  "version": "2.0.0",
  "features": {
    "configuration_api": true,
    "database_config": false,
    "oauth": true,
    "rate_limiting": false,
    "audit_logging": true
  }
}

Configuration

Get Configuration

GET /api/v1/config

Response:

{
  "analyzer": {
    "timeout_ms": 30000,
    "min_confidence": 0.7
  },
  "workflow": {
    "default_workflow_id": "default-workflow",
    "max_retries": 3
  }
}

Data Models

Email

{
  headers: {
    subject: string
    sender: string              // Valid email address
    recipients: string[]        // At least one
    cc?: string[]
    bcc?: string[]
    date: string               // ISO 8601
    raw_headers?: object
  }
  body_text?: string           // At least one of body_text
  body_html?: string           // or body_html required
  attachments?: Attachment[]
  language?: string            // ISO 639-1 code
  source?: string
}

AnalysisResult

{
  is_phishing: boolean
  threat_level: "none" | "low" | "medium" | "high" | "critical"
  confidence: number          // 0.0 to 1.0
  summary: string
  recommended_action: "allow" | "flag" | "review" | "quarantine"
  indicators: Indicator[]
}

Indicator

{
  type: string               // domain_spoofing, urgency_language, etc.
  value: string              // Description of indicator
  confidence: number         // 0.0 to 1.0
}

Error Responses

Standard error format:

{
  "detail": "Error message",
  "type": "validation_error"
}

Common status codes:

  • 200: Success
  • 400: Bad Request
  • 401: Unauthorized
  • 404: Not Found
  • 422: Validation Error
  • 500: Internal Server Error

Rate Limiting

Rate limiting is disabled by default. When enabled via ENABLE_RATE_LIMITING=true:

  • 100 requests per 60 seconds per client

Pagination

For list endpoints:

GET /api/v1/endpoint?skip=0&limit=20

Response:

{
  "items": [...],
  "total": 100
}

Examples

Python

import requests

# Authenticate
auth_response = requests.post(
    "http://localhost:8001/auth/token",
    data={
        "username": "demo",
        "password": "demo123",
        "grant_type": "password"
    }
)
token = auth_response.json()["access_token"]

# Analyze email
headers = {"Authorization": f"Bearer {token}"}
response = requests.post(
    "http://localhost:8001/api/v1/analyze",
    json={
        "email": {
            "headers": {
                "subject": "Test",
                "sender": "test@example.com",
                "recipients": ["user@company.com"],
                "date": "2024-01-15T14:30:00Z"
            },
            "body_text": "Test email"
        }
    },
    headers=headers
)

job_id = response.json()["job_id"]

# Check status
status_response = requests.get(
    f"http://localhost:8001/api/v1/analyze/{job_id}",
    headers=headers
)
result = status_response.json()

cURL

# Get token
TOKEN=$(curl -s -X POST http://localhost:8001/auth/token \
  -d "username=demo&password=demo123&grant_type=password" | \
  jq -r '.access_token')

# Submit analysis
JOB_ID=$(curl -s -X POST http://localhost:8001/api/v1/analyze \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": {
      "headers": {
        "subject": "Test",
        "sender": "test@example.com",
        "recipients": ["user@company.com"],
        "date": "2024-01-15T14:30:00Z"
      },
      "body_text": "Test email"
    }
  }' | jq -r '.job_id')

# Check status
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8001/api/v1/analyze/$JOB_ID

JavaScript

// Authenticate
const authResponse = await fetch('http://localhost:8001/auth/token', {
  method: 'POST',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  body: 'username=demo&password=demo123&grant_type=password'
});
const {access_token} = await authResponse.json();

// Analyze email
const response = await fetch('http://localhost:8001/api/v1/analyze', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${access_token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email: {
      headers: {
        subject: 'Test',
        sender: 'test@example.com',
        recipients: ['user@company.com'],
        date: '2024-01-15T14:30:00Z'
      },
      body_text: 'Test email'
    }
  })
});

const {job_id} = await response.json();

// Check status
const statusResponse = await fetch(
  `http://localhost:8001/api/v1/analyze/${job_id}`,
  {headers: {'Authorization': `Bearer ${access_token}`}}
);
const result = await statusResponse.json();

OpenAPI Specification

Full OpenAPI specification is available here.