This FastAPI example wires the Siftfy spam-detection API into a Python contact endpoint. The handler scores incoming message text with the official AsyncSiftfy client, drops submissions scored above the response's own `max_confidence`, queues everything from 0.50 up to that ceiling for review, and delivers the rest. It fails open on provider timeouts so a brief outage never silently loses a real lead.
A runnable FastAPI route that scores a contact-form message with the official Python SDK before deciding whether to deliver, queue, or drop it.
main.pypython
python
# pip install fastapi uvicorn siftfyimport os
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
from siftfy import AsyncSiftfy
app = FastAPI()
client = AsyncSiftfy(api_key=os.environ["SIFTFY_KEY"], timeout=2.0)
classContactSubmission(BaseModel):
email: EmailStr
message: str@app.post("/contact")asyncdefcontact(payload: ContactSubmission) -> dict[str, bool]:
probability, ceiling = 0.0, Nonetry:
result = await client.predict(payload.message)
probability, ceiling = result.spam_probability, result.max_confidence
except Exception:
# Fail open so a provider outage does not lose a real lead.
probability = 0.0# Drop only ABOVE the ceiling the response reports. At the ceiling the score# is censored, so a fixed constant never fires on the model's own opinion.if ceiling isnotNoneand probability > ceiling:
return {"ok": True}
if probability >= 0.50:
await queue_for_review(payload.email, payload.message, probability)
else:
await deliver_to_inbox(payload.email, payload.message)
return {"ok": True}
Production notes
01`max_confidence` is the highest score the model is allowed to return on its own word; only a score above it is more than the model's opinion.
02Use the official SDK when you want typed responses and retry behavior.
03Keep the same success response for spam and clean messages.
04Queue borderline submissions instead of dropping them until thresholds are proven.
Common questions
How do I add Siftfy spam detection to a FastAPI app?
Install the `siftfy` Python package, instantiate `AsyncSiftfy` with your API key, then call `client.predict(text)` inside an async route handler before forwarding the submission downstream. The full handler is shown in the code block above.
What spam-probability thresholds should I use in FastAPI?
Take the drop threshold from the response, not from a constant. `max_confidence` is the highest score the model is allowed to return on its own, so a score above it carries evidence beyond the model — that is the only safe place to drop. A hard-coded 0.85 sits above that ceiling and never fires. Start the review queue at 0.50 and re-tune that floor after a week of queue audits.
How do I handle Siftfy API timeouts in FastAPI?
Set a tight client timeout (2 seconds is typical), wrap the predict call in try/except, and fall open by treating any failure as probability 0.0. Real visitors should never lose a submission to a transient classification outage.
Can I run this on serverless FastAPI deployments?
Yes. The same handler works on AWS Lambda (Mangum), Vercel Python runtime, and self-hosted ASGI servers. Keep the AsyncSiftfy client module-scoped so it's reused across warm invocations.