16 KiB
API Reference
Complete reference for the RedditBot web dashboard API.
Table of Contents
- Overview
- Authentication
- Base URL
- Bot Status & Control
- Activity & Messages
- Chat & Conversations
- Media
- Analytics
- Configuration
- Logs & Debugging
- Error Responses
- SSE Events
Overview
The RedditBot web dashboard exposes a REST API for monitoring and controlling the bot. All endpoints are served by the Express server.
Content-Type: application/json (except SSE)
Response Format: JSON
Authentication: Required for cutover; not yet enforced by the checked-in Express host
Authentication
The React cutover requires a single Express authentication boundary covering
the dashboard assets, /api, both SSE streams, debug routes, and private media.
That boundary and its token/session configuration are not present in the
checked-in server yet. Until they land and their security tests pass, bind the
dashboard to a trusted network and do not expose port 3000 publicly.
The intended contract is an HttpOnly, SameSite=Strict dashboard session for interactive users and bearer-token access for API clients. Treat those details as a migration requirement, not as proof of current protection.
Base URL
http://localhost:3000/api
The port is configured via config.web.port (default: 3000).
Bot Status & Control
Get Bot Statistics
Retrieve current bot statistics including running state, counts, and response rate.
GET /api/stats
Response:
{
"running": true,
"processed": 1250,
"sent": 980,
"responded": 312,
"responseRate": 0.318,
"hourlyCount": 15,
"timeUntilSlot": 45
}
Fields:
| Field | Type | Description |
|---|---|---|
running |
boolean | Whether the bot is currently running |
processed |
number | Total posts processed |
sent |
number | Total messages sent |
responded |
number | Total messages that received responses |
responseRate |
number | Response rate (0.0 to 1.0) |
hourlyCount |
number | Messages sent this hour |
timeUntilSlot |
number | Seconds until next message slot |
Start Bot
Start the bot's main processing loop.
POST /api/start
Response:
{
"success": true,
"message": "Bot started"
}
Errors:
{
"error": "Bot is already running"
}
Stop Bot
Stop the bot's main processing loop gracefully.
POST /api/stop
Response:
{
"success": true,
"message": "Bot stopping..."
}
Activity & Messages
Get Activity Log
Retrieve recent activity entries from the bot's log.
GET /api/activity
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
number | 50 | Number of entries to return |
Response:
[
{
"level": "info",
"message": "Processed post abc123 from r/gonewild",
"timestamp": "2024-01-15T10:30:00.000Z"
},
{
"level": "warn",
"message": "AI model refused to analyze post def456",
"timestamp": "2024-01-15T10:28:00.000Z"
},
{
"level": "error",
"message": "Failed to send DM to user789: timeout",
"timestamp": "2024-01-15T10:25:00.000Z"
}
]
Get Posts by Author
Look up processed posts for a specific Reddit user.
GET /api/posts/by-author/:username
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
username |
string | Reddit username |
Response:
[
{
"id": "abc123",
"subreddit": "gonewild",
"author": "user123",
"title": "Summer vibes",
"image_url": "https://...",
"image_analysis": "{\"gender\":\"F\",\"description\":\"...\"}",
"generated_message": "Hey, you look amazing...",
"processed_at": 1716234567,
"message_sent": 1,
"error": null
}
]
Get Sent Messages
Retrieve recent sent messages.
GET /api/messages
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
number | 50 | Number of messages to return |
Response:
[
{
"id": 1,
"post_id": "abc123",
"recipient": "user123",
"subject": "Stunning",
"message": "Hey, you look amazing...",
"sent_at": "2024-01-15T10:30:00.000Z",
"strategy_id": "compliment",
"got_response": 1,
"response_checked_at": "2024-01-15T11:00:00.000Z"
}
]
Get Successful Messages
Retrieve successful message/response pairs used for few-shot learning.
GET /api/successful
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
number | 50 | Number of entries to return |
Response:
[
{
"id": 1,
"sent_message_id": 1,
"original_message": "Hey, you look amazing...",
"image_analysis": "{\"gender\":\"F\",\"description\":\"...\"}",
"post_title": "Summer vibes",
"response_snippet": "Thank you so much! 😊",
"subreddit": "gonewild",
"created_at": "2024-01-15T10:30:00.000Z"
}
]
Chat & Conversations
Get Active Chats
Retrieve cached active conversations.
GET /api/chats
Response:
[
{
"chatId": "chat_abc123",
"participant": "user456",
"lastMessage": "Thanks for the compliment!",
"timestamp": "2024-01-15T10:30:00.000Z",
"hasNewMessages": false
}
]
Fetch All Chats
Force-fetch all chats from Reddit (refreshes cache).
POST /api/chats/fetch-all
Response:
{
"success": true,
"count": 15
}
Get Conversations
Retrieve all cached conversations.
GET /api/conversations
Response:
[
{
"chatId": "chat_abc123",
"participants": ["user456", "bot"],
"messageCount": 24,
"lastUpdated": "2024-01-15T10:30:00.000Z",
"hasNewMessages": false,
"pendingReply": false,
"isUpsell": false
}
]
Get Conversation Detail
Retrieve full details of a specific conversation.
GET /api/conversations/:id
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Chat ID |
Response:
{
"chatId": "chat_abc123",
"participants": ["user456", "bot"],
"messages": [
{
"author": "user456",
"text": "Hey there!",
"timestamp": "2024-01-15T10:00:00.000Z"
},
{
"author": "bot",
"text": "Hi! Thanks for the compliment!",
"timestamp": "2024-01-15T10:01:00.000Z"
},
{
"author": "user456",
"text": "Thanks for the compliment!",
"timestamp": "2024-01-15T10:02:00.000Z"
}
],
"lastUpdated": "2024-01-15T10:30:00.000Z",
"hasNewMessages": false,
"pendingReply": false,
"isUpsell": false
}
Suggest Reply
Generate an AI reply suggestion for a conversation.
POST /api/conversations/:id/suggest-reply
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Chat ID |
Response:
{
"success": true,
"reply": "Thanks for reaching out! 😊 How's your day going?"
}
Send Reply
Send a manual reply in a conversation.
POST /api/conversations/:id/send-reply
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Chat ID |
Request Body:
{
"text": "Thanks for reaching out! 😊"
}
Response:
{
"success": true,
"delivered": true
}
Approve Pending Reply
Approve an auto-reply that is pending manual approval.
POST /api/conversations/:id/approve-reply
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Chat ID |
Response:
{
"success": true,
"message": "Reply sent"
}
Reject Pending Reply
Reject an auto-reply that is pending manual approval.
POST /api/conversations/:id/reject-reply
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Chat ID |
Response:
{
"success": true,
"message": "Reply rejected"
}
Dismiss Upsell Flag
Clear the upsell/spam flag on a conversation.
POST /api/conversations/:id/dismiss-upsell
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Chat ID |
Response:
{
"success": true,
"message": "Upsell flag dismissed"
}
Media
Get Media Gallery
Retrieve downloaded media files.
GET /api/media
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
number | 100 | Number of files to return |
Response:
[
{
"hash": "abc123def456",
"filename": "abc123def456.jpg",
"size": 245678,
"conversationId": "chat_abc123",
"downloadedAt": "2024-01-15T10:30:00.000Z"
}
]
Get Media Sync Status
Retrieve current media sync status.
GET /api/media/sync
Response:
{
"running": false,
"mode": null,
"progress": 0,
"total": 0,
"completed": 0,
"lastSync": "2024-01-15T09:00:00.000Z"
}
Trigger Incremental Sync
Start an incremental media sync (top 10 conversations).
POST /api/media/sync
Response:
{
"success": true,
"message": "Incremental sync started"
}
Trigger Full Sync
Start a full media sync (all conversations).
POST /api/media/sync/full
Response:
{
"success": true,
"message": "Full sync started"
}
Analytics
Response Rate by Subreddit
Get response rates broken down by subreddit.
GET /api/analytics/by-subreddit
Response:
[
{
"subreddit": "gonewild",
"sent": 500,
"responded": 175,
"rate": 0.35
},
{
"subreddit": "ratemyboobs",
"sent": 300,
"responded": 90,
"rate": 0.30
},
{
"subreddit": "HomemadeNsfw",
"sent": 180,
"responded": 72,
"rate": 0.40
}
]
Response Rate by Strategy
Get response rates broken down by A/B test variant.
GET /api/analytics/by-strategy
Response:
[
{
"strategy_id": "compliment",
"sent": 400,
"responded": 140,
"rate": 0.35
},
{
"strategy_id": "question",
"sent": 350,
"responded": 147,
"rate": 0.42
},
{
"strategy_id": "observation",
"sent": 230,
"responded": 69,
"rate": 0.30
}
]
Daily Response Trend
Get daily response rates over time.
GET /api/analytics/trend
Response:
[
{
"date": "2024-01-01",
"sent": 18,
"responded": 6,
"rate": 0.33
},
{
"date": "2024-01-02",
"sent": 22,
"responded": 8,
"rate": 0.36
},
{
"date": "2024-01-03",
"sent": 15,
"responded": 4,
"rate": 0.27
}
]
Configuration
Get Runtime Configuration
Get current runtime configuration.
GET /api/config
Response:
{
"reddit": {
"subreddits": ["gonewild", "ratemyboobs"],
"pollInterval": 15,
"targetGender": "F",
"sellerKeywords": ["seller", "onlyfans"]
},
"openrouter": {
"model": "meta-llama/llama-3.2-90b-vision-preview",
"fallbackModels": ["google/gemini-2.0-flash-001"]
},
"rateLimit": {
"minDelayMs": 30000,
"maxMessagesPerHour": 20,
"jitterMs": 15000
},
"browser": {
"sessionDir": "./data/browser-session",
"dryRun": false
},
"database": {
"path": "./data/reddit-bot.db"
},
"mediaSync": {
"enabled": true,
"intervalMinutes": 30
},
"autoReply": {
"enabled": true,
"autoSend": false,
"checkInterval": 10
},
"strategyVariants": [
{
"name": "compliment",
"enabled": true
}
],
"web": {
"port": 3000
},
"dryRun": false,
"fewShotExamples": 3,
"minStrategySamples": 10,
"explorationRate": 0.15
}
Update Runtime Configuration
Update runtime configuration values without restarting.
PUT /api/config
Request Body (partial updates supported):
{
"rateLimit": {
"minDelayMs": 45000,
"maxMessagesPerHour": 15
},
"dryRun": true,
"reddit": {
"pollInterval": 20
}
}
Response:
{
"success": true,
"config": { ... }
}
Errors:
{
"error": "Invalid config: rateLimit.minDelayMs must be a positive integer"
}
Logs & Debugging
SSE Log Stream
Connect to the realtime log stream via Server-Sent Events.
GET /api/logs/stream
Headers:
| Header | Value |
|---|---|
| Accept | text/event-stream |
Response (streaming):
event: log
data: {"level":"info","message":"Bot started","timestamp":"2024-01-15T10:30:00.000Z"}
event: log
data: {"level":"info","message":"Processed post abc123","timestamp":"2024-01-15T10:30:05.000Z"}
event: log
data: {"level":"warn","message":"AI refusal detected","timestamp":"2024-01-15T10:30:10.000Z"}
Client usage (JavaScript):
const eventSource = new EventSource('/api/logs/stream');
eventSource.onmessage = (event) => {
const log = JSON.parse(event.data);
console.log(log.level, log.message);
};
// Close connection
eventSource.close();
Get Recent Logs
Retrieve recent log entries via HTTP (non-streaming).
GET /api/logs
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
number | 100 | Number of entries to return |
level |
string | all | Filter by level: info, warn, error |
Response: Same format as /api/activity.
Get Rate Limiter Timers
Get current rate limiter status.
GET /api/timers
Response:
{
"timeUntilSlot": 45,
"hourlyCount": 15,
"maxMessagesPerHour": 20,
"isThrottled": false
}
Debug: Inspect DOM
Inspect the current chat DOM structure (for debugging shadow DOM issues).
POST /api/debug/inspect-dom
Response:
{
"success": true,
"domStructure": { ... }
}
Debug: Manual Response Check
Trigger a manual response check (bypasses scheduled interval).
POST /api/debug/check-responses
Response:
{
"success": true,
"responsesFound": 3,
"updated": 2
}
Error Responses
All error responses follow this format:
{
"error": "Error message describing what went wrong"
}
Common Error Codes
| HTTP Status | Description | Example |
|---|---|---|
| 400 | Bad Request | Invalid query parameter |
| 404 | Not Found | Resource not found |
| 500 | Internal Server Error | Unexpected error |
SSE Events
GET /api/events/stream is the typed resumable event stream used by the React
dashboard. Each SSE frame contains id, event, and data fields. The data is
the complete validated event envelope:
{
"id": "1786201200000-000000",
"occurredAt": "2026-08-08T15:00:00.000Z",
"type": "log.created",
"payload": {
"level": "info",
"message": "Dashboard started"
}
}
Clients may reconnect with Last-Event-ID; the server replays retained events
after that ID in order. The stream sends heartbeats, bounds buffered events and
slow-client queues, and uses the same authentication boundary as the API.
Current event families include bot status, message sent or failed, conversation updated, reply received, sync lifecycle and progress, rate-limit state, Reddit session state, and logs.
GET /api/logs/stream remains temporarily available for compatibility tooling.
New clients use the typed /api/events/stream endpoint.
Log Levels:
| Level | Description |
|---|---|
info |
Normal operation |
warn |
Warning (recoverable issue) |
error |
Error (action failed) |
debug |
Debug information |