Skip to content

API Reference

Complete API documentation for the Alphapy Discord Bot FastAPI server.

All API endpoints are prefixed with /api unless otherwise noted.

  • Health & Status: Basic health checks and monitoring (/api/health, /api/health/history)
  • Metrics & Analytics: Dashboard metrics and command analytics (/api/dashboard/metrics, /top-commands)
  • Dashboard Configuration: Web dashboard endpoints for managing settings, onboarding, auto-moderation (requires Supabase JWT)
  • Auto-Moderation: Complete auto-moderation rule management with analytics (/api/dashboard/{guild_id}/automod/*)
  • Onboarding Management: Questions, rules, and flow configuration (/api/dashboard/{guild_id}/onboarding/*)
  • Reminder Management: User-facing reminder CRUD operations (requires API key + user ID)
  • Exports: CSV export endpoints for tickets and FAQ
  • Webhooks: Incoming webhooks from Core-API (app-reflections, revoke-reflection); validated via X-Webhook-Signature

Note for Mind Dashboard: Mind primarily uses:

  • /api/dashboard/metrics (or /api/metrics alias) for live metrics
  • /api/health for health checks
  • Dashboard configuration endpoints for web UI management
  • /api/observability for internal/ops observability snapshots (not part of Alphapy dashboard configuration flows)

Most endpoints require authentication via:

  • Supabase JWT: Authorization: Bearer <token> (preferred)
  • API Key: X-API-Key (fallback when JWT is not present/invalid and API_KEY is configured)

Important:

  • User identity is derived from verified JWT claims (sub) only.
  • X-User-Id is not trusted for authentication or authorization.

Example (JWT):

Terminal window
curl -H "Authorization: Bearer <supabase_jwt>" \
https://your-bot-url/api/reminders/123456789

Dashboard endpoints example:

Terminal window
curl -H "Authorization: Bearer supabase_token" \
https://your-bot-url/api/dashboard/123456789/settings

Enhanced health check endpoint with detailed metrics.

Response:

{
"service": "alphapy",
"version": "3.6.0",
"uptime_seconds": 3600,
"db_status": "ok",
"timestamp": "2026-01-21T12:00:00Z",
"guild_count": 2,
"active_commands_24h": 150,
"gpt_status": "operational",
"database_pool_size": 5
}

Simple status check endpoint (legacy, no authentication required).

Response:

{
"online": true,
"latency": 0,
"uptime": "60 min"
}

Internal observability snapshot endpoint.

This endpoint is intended for Mind/internal monitoring and operations use. It is not a /api/dashboard/* configuration endpoint. Requires X-Api-Key with the configured service key.

Returns rolling in-memory request metrics for API and webhook traffic:

  • success rate
  • latency percentiles (p50, p95, p99)
  • request counts

Response:

{
"api": {
"requests": 120,
"success_rate": 0.9917,
"latency_ms": { "p50": 12.4, "p95": 43.9, "p99": 81.2 }
},
"webhooks": {
"requests": 45,
"success_rate": 1.0,
"latency_ms": { "p50": 7.1, "p95": 18.0, "p99": 28.3 }
}
}

All responses now include an X-Request-ID header for request correlation.

Fields:

  • service: Service name
  • version: Bot version
  • uptime_seconds: Uptime in seconds
  • db_status: Database status (ok, not_initialized, or error:...)
  • timestamp: ISO timestamp of check
  • guild_count: Number of guilds bot is connected to (optional)
  • active_commands_24h: Number of commands executed in last 24 hours (optional)
  • gpt_status: Grok/LLM service status (operational, degraded, error) (optional)
  • database_pool_size: Current size of the database connection pool (managed automatically by asyncpg)

Get historical health check data for trend analysis.

Query Parameters:

  • hours (optional, default: 24): Number of hours to look back
  • limit (optional, default: 100): Maximum number of records to return

Response:

{
"history": [
{
"service": "alphapy",
"version": "3.6.0",
"uptime_seconds": 3600,
"db_status": "ok",
"guild_count": 2,
"active_commands_24h": 150,
"gpt_status": "operational",
"database_pool_size": 5,
"checked_at": "2026-01-21T12:00:00Z"
}
],
"period_hours": 24,
"total_records": 1
}

Comprehensive dashboard metrics including bot status, Grok/LLM stats, reminders, tickets, and command usage.

Authentication: Required (Supabase JWT token)

Query Parameters:

  • guild_id (optional): Filter metrics by guild ID

Response:

{
"bot": {
"version": "3.6.0",
"codename": "Lifecycle Manager",
"online": true,
"latency_ms": 45.2,
"uptime_seconds": 3600,
"uptime_human": "1 hour",
"commands_loaded": 30,
"guilds": [...]
},
"gpt": {
"last_success_time": "2026-01-21T12:00:00Z",
"last_error_time": "2026-01-21T12:05:00Z",
"last_error_type": "RateLimitError: ...",
"average_latency_ms": 1200,
"total_tokens_session": 5000,
"current_model": "grok-3",
"last_user_id": 123456789,
"success_count": 100,
"error_count": 2,
"rate_limit_hits": 1,
"last_rate_limit_time": "2026-01-21T12:05:00Z",
"last_success_latency_ms": 980,
"recent_successes": [...],
"recent_errors": [...]
},
"reminders": {
"total": 15,
"recurring": 10,
"one_off": 5,
"next_event_time": "2026-01-21T19:00:00Z",
...
},
"tickets": {
"total": 50,
"open_count": 5,
"per_status": {...},
"open_ticket_ids": [123, 456, 789],
"open_items": [
{
"id": 123,
"username": "user123",
"status": "open",
"channel_id": 987654321,
"created_at": "2026-01-21T12:00:00Z"
}
],
...
},
"command_usage": {
"top_commands": [
{"command_name": "add_reminder", "usage_count": 45},
{"command_name": "ticket", "usage_count": 30}
],
"total_commands_24h": 150,
"period_days": 7
},
"infrastructure": {
"database_up": true,
"pool_size": 5,
"checked_at": "2026-01-21T12:00:00Z"
},
"premium_metrics": {
"premium_checks_total": 120,
"premium_checks_core_api": 80,
"premium_checks_local": 40,
"premium_cache_hits": 200,
"premium_transfers_count": 3,
"premium_cache_size": 25
}
}

The optional premium_metrics block provides observability for the Premium guard:

  • premium_checks_total: Total number of premium checks performed
  • premium_checks_core_api: Checks served by the Core-API
  • premium_checks_local: Checks served from local database/cache
  • premium_cache_hits: Number of cache hits when resolving premium status
  • premium_transfers_count: Number of premium transfers between guilds
  • premium_cache_size: Current in-memory cache size for premium status

Alias for /api/dashboard/metrics - provided for compatibility with Mind monitoring system.

Authentication: Required (Supabase JWT token)

Query Parameters:

  • guild_id (optional): Filter metrics by guild ID

Response: Same as /api/dashboard/metrics

Command usage analytics endpoint.

Query Parameters:

  • guild_id (optional): Filter by guild ID
  • days (optional, default: 7): Number of days to look back
  • limit (optional, default: 10): Maximum number of commands to return

Response:

{
"commands": {
"add_reminder": 45,
"ticket": 30,
"reminder_list": 20
},
"period_days": 7,
"guild_id": null,
"total_commands": 3
}

These endpoints are used by the web dashboard (Mind) for configuration management.

Get all settings for a specific guild, organized by category.

Authentication: Required (Supabase JWT token)

Path Parameters:

  • guild_id (required): Discord guild ID

Response:

{
"system": {
"log_channel_id": 123456789,
"rules_channel_id": 987654321,
"log_level": "verbose"
},
"reminders": {
"enabled": true,
"default_channel_id": 111222333,
"allow_everyone_mentions": false
},
"embedwatcher": {
"announcements_channel_id": 444555666,
"reminder_offset_minutes": 60,
"gpt_fallback_enabled": true,
"non_embed_enabled": false,
"process_bot_messages": false
},
"gpt": {
"model": "grok-3",
"temperature": 0.7
},
"invites": {
"enabled": true,
"announcement_channel_id": 123456789,
"with_inviter_template": "{member} joined! {inviter} now has {count} invites.",
"no_inviter_template": "{member} joined, but no inviter data found."
},
"gdpr": {
"enabled": true,
"channel_id": 123456789
},
"automod": {
"enabled": false,
"log_channel_id": 123456789,
"log_actions": true,
"log_to_database": true
},
"onboarding": {
"enabled": true,
"mode": "rules_with_questions",
"completion_role_id": 123456789,
"join_role_id": 987654321
},
"ticketbot": {
"category_id": 123456789,
"staff_role_id": 987654321,
"escalation_role_id": 555666777,
"idle_days_threshold": 5,
"auto_close_days_threshold": 14
},
"verification": {
"verified_role_id": 123456789,
"category_id": 987654321,
"vision_model": "grok-3"
}
}

Update settings for a specific guild category.

Authentication: Required (Supabase JWT token)

Path Parameters:

  • guild_id (required): Discord guild ID

Request Body:

{
"category": "reminders",
"settings": {
"default_channel_id": "111222333",
"allow_everyone_mentions": false
}
}

Response:

{
"success": true,
"message": "Updated reminders settings"
}

GET /api/dashboard/{guild_id}/onboarding/questions

Section titled “GET /api/dashboard/{guild_id}/onboarding/questions”

Get all onboarding questions for a guild.

Authentication: Required (Supabase JWT token)

Response:

[
{
"id": 1,
"question": "What is your trading experience?",
"question_type": "select",
"options": [{"label": "Beginner", "value": "beginner"}],
"required": true,
"enabled": true,
"step_order": 1
}
]

POST /api/dashboard/{guild_id}/onboarding/questions

Section titled “POST /api/dashboard/{guild_id}/onboarding/questions”

Save or update an onboarding question.

Authentication: Required (Supabase JWT token + guild admin access)

Request Body: Same structure as GET response

DELETE /api/dashboard/{guild_id}/onboarding/questions/{question_id}

Section titled “DELETE /api/dashboard/{guild_id}/onboarding/questions/{question_id}”

Delete an onboarding question.

Authentication: Required (Supabase JWT token + guild admin access)

GET /api/dashboard/{guild_id}/onboarding/rules

Section titled “GET /api/dashboard/{guild_id}/onboarding/rules”

Get all onboarding rules for a guild.

Authentication: Required (Supabase JWT token)

Response:

[
{
"id": 1,
"title": "Be Respectful",
"description": "Treat all members with respect",
"thumbnail_url": "https://example.com/thumb.png",
"image_url": "https://example.com/image.png",
"enabled": true,
"rule_order": 1
}
]

thumbnail_url and image_url are optional; shown as thumbnail (right) and image (bottom) in rule embeds.

POST /api/dashboard/{guild_id}/onboarding/rules

Section titled “POST /api/dashboard/{guild_id}/onboarding/rules”

Save or update an onboarding rule.

Authentication: Required (Supabase JWT token + guild admin access)

DELETE /api/dashboard/{guild_id}/onboarding/rules/{rule_id}

Section titled “DELETE /api/dashboard/{guild_id}/onboarding/rules/{rule_id}”

Delete an onboarding rule.

Authentication: Required (Supabase JWT token + guild admin access)

POST /api/dashboard/{guild_id}/onboarding/reorder

Section titled “POST /api/dashboard/{guild_id}/onboarding/reorder”

Reorder onboarding questions and rules.

Authentication: Required (Supabase JWT token + guild admin access)

Request Body:

{
"questions": [1, 3, 2],
"rules": [2, 1]
}

Response:

{
"success": true
}

GET /api/dashboard/{guild_id}/settings/history

Section titled “GET /api/dashboard/{guild_id}/settings/history”

Get settings change history for a guild.

Authentication: Required (Supabase JWT token)

Query Parameters:

  • scope (optional): Filter by scope (e.g., “reminders”)
  • key (optional): Filter by specific key
  • limit (optional, default: 50): Maximum number of records

Response:

[
{
"id": 1,
"scope": "reminders",
"key": "default_channel_id",
"old_value": "111222333",
"new_value": "444555666",
"changed_by": 123456789,
"changed_at": "2026-01-21T12:00:00Z",
"change_type": "updated"
}
]

POST /api/dashboard/{guild_id}/settings/rollback/{history_id}

Section titled “POST /api/dashboard/{guild_id}/settings/rollback/{history_id}”

Rollback a setting to a previous value.

Authentication: Required (Supabase JWT token)

Response:

{
"success": true,
"message": "Rolled back reminders.default_channel_id to previous value"
}

GET /api/dashboard/{guild_id}/automod/rules

Section titled “GET /api/dashboard/{guild_id}/automod/rules”

List all auto-moderation rules for a guild.

Authentication: Required (Supabase JWT token + guild admin access)

Response:

[
{
"id": 1,
"guild_id": 123456789,
"rule_type": "content",
"name": "No Bad Words",
"enabled": true,
"config": {
"content_type": "bad_words",
"words": ["spam", "curse"]
},
"action_type": "warn",
"action_config": {
"message": "Please watch your language!"
},
"severity": 1,
"created_by": 987654321,
"created_at": "2026-01-21T12:00:00Z",
"updated_at": "2026-01-21T12:00:00Z",
"is_premium": false
}
]

POST /api/dashboard/{guild_id}/automod/rules

Section titled “POST /api/dashboard/{guild_id}/automod/rules”

Create a new auto-moderation rule.

Authentication: Required (Supabase JWT token + guild admin access)

Request Body:

{
"rule_type": "content",
"name": "No Links",
"enabled": true,
"config": {
"content_type": "links",
"allow_links": false,
"whitelist": ["discord.com"],
"blacklist": ["spam.com"]
},
"action_type": "delete",
"action_config": {},
"severity": 2
}

Response: Returns the created rule with assigned ID

PUT /api/dashboard/{guild_id}/automod/rules/{rule_id}

Section titled “PUT /api/dashboard/{guild_id}/automod/rules/{rule_id}”

Update an existing auto-moderation rule.

Authentication: Required (Supabase JWT token + guild admin access)

Request Body:

{
"name": "Updated Rule Name",
"enabled": false,
"severity": 3
}

Response: Returns the updated rule

DELETE /api/dashboard/{guild_id}/automod/rules/{rule_id}

Section titled “DELETE /api/dashboard/{guild_id}/automod/rules/{rule_id}”

Delete an auto-moderation rule.

Authentication: Required (Supabase JWT token + guild admin access)

Response:

{
"success": true
}

GET /api/dashboard/{guild_id}/automod/stats

Section titled “GET /api/dashboard/{guild_id}/automod/stats”

Get auto-moderation statistics and analytics.

Authentication: Required (Supabase JWT token + guild admin access)

Response:

{
"total_rules": 5,
"enabled_rules": 3,
"rules_by_type": {
"content": 2,
"spam": 1,
"links": 1,
"mentions": 1
},
"total_violations": 127,
"violations_today": 8,
"violations_week": 45,
"top_violated_rules": [
{
"name": "No Bad Words",
"rule_type": "content",
"violation_count": 23
}
]
}

GET /api/dashboard/{guild_id}/automod/violations

Section titled “GET /api/dashboard/{guild_id}/automod/violations”

Get recent auto-moderation violation logs.

Authentication: Required (Supabase JWT token + guild admin access)

Query Parameters:

  • limit (optional, default: 50): Maximum number of violations to return
  • days (optional, default: 7): Number of days to look back

Response:

[
{
"id": 1,
"guild_id": 123456789,
"user_id": 987654321,
"message_id": 111222333,
"channel_id": 444555666,
"rule_id": 1,
"action_taken": "warn",
"message_content": "This message contained bad words",
"ai_analysis": null,
"context": {},
"timestamp": "2026-01-21T12:00:00Z",
"moderator_id": null
}
]

GET /api/dashboard/{guild_id}/automod/settings

Section titled “GET /api/dashboard/{guild_id}/automod/settings”

Get auto-moderation specific settings.

Authentication: Required (Supabase JWT token + guild admin access)

Response:

{
"enabled": false,
"log_channel_id": 123456789,
"log_actions": true,
"log_to_database": true
}

POST /api/dashboard/{guild_id}/automod/settings

Section titled “POST /api/dashboard/{guild_id}/automod/settings”

Update auto-moderation settings.

Authentication: Required (Supabase JWT token + guild admin access)

Request Body:

{
"enabled": true,
"log_channel_id": 123456789,
"log_actions": true,
"log_to_database": true
}

Response:

{
"success": true
}

Get GDPR acceptance statistics for a guild.

Authentication: Required (Supabase JWT token + guild admin access)

Response:

{
"guild_id": 123456789,
"acceptance_count": 42
}

Get operational logs (reconnect, disconnect, etc.) for the Mind dashboard. Requires guild admin access (verified via Supabase profile’s Discord ID). Global events (e.g. BOT_RECONNECT, BOT_DISCONNECT) are included for any guild request.

Authentication: Required (Supabase JWT token + guild admin access)

Query Parameters:

  • guild_id (required): Discord guild ID – user must have admin access to this guild
  • limit (optional, default: 50, max: 100): Maximum number of log entries to return
  • event_types (optional): Comma-separated list of event types to filter (e.g. BOT_RECONNECT,BOT_DISCONNECT)

Response:

{
"logs": [
{
"timestamp": "2026-02-10T21:30:00Z",
"event_type": "BOT_RECONNECT",
"guild_id": null,
"message": "Reconnect phase complete: commands synced",
"details": {"synced": 5, "skipped": 0}
}
]
}

Event types:

  • BOT_READY – Bot startup complete
  • BOT_RECONNECT – Bot reconnected and resynced commands (includes synced and skipped counts)
  • BOT_DISCONNECT – Bot disconnected from Discord
  • GUILD_SYNC – Command sync per guild (success/failure/cooldown, includes sync_type: startup/reconnect/guild_join)
  • ONBOARDING_ERROR – Onboarding errors (no rules configured, role assignment failures, member not found)
  • SETTINGS_CHANGED – Settings changes via commands or API (includes action: set/clear/bulk_update/rollback, source: command/api)
  • COG_ERROR – Slash command errors per guild (includes command name, user ID, error type)

List reminders for a specific user.

Authentication: Required (Supabase JWT or API key, plus user match against authenticated JWT subject)

Path Parameters:

  • user_id (required): Discord user ID whose reminders to fetch

Response:

[
{
"id": 1,
"name": "Weekly Meeting",
"channel_id": 123456789,
"time": "18:00:00",
"call_time": "19:00:00",
"days": ["2"],
"message": "Weekly team meeting",
"location": "Conference Room",
"event_time": null,
"created_at": "2026-01-21T10:00:00Z"
}
]

Create a new reminder.

Authentication: Required (Supabase JWT or API key, plus user match against authenticated JWT subject)

Supports optional Idempotency-Key header for safe retries (duplicate requests with the same key return the cached success response instead of creating duplicate writes).

Request Body:

{
"name": "Team Standup",
"channel_id": 123456789,
"time": "09:00:00",
"days": ["0", "2", "4"],
"message": "Daily standup meeting",
"location": "Main Channel"
}

Update an existing reminder.

Authentication: Required (Supabase JWT or API key, plus user match against authenticated JWT subject)

Supports optional Idempotency-Key header for safe retries.

Request Body: Same as POST, include id in payload. All fields optional except id and user_id.

DELETE /api/reminders/{reminder_id}/{created_by}

Section titled “DELETE /api/reminders/{reminder_id}/{created_by}”

Delete a reminder.

Authentication: Required (Supabase JWT or API key, plus user match against authenticated JWT subject)

Supports optional Idempotency-Key header for safe retries.

Path Parameters:

  • reminder_id (required): ID of the reminder to delete
  • created_by (required): Discord user ID who created the reminder

Note: Ticket and FAQ exports are available via Discord slash commands (/export_tickets, /export_faq), not API endpoints. These commands are admin-only and generate CSV files sent via Discord.

These endpoints receive payloads from Core-API. They do not use API key authentication; use X-Webhook-Signature (HMAC) with the configured secret (APP_REFLECTIONS_WEBHOOK_SECRET or fallback). See Configuration for environment variables.

Receives plaintext reflection content from the App via Core-API. Payload is stored in app_reflections (Railway) and used for Grok context in user-self flows (e.g. /growthcheckin; not used for ticket “Suggest reply” for privacy).

Note: Grok context for /growthcheckin is merged from three sources: Supabase reflections_shared (opt-in via bot_sharing_enabled), Supabase reflections (Discord check-ins, always), and Railway app_reflections (this webhook, always). Max 5 reflections total.

Headers: X-Webhook-Signature (optional if no secret configured)

Request body:

{
"user_id": 123456789,
"reflection_id": "uuid-from-app",
"plaintext_content": { "reflection_text": "...", "mantra": "...", "thoughts": "...", "future_message": "...", "date": "YYYY-MM-DD" }
}

Response: 200 with {"status": "acknowledged", "reflection_id": "..."}.

Deletes a previously stored reflection when the user revokes consent in the App. Core-API sends this after consent is revoked.

Headers: X-Webhook-Signature (optional if no secret configured)

Request body:

{
"user_id": 123456789,
"reflection_id": "uuid-from-app"
}

Response: 200 with {"status": "deleted", "count": 1} (or count: 0 if no row matched).

Triggered by a GitHub Action when docs/terms-of-service.md or docs/privacy-policy.md changes on main. Posts a formatted embed in the configured channel of the main guild (MAIN_GUILD_ID).

Headers: X-Webhook-Signature (HMAC-SHA256; secret: LEGAL_UPDATE_WEBHOOK_SECRET, falls back to APP_REFLECTIONS_WEBHOOK_SECRET / WEBHOOK_SECRET)

Request body:

{
"documents": ["tos", "pp"],
"tos_version": "2026-03-31",
"pp_version": "2026-03-31"
}
  • documents (required): array of keys — "tos" (Terms of Service) and/or "pp" (Privacy Policy)
  • tos_version / pp_version: effective date string extracted from the document header (format YYYY-MM-DD)

Response: 200 with {"status": "acknowledged", "sent": "tos, pp"}. Returns {"status": "skipped", "reason": "..."} if MAIN_GUILD_ID is not set or no target channel is configured.


Clears the premium cache for a user so the next check refetches from Core-API/DB. Sent by Core-API on subscription changes (new purchase, cancellation, transfer).

Headers: X-Webhook-Signature (HMAC-SHA256; secret: PREMIUM_INVALIDATE_WEBHOOK_SECRET, falls back to APP_REFLECTIONS_WEBHOOK_SECRET / WEBHOOK_SECRET)

Request body:

{
"user_id": 123456789,
"guild_id": 987654321
}
  • guild_id is optional — if omitted, cache is cleared for all guilds for that user.

Response: 200 with {"status": "ok"}.


Sends a founder welcome DM to a Discord user. Triggered by Core-API when a founder purchase is confirmed.

Headers: X-Webhook-Signature (HMAC-SHA256; secret: FOUNDER_WEBHOOK_SECRET, falls back to APP_REFLECTIONS_WEBHOOK_SECRET / WEBHOOK_SECRET)

Request body:

{
"user_id": 123456789,
"message": "Optional custom message to include in the DM"
}

Response: 200 with {"status": "ok"} or {"status": "dm_failed"} if the user has DMs disabled.

All endpoints may return standard HTTP error codes:

  • 400 Bad Request: Invalid request parameters
  • 401 Unauthorized: Missing or invalid authentication
  • 404 Not Found: Resource not found
  • 500 Internal Server Error: Server error

Error response format:

{
"detail": "Error message description"
}

In-memory IP-based sliding window limits:

  • Health/metrics/status endpoints: 60 req/min
  • Read requests (GET): 30 req/min
  • Write requests (POST, PUT, DELETE): 10 req/min

Current API version: 3.7.0 (Enterprise Ready)

Version information is included in health check responses and can be queried via /api/health.

  • system: Log channels, log level
  • reminders: Reminder functionality, default channels
  • embedwatcher: Embed parsing, reminder offsets
  • gpt: AI model configuration
  • invites: Invite tracking settings
  • gdpr: GDPR compliance settings
  • automod: Auto-moderation configuration
  • onboarding: User onboarding flow
  • ticketbot: Ticket system configuration
  • verification: Payment verification setup
  • engagement: Challenges, weekly awards, streaks, badges, OG claims
  • growth: Growth Check-in channel
  • spam: Message spam detection
  • content: Content filtering (bad words, links, etc.)
  • regex: Custom regex patterns (premium)
  • ai: AI-powered content analysis (premium)
  • mentions: Mention spam detection
  • caps: Excessive capitalization
  • duplicate: Duplicate message detection
  • delete: Delete message
  • warn: Send warning message
  • mute: Mute user (premium)
  • timeout: Timeout user (premium)
  • ban: Ban user (premium)
  • text: Free text input
  • email: Email validation
  • select: Single choice dropdown
  • multiselect: Multiple choice checkboxes