Skip to content

SPOT SDK

The SPOT SDK is the Python package for writing SPOT plugins. SPOT runs each plugin as a container and calls the plugin's /internal/* routes with the plugin's own token. The SDK holds everything both sides share:

  • the contract: the email view, verdicts and signals, the workflow policy, the results and the plugin manifest (Pydantic models);
  • the parser that core runs on every message at intake (spot_sdk.mime), so plugins and their tests see the same view;
  • the plugin runtime: create_plugin_app builds the FastAPI app with the routes core calls, and PluginSettings reads the token and the settings core gives the container;
  • the clients: SpotClient (the gateway), KnowledgeClient (the Knowledge Store) and LLMClient (OpenAI-compatible chat models);
  • test helpers: views from .eml files, fakes of the three clients, and assert_contract.

Install

Pin the exact version:

pip install spot-sdk-python==2.0.0

It needs Python 3.11 to 3.15. SDK 2 implements plugin contract 2 and works with SPOT 2.0; plugins written for SDK 1 must be ported (see Migrating from 1.x).

Plugin kinds

Kind What it does Handler Route core calls
analyzer gives a verdict on an email analyze(request, settings) -> AnalyzerVerdict POST /internal/analyze
context_provider fills the Knowledge Store with company data sync(settings) -> int POST /internal/sync, GET /internal/state
mail_retriever pushes raw messages to SPOT none: it calls SpotClient.ingest none
responder acts on a workflow's verdict respond(request, settings) -> None POST /internal/respond

A plugin has exactly one kind. Every plugin also answers GET /health and GET /manifest.

A minimal analyzer

from spot_sdk import (
    AnalyzerVerdict,
    AnalyzeRequest,
    Egress,
    Manifest,
    PluginKind,
    PluginSettings,
    Signal,
    VerdictClass,
    create_plugin_app,
)
from spot_sdk.signals import AUTH_DMARC_FAIL

MANIFEST = Manifest(
    id="analyzer-dmarc",
    version="1.0.0",
    kind=PluginKind.ANALYZER,
    egress=Egress.NONE,
)


def analyze(request: AnalyzeRequest, settings: PluginSettings) -> AnalyzerVerdict:
    failed = [
        result
        for result in request.email.authentication
        if result.method == "dmarc" and result.result == "fail"
    ]
    if not failed:
        return AnalyzerVerdict(verdict=VerdictClass.BENIGN, score=10, confidence=60)
    return AnalyzerVerdict(
        verdict=VerdictClass.SUSPICIOUS,
        score=70,
        confidence=80,
        signals=[Signal(name=AUTH_DMARC_FAIL, weight=60, evidence="dmarc=fail")],
        summary="The sender's domain fails DMARC",
    )


app = create_plugin_app(MANIFEST, PluginSettings, analyze=analyze)

Run it with uvicorn analyzer_dmarc:app --host 0.0.0.0 --port 8000.

Where next

  • Overview: how core and plugins talk, and the models of the contract.
  • Writing plugins: one section per kind, settings and secrets, the manifest and the Dockerfile, testing.
  • Reference: the email view and its anomalies, signals, the clients and the test helpers.
  • Migrating from 1.x: every removed name and its replacement.
  • Maintaining the SDK: working on this repository and releasing it.

The platform's own documentation covers installing plugins, workflows and verdict policies: SPOT platform documentation.