PyGuard

API reference

The PyGuard backend is a FastAPI application that exposes a small HTTP surface. Most interactions happen through Slack, which calls into the same process_chat_message function internally, so the HTTP API is there for programmatic access and for the (existing) web chat UI.

  • Base URL (local): http://127.0.0.1:8000
  • Authentication: none in beta. Run the backend on localhost or behind your own VPN.

POST /api/chat

The main conversational endpoint. Runs the full Memory Agent plus fraud or follow-up pipeline and returns a single ChatResponse.

Request body (ChatRequest)

{
  "message": "Generate a fraud intelligence report.",
  "user": "alice@example.com",
  "source": "chat",
  "subject": "monthly-review"
}

| Field | Type | Required | Notes | | --- | --- | --- | --- | | message | string | yes | The user's message. | | user | string | no | Identifier for the sender. Defaults to "default". | | source | string | no | Channel identifier for the message history. Defaults to "chat". | | subject | string or null | no | Optional thread-like grouping; used by the message history helpers. |

The HTTP endpoint does not currently take slack_thread_ts or slack_channel_id. Those are only injected by the Slack service and are used for the in-thread follow-up routing.

Response body (ChatResponse)

{
  "status": "success",
  "type": "fraud_analysis",
  "response": "... short narrative summary ...",
  "rule_created": null,
  "fraud_analysis": {
    "verification_passed": true,
    "attempts": 1
  },
  "pdf_path": "/abs/path/to/backend/reports/fraud_report_<ts>/fraud_report_<ts>.pdf",
  "report_id": 12,
  "report_version": 1,
  "error": null
}

| Field | Type | Notes | | --- | --- | --- | | status | "success" | "error" | Top-level result indicator. | | type | string | One of action_execution, rule_creation, both, user_management, fraud_analysis, report_qa, report_edit, conversational, error. | | response | string | The assistant's final user-facing text. | | rule_created | object or null | Populated when the Memory Agent created a rule. | | fraud_analysis | object or null | Verification metadata for fraud runs. | | pdf_path | string or null | Absolute path to the generated or updated PDF when applicable. | | report_id | number or null | Matching row id in fraud_reports when this response is tied to a persisted report. | | report_version | number or null | Current version of the bundle (bumps on every successful edit). | | error | string or null | Error text when status == "error". |

Example

curl -s http://127.0.0.1:8000/api/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"Generate a fraud intelligence report","user":"alice"}' \
  | jq

GET /api/history

Returns recent rows from the messages table (all sources combined). Useful for debugging the conversation log.

curl -s "http://127.0.0.1:8000/api/history?limit=10" | jq

Query parameters

| Parameter | Default | Notes | | --- | --- | --- | | limit | 50 | Maximum number of rows to return. |

Response

{
  "messages": [
    {
      "id": 42,
      "user": "U0ALE1GP7DF",
      "source": "slack",
      "input": "Generate a fraud intelligence report.",
      "subject": null,
      "created_at": "2026-04-20T17:41:03.118Z"
    }
  ]
}

GET /api/rules

Returns every row from the rules table. Useful for seeing what preferences the Memory Agent has persisted for future turns.

curl -s "http://127.0.0.1:8000/api/rules" | jq

GET /api/health

Liveness check.

curl -s "http://127.0.0.1:8000/api/health"
# {"status":"ok"}

Behind the scenes

The Slack service in backend/slack/service.py calls process_chat_message directly with two extra kwargs (slack_thread_ts, slack_channel_id) that are not exposed through the HTTP route. This is how the in-thread Q&A and edit routing works. If you build a new surface (WhatsApp, a web UI, anything else), the pattern is the same: call process_chat_message directly with whatever thread or conversation identifier makes sense for your surface.

Deployment

The backend is a standard uvicorn-served FastAPI app. You can deploy it anywhere you can install Python 3.11, tectonic, and a persistent file system for the reports/ bundles. Because PyGuard writes to disk per request and persists SQLite state, a single long-lived process is the simplest topology. A container image with tectonic preinstalled is recommended for production-style deployments.

See /setup for deploying the marketing site to Vercel; the backend itself is not currently deployed there.