{"openapi":"3.0.0","info":{"title":"Lunex REST API v1","version":"1.0.0","description":"Official Programmatic REST API for LunexHost. Provides automated 24/7 Discord bot deployment, source upload, secret configuration, process management, and status monitoring for developers and AI Agents."},"servers":[{"url":"https://lunexhost.my.id/api/v1","description":"Production Server"}],"paths":{"/bots":{"post":{"summary":"Create a new Bot Container","description":"Creates a new Discord bot container and allocates an isolated workspace.","security":[{"BearerAuth":[]}],"parameters":[{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean"},"description":"Perform validation without creating DB records or workspace folders."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"My Discord Bot"},"runtime":{"type":"string","enum":["nodejs","python"],"example":"nodejs"},"startCommand":{"type":"string","example":"npm start"}},"required":["name","runtime"]}}}},"responses":{"201":{"description":"Bot created successfully","content":{"application/json":{"example":{"botId":"bot_m7x9k2p1a","uploadUrl":"/api/v1/bots/bot_m7x9k2p1a/upload","message":"Bot created successfully"}}}},"400":{"description":"Invalid input or subscription plan limit exceeded"},"401":{"description":"Missing or invalid Bearer token"},"403":{"description":"Insufficient scope or revoked API key"},"429":{"description":"Rate limit exceeded (60 req/min)"}}}},"/bots/{id}/upload":{"post":{"summary":"Upload Bot Source Code (ZIP)","description":"Uploads a ZIP archive containing project source code. Files must be located at the root of the ZIP file.","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"ZIP file containing source code"}},"required":["file"]}}}},"responses":{"200":{"description":"Source code extracted successfully"},"400":{"description":"Missing or non-ZIP file"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden or not bot owner"},"404":{"description":"Bot not found"}}}},"/bots/{id}/env":{"post":{"summary":"Set Environment Variables / Secrets","description":"Sets or updates environment variables (e.g., DISCORD_TOKEN) for the specified bot.","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"example":{"DISCORD_TOKEN":"MTI3NDk1OD..."}}}}},"responses":{"200":{"description":"Environment variables updated"},"400":{"description":"Invalid JSON object"},"401":{"description":"Unauthorized"},"404":{"description":"Bot not found"}}}},"/bots/{id}/actions":{"post":{"summary":"Control Bot Process","description":"Triggers a process lifecycle action: start, stop, restart, or kill.","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["start","stop","restart","kill"]}},"required":["action"]}}}},"responses":{"200":{"description":"Action executed successfully"},"400":{"description":"Invalid action parameter"},"401":{"description":"Unauthorized"},"404":{"description":"Bot not found"}}}},"/bots/{id}/status":{"get":{"summary":"Get Real-time Bot Status","description":"Returns status (online/offline), CPU usage, RAM usage, and uptime.","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Status retrieved successfully","content":{"application/json":{"example":{"status":"online","cpuUsage":"0.4%","ramUsage":"42 MB","uptime":120}}}},"401":{"description":"Unauthorized"},"404":{"description":"Bot not found"}}}},"/bots/{id}/logs":{"get":{"summary":"Fetch Console Logs","description":"Returns recent stdout/stderr log output for the bot.","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"maximum":500}}],"responses":{"200":{"description":"Logs array retrieved successfully","content":{"application/json":{"example":["2026-09-18T22:00:00.000Z [system] Starting process: node index.js","2026-09-18T22:00:01.000Z [stdout] Logged in as MyBot#1234!"]}}},"401":{"description":"Unauthorized"},"404":{"description":"Bot not found"}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key (lnx_...)"}}}}