Skip to content

API_REFERENCE_FULL

Nick edited this page Mar 10, 2026 · 1 revision

PATAS API Reference - Complete Documentation

Version: 2.0.0
Base URL: http://localhost:8000/api/v1 (or your production URL)


Authentication

PATAS API does not require authentication by default. For production, it is recommended to configure API key middleware or use a reverse proxy (Caddy, nginx).


Endpoints

1. Health Check

GET /api/v1/health

Check API status and system readiness.

Response:

{
  "status": "ok",
  "version": "2.0.0",
  "core_ready": true
}

Example:

curl http://localhost:8000/api/v1/health

2. Ingest Messages

POST /api/v1/messages/ingest

Ingest messages into PATAS storage. Messages are saved with idempotency via external_id.

Request Body:

{
  "messages": [
    {
      "id": "msg_001",
      "text": "Your message text here",
      "is_spam": true,
      "meta": {
        "sender": "user123",
        "source": "chat456",
        "language": "en",
        "country": "US"
      },
      "timestamp": "2025-01-15T10:00:00Z"
    }
  ]
}

Request Model:

  • messages (required): List[APIMsgInput]
    • id (optional): External message ID (for idempotency)
    • text (required): Message text content
    • is_spam (optional): Spam label (True/False/None)
    • meta (optional): JSON metadata (sender, source, language, country, etc.)
    • timestamp (optional): ISO 8601 timestamp (default: now)

Response:

{
  "ingested_count": 1,
  "last_id": 123,
  "message": "Messages ingested successfully"
}

Examples:

Python:

import requests

response = requests.post(
    "http://localhost:8000/api/v1/messages/ingest",
    json={
        "messages": [
            {
                "id": "msg_001",
                "text": "Buy now! http://spam.com",
                "is_spam": True,
                "meta": {"sender": "user123"}
            }
        ]
    }
)
print(response.json())

cURL:

curl -X POST http://localhost:8000/api/v1/messages/ingest \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "id": "msg_001",
        "text": "Buy now! http://spam.com",
        "is_spam": true
      }
    ]
  }'

JavaScript:

const response = await fetch('http://localhost:8000/api/v1/messages/ingest', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    messages: [
      {
        id: 'msg_001',
        text: 'Buy now! http://spam.com',
        is_spam: true
      }
    ]
  })
});
const data = await response.json();

Errors:

  • 400: Empty message list
  • 500: Database error

3. Mine Patterns

POST /api/v1/patterns/mine

Run pattern mining pipeline on recent messages. Analyzes messages and creates Pattern and Rule objects.

Request Body:

{
  "days": 7,
  "use_llm": false,
  "min_spam_count": 10
}

Request Model:

  • days (optional, default: 7): Number of days to analyze (1-365)
  • use_llm (optional, default: false): Use LLM for pattern discovery
  • min_spam_count (optional, default: 10): Minimum spam messages required for pattern

Response:

{
  "patterns_created": 5,
  "rules_created": 5,
  "messages_processed": 1000,
  "spam_count": 750,
  "ham_count": 250
}

Examples:

Python:

response = requests.post(
    "http://localhost:8000/api/v1/patterns/mine",
    json={"days": 7, "use_llm": True, "min_spam_count": 10}
)
result = response.json()
print(f"Created {result['patterns_created']} patterns")

cURL:

curl -X POST http://localhost:8000/api/v1/patterns/mine \
  -H "Content-Type: application/json" \
  -d '{"days": 7, "use_llm": false}'

Errors:

  • 400: Pattern mining failed (см. detail в ответе)

Notes:

  • If use_llm=true, OPENAI_API_KEY or PATAS_OPENAI_API_KEY is required
  • Semantic mining is enabled by default (if enable_semantic_mining=true in config)

4. List Patterns

GET /api/v1/patterns

Get list of discovered patterns.

Query Parameters:

  • limit (optional, default: 100): Maximum number of patterns (1-1000)
  • offset (optional, default: 0): Pagination offset
  • pattern_type (optional): Filter by type (url, phone, text, meta, signature, keyword)

Response:

[
  {
    "id": 1,
    "type": "url",
    "description": "URL pattern: http://spam.com",
    "examples": ["Buy now! http://spam.com", "Click here: http://spam.com"],
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T10:00:00Z"
  }
]

Examples:

Python:

response = requests.get(
    "http://localhost:8000/api/v1/patterns",
    params={"limit": 50, "pattern_type": "url"}
)
patterns = response.json()

cURL:

curl "http://localhost:8000/api/v1/patterns?limit=50&pattern_type=url"

5. List Rules

GET /api/v1/rules

Get list of rules with optional evaluation metrics.

Query Parameters:

  • status (optional): Filter by status (candidate, shadow, active, deprecated)
  • limit (optional, default: 100): Maximum number of rules (1-1000)
  • offset (optional, default: 0): Pagination offset
  • include_evaluation (optional, default: false): Include latest evaluation metrics

Response:

[
  {
    "id": 1,
    "pattern_id": 1,
    "status": "shadow",
    "sql_expression": "SELECT id FROM messages WHERE text LIKE '%http://spam.com%'",
    "origin": "llm",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T10:00:00Z",
    "evaluation": {
      "hits_total": 100,
      "spam_hits": 95,
      "ham_hits": 5,
      "precision": 0.95,
      "coverage": 0.15,
      "time_period_start": "2025-01-08T10:00:00Z",
      "time_period_end": "2025-01-15T10:00:00Z"
    }
  }
]

Examples:

Python:

response = requests.get(
    "http://localhost:8000/api/v1/rules",
    params={"status": "active", "include_evaluation": True}
)
rules = response.json()

cURL:

curl "http://localhost:8000/api/v1/rules?status=active&include_evaluation=true"

6. Evaluate Shadow Rules

POST /api/v1/rules/eval-shadow

Evaluate shadow rules on recent messages. Computes metrics (precision, coverage, spam_hits, ham_hits).

Request Body:

{
  "rule_ids": [1, 2, 3],
  "days": 7
}

Request Model:

  • rule_ids (optional): List of specific rule IDs to evaluate (empty = all shadow rules)
  • days (optional, default: 7): Time window for evaluation (1-365)

Response:

{
  "evaluated_count": 3,
  "message": "Rules evaluated successfully"
}

Examples:

Python:

response = requests.post(
    "http://localhost:8000/api/v1/rules/eval-shadow",
    json={"rule_ids": [1, 2, 3], "days": 7}
)
result = response.json()

cURL:

curl -X POST http://localhost:8000/api/v1/rules/eval-shadow \
  -H "Content-Type: application/json" \
  -d '{"rule_ids": [1, 2, 3], "days": 7}'

Notes:

  • If rule_ids is not specified, all shadow rules are evaluated
  • Errors when evaluating individual rules are logged but do not interrupt the process

7. Promote Rules

POST /api/v1/rules/promote

Promote shadow rules to active and deprecate degrading active rules. Uses configured aggressiveness profile.

Request Body: (no parameters)

Response:

{
  "promoted_count": 2,
  "deprecated_count": 1,
  "message": "Promotion/rollback completed"
}

Examples:

Python:

response = requests.post("http://localhost:8000/api/v1/rules/promote")
result = response.json()
print(f"Promoted {result['promoted_count']} rules")

cURL:

curl -X POST http://localhost:8000/api/v1/rules/promote

Notes:

  • Uses aggressiveness_profile from configuration (conservative/balanced/aggressive)
  • Shadow rules are promoted if metrics meet profile thresholds
  • Active rules are deprecated if metrics degrade

8. Export Rules

GET /api/v1/rules/export

Export all active rules in the specified format.

Query Parameters:

  • backend (optional, default: "sql"): Export format ("sql" or "rol")

Response (SQL):

SELECT id FROM messages WHERE text LIKE '%http://spam.com%';
SELECT id FROM messages WHERE text LIKE '%buy now%' AND text LIKE '%price%';

Response (ROL):

{
  "rules": [
    {
      "id": 1,
      "sql_expression": "SELECT id FROM messages WHERE text LIKE '%http://spam.com%'",
      "pattern_id": 1
    }
  ]
}

Examples:

Python:

# SQL export
response = requests.get(
    "http://localhost:8000/api/v1/rules/export",
    params={"backend": "sql"}
)
sql_rules = response.text

# ROL export
response = requests.get(
    "http://localhost:8000/api/v1/rules/export",
    params={"backend": "rol"}
)
rol_rules = response.json()

cURL:

# SQL export
curl "http://localhost:8000/api/v1/rules/export?backend=sql"

# ROL export
curl "http://localhost:8000/api/v1/rules/export?backend=rol"

9. Batch Analyze ⭐

POST /api/v1/analyze

Main endpoint для batch анализа. Bundles the complete workflow:

  1. Ingest messages
  2. Run pattern mining (optional)
  3. Evaluate rules (optional)
  4. Export rules (optional)

Perfect for: Small-medium batch analysis, RapidAPI integration, quick prototyping.

Request Body:

{
  "messages": [
    {
      "id": "msg_001",
      "text": "Buy now! http://spam.com",
      "is_spam": true,
      "meta": {"sender": "user123", "source": "chat456"}
    }
  ],
  "run_mining": true,
  "run_evaluation": true,
  "export_backend": "sql"
}

Request Model:

  • messages (required): List[APIMsgInput]
  • run_mining (optional, default: true): Run pattern mining on ingested messages
  • run_evaluation (optional, default: true): Evaluate candidate/shadow rules
  • export_backend (optional): Export format ("sql" or "rol")

Response:

{
  "patterns": [
    {
      "id": 1,
      "type": "url",
      "description": "URL pattern: http://spam.com",
      "group_size": 45,
      "sources_count": 3,
      "senders_count": 2,
      "similarity_reason": "Messages contain the same suspicious URL: http://spam.com",
      "example_report_ids": ["msg_001", "msg_002", "msg_003"],
      "bot_likelihood": 0.85,
      "sql_query": "SELECT id, message_content, sender, source FROM reports WHERE LOWER(message_content) LIKE '%http://spam.com%'"
    }
  ],
  "rules": [
    {
      "id": 1,
      "pattern_id": 1,
      "status": "candidate",
      "sql_expression": "SELECT id FROM messages WHERE text LIKE '%http://spam.com%'",
      "precision": 0.95,
      "coverage": 0.15,
      "hits_total": 100
    }
  ],
  "export": "SELECT id FROM messages WHERE text LIKE '%http://spam.com%';",
  "meta": {
    "ingested_count": 10,
    "patterns_created": 3,
    "rules_created": 3,
    "evaluation_count": 3,
    "timings": {
      "ingest_seconds": 0.123,
      "mining_seconds": 2.456,
      "evaluation_seconds": 0.789,
      "total_seconds": 3.368
    }
  }
}

Examples:

Python:

response = requests.post(
    "http://localhost:8000/api/v1/analyze",
    json={
        "messages": [
            {"id": "1", "text": "Buy now! http://spam.com", "is_spam": True},
            {"id": "2", "text": "Click here: http://spam.com", "is_spam": True}
        ],
        "run_mining": True,
        "run_evaluation": True,
        "export_backend": "sql"
    }
)
result = response.json()

# Access patterns
for pattern in result["patterns"]:
    print(f"Pattern: {pattern['description']}")
    print(f"SQL: {pattern['sql_query']}")

# Access export
if result.get("export"):
    print(f"Export:\n{result['export']}")

cURL:

curl -X POST http://localhost:8000/api/v1/analyze \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"id": "1", "text": "Buy now! http://spam.com", "is_spam": true},
      {"id": "2", "text": "Click here: http://spam.com", "is_spam": true}
    ],
    "run_mining": true,
    "run_evaluation": true,
    "export_backend": "sql"
  }'

JavaScript:

const response = await fetch('http://localhost:8000/api/v1/analyze', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    messages: [
      { id: '1', text: 'Buy now! http://spam.com', is_spam: true },
      { id: '2', text: 'Click here: http://spam.com', is_spam: true }
    ],
    run_mining: true,
    run_evaluation: true,
    export_backend: 'sql'
  })
});
const result = await response.json();

// Access patterns
result.patterns.forEach(pattern => {
  console.log(`Pattern: ${pattern.description}`);
  console.log(`SQL: ${pattern.sql_query}`);
});

Errors:

  • 400: Empty messages list
  • 500: Internal server error

Notes:

  • For large datasets, use lower-level endpoints
  • Semantic mining включен по умолчанию (если доступен embedding engine)
  • LLM is used automatically if OPENAI_API_KEY is set and run_mining=true

Error Handling

All endpoints return standard HTTP status codes:

  • 200: Success
  • 400: Bad Request (invalid data)
  • 404: Not Found (resource not found)
  • 500: Internal Server Error

Error format:

{
  "detail": "Error message here"
}

Example error handling (Python):

try:
    response = requests.post("http://localhost:8000/api/v1/analyze", json=data)
    response.raise_for_status()
    result = response.json()
except requests.exceptions.HTTPError as e:
    error_detail = e.response.json().get("detail", "Unknown error")
    print(f"Error: {error_detail}")

Rate Limiting

PATAS API does not have built-in rate limiting. For production, it is recommended to configure rate limiting at the reverse proxy level (Caddy, nginx) or use middleware.


Versioning

Current API version: 2.0.0

All endpoints are under /api/v1/. Future breaking changes will be in /api/v2/.


Additional Resources

Clone this wiki locally