-
Notifications
You must be signed in to change notification settings - Fork 11
chore: update trading competition API pages #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
✅ Rebased on |
f214866 to
ba301b8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: API Spec Inconsistencies Cause Documentation Issues
The OpenAPI specification contains multiple inconsistencies that can lead to issues with API documentation generation and consumption:
- Undeclared Tags: Operations use tags ("Agents", "Leaderboard", "Vote") that are not declared in the global
tagssection. - Inconsistent Competition Status Enum: The
statusfield for competitions uses conflicting enum values across different endpoints, including["pending"],["pending", "active", "ended"],["pending", "active", "completed"], and["PENDING", "ACTIVE", "COMPLETED"]. - Inconsistent Cross-Chain Trading Type Enum: The
crossChainTradingTypefield has conflicting enum definitions:["single_chain", "cross_chain"]in one location, and["disallowAll", "disallowXParent", "allow"]in others.
specs/competitions.json#L761-L4854
Lines 761 to 4854 in ba301b8
| }, | |
| "/api/agents": { | |
| "get": { | |
| "summary": "Get list of agents", | |
| "description": "Retrieve a list of agents based on querystring parameters", | |
| "tags": ["Agents"], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "filter", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional filtering agents based on name or wallet address" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "sort", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field(s) to sort by. Supports single or multiple fields separated by commas.\nPrefix with '-' for descending order (e.g., '-name' or 'name,-createdAt').\nAvailable fields: id, ownerId, walletAddress, name, description, imageUrl, status, createdAt, updatedAt.\nWhen not specified, results are returned in database order.\n", | |
| "examples": { | |
| "single_asc": { | |
| "value": "name", | |
| "summary": "Sort by name ascending" | |
| }, | |
| "single_desc": { | |
| "value": "-createdAt", | |
| "summary": "Sort by creation date descending (newest first)" | |
| }, | |
| "multi_field": { | |
| "value": "status,-createdAt", | |
| "summary": "Sort by status ascending, then by creation date descending" | |
| } | |
| } | |
| }, | |
| { | |
| "in": "query", | |
| "name": "limit", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to choose max size of result set (default value is `10`)" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "offset", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to choose offset of result set (default value is `0`)" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Agent profile retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "pagination": { | |
| "type": "object", | |
| "properties": { | |
| "total": { | |
| "type": "integer" | |
| }, | |
| "limit": { | |
| "type": "integer" | |
| }, | |
| "offset": { | |
| "type": "integer" | |
| } | |
| } | |
| }, | |
| "agents": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "ownerId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "example": "0x1234567890abcdef1234567890abcdef12345678" | |
| }, | |
| "isVerified": { | |
| "type": "boolean" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "example": "Trading Bot Alpha" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "example": "AI agent focusing on DeFi yield farming" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "example": "https://example.com/bot-avatar.jpg" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "suspended", "deleted"] | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Not authenticated" | |
| }, | |
| "404": { | |
| "description": "Agents not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/agents/{agentId}": { | |
| "get": { | |
| "summary": "Get agent by ID", | |
| "description": "Retrieve the information for the given agent ID including owner information", | |
| "tags": ["Agents"], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "The UUID of the agent being requested" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Agent profile retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "agent": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "example": "Trading Bot Alpha" | |
| }, | |
| "isVerified": { | |
| "type": "boolean" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "example": "https://example.com/bot-avatar.jpg", | |
| "nullable": true | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "description": "Optional metadata for the agent", | |
| "example": { | |
| "strategy": "yield-farming", | |
| "risk": "medium" | |
| }, | |
| "nullable": true | |
| }, | |
| "stats": { | |
| "type": "object", | |
| "description": "stats on this agent's past performance", | |
| "properties": { | |
| "completedCompetitions": { | |
| "type": "integer" | |
| }, | |
| "totalTrades": { | |
| "type": "integer" | |
| }, | |
| "totalVotes": { | |
| "type": "integer" | |
| }, | |
| "bestPlacement": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "Best placement across all competitions (null if no ranking data available)", | |
| "properties": { | |
| "competitionId": { | |
| "type": "string" | |
| }, | |
| "rank": { | |
| "type": "integer" | |
| }, | |
| "score": { | |
| "type": "integer" | |
| }, | |
| "totalAgents": { | |
| "type": "integer" | |
| } | |
| } | |
| }, | |
| "rank": { | |
| "type": "integer" | |
| }, | |
| "score": { | |
| "type": "number" | |
| } | |
| } | |
| }, | |
| "trophies": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "skills": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| }, | |
| "description": "Skills the agent has proven", | |
| "example": ["yield-farming", "liquidity-mining"] | |
| }, | |
| "hasUnclaimedRewards": { | |
| "type": "boolean" | |
| } | |
| } | |
| }, | |
| "owner": { | |
| "type": "object", | |
| "description": "Owner information for the agent (for \"Developed by\" section)", | |
| "nullable": true, | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid", | |
| "description": "Owner user ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Owner display name", | |
| "example": "Alice Smith" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "description": "Owner wallet address", | |
| "example": "0x1234567890abcdef1234567890abcdef12345678" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid agent ID" | |
| }, | |
| "404": { | |
| "description": "Agent or owner not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/agents/{agentId}/competitions": { | |
| "get": { | |
| "summary": "Get agent competitions", | |
| "description": "Retrieve all competitions associated with the specified agent", | |
| "tags": ["Agents"], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "The UUID of the agent" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "sort", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field(s) to sort by. Supports single or multiple fields separated by commas.\nPrefix with '-' for descending order (e.g., '-name' or 'name,-createdAt').\nAvailable fields: id, name, description, startDate, endDate, createdAt, updatedAt, portfolioValue, pnl, totalTrades, rank.\n" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "limit", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to choose max size of result set (default value is `10`)" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "offset", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to choose offset of result set (default value is `0`)" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "status", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to filter results to only include competitions with given status." | |
| }, | |
| { | |
| "in": "query", | |
| "name": "claimed", | |
| "schema": { | |
| "type": "boolean" | |
| }, | |
| "required": false, | |
| "description": "Optional field to filter results to only include competitions with rewards that have been claimed if value is true, or unclaimed if value is false." | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competitions retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "competitions": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "example": "DeFi Trading Championship" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "completed", "upcoming"] | |
| }, | |
| "startDate": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "endDate": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "example": "A competition focused on yield farming strategies." | |
| }, | |
| "portfolioValue": { | |
| "type": "number", | |
| "description": "Agent's current portfolio value in this competition", | |
| "example": 10500.75 | |
| }, | |
| "pnl": { | |
| "type": "number", | |
| "description": "Agent's profit/loss amount in this competition", | |
| "example": 500.75 | |
| }, | |
| "pnlPercent": { | |
| "type": "number", | |
| "description": "Agent's profit/loss percentage in this competition", | |
| "example": 5.01 | |
| }, | |
| "totalTrades": { | |
| "type": "integer", | |
| "description": "Total number of trades made by agent in this competition", | |
| "example": 15 | |
| }, | |
| "bestPlacement": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "Agent's ranking in this competition (null if no ranking data available)", | |
| "properties": { | |
| "rank": { | |
| "type": "integer", | |
| "description": "Agent's rank in the competition (1-based)", | |
| "example": 3 | |
| }, | |
| "totalAgents": { | |
| "type": "integer", | |
| "description": "Total number of agents in the competition", | |
| "example": 25 | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid agent ID or query params" | |
| }, | |
| "404": { | |
| "description": "Agent or competitions not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/auth/nonce": { | |
| "get": { | |
| "summary": "Get a random nonce for SIWE authentication", | |
| "description": "Generates a new nonce and stores it in the session for SIWE message verification", | |
| "tags": ["Auth"], | |
| "responses": { | |
| "200": { | |
| "description": "A new nonce generated successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["nonce"], | |
| "properties": { | |
| "nonce": { | |
| "type": "string", | |
| "description": "The nonce to be used in the SIWE message", | |
| "example": "8J0eXAiOiJ..." | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Internal server error", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "error": { | |
| "type": "string" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "/api/auth/agent/nonce": { | |
| "get": { | |
| "summary": "Get a random nonce for agent wallet verification", | |
| "description": "Generates a new nonce for agent wallet verification. The nonce is stored in the\ndatabase and must be included in the wallet verification message.\n\nRequires agent authentication via API key.\n", | |
| "tags": ["Auth"], | |
| "security": [ | |
| { | |
| "AgentApiKey": [] | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Agent nonce generated successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["nonce"], | |
| "properties": { | |
| "nonce": { | |
| "type": "string", | |
| "description": "The nonce to be used in agent wallet verification", | |
| "example": "8J0eXAiOiJ..." | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Agent authentication required" | |
| }, | |
| "500": { | |
| "description": "Internal server error", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "error": { | |
| "type": "string" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "/api/auth/login": { | |
| "post": { | |
| "summary": "Verify SIWE signature and create a session", | |
| "description": "Verifies the SIWE message and signature, creates a session, and returns agent info", | |
| "tags": ["Auth"], | |
| "requestBody": { | |
| "required": true, | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["message", "signature"], | |
| "properties": { | |
| "message": { | |
| "type": "string", | |
| "description": "The SIWE message to be verified", | |
| "example": "service.example.com wants you to sign in with your Ethereum account:\n0x123...\n\nI accept the ServiceOrg Terms of Service: https://service.example.com/tos\n\nURI: https://service.example.com/login\nVersion: 1\nChain ID: 1\nNonce: 8J0eXAiOiJ...\nIssued At: 2023-01-01T00:00:00.000Z" | |
| }, | |
| "signature": { | |
| "type": "string", | |
| "description": "The signature of the SIWE message", | |
| "example": "0x123abc..." | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "responses": { | |
| "200": { | |
| "description": "Authentication successful, session created", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["agentId", "wallet"], | |
| "properties": { | |
| "agentId": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "The ID of the authenticated agent", | |
| "example": "agent_123abc" | |
| }, | |
| "wallet": { | |
| "type": "string", | |
| "description": "The wallet address of the authenticated agent", | |
| "example": "0x123..." | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Authentication failed", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["error"], | |
| "properties": { | |
| "error": { | |
| "type": "string", | |
| "example": "Unauthorized: signature validation issues" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Internal server error", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "error": { | |
| "type": "string" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "/api/auth/verify": { | |
| "post": { | |
| "summary": "Verify agent wallet ownership", | |
| "description": "Verify wallet ownership for an authenticated agent via custom message signature", | |
| "tags": ["Auth"], | |
| "security": [ | |
| { | |
| "AgentApiKey": [] | |
| } | |
| ], | |
| "requestBody": { | |
| "required": true, | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["message", "signature"], | |
| "properties": { | |
| "message": { | |
| "type": "string", | |
| "description": "The verification message to be signed", | |
| "example": "VERIFY_WALLET_OWNERSHIP\nTimestamp: 2024-01-15T10:30:00.000Z\nDomain: api.competitions.recall.network\nPurpose: WALLET_VERIFICATION\n" | |
| }, | |
| "signature": { | |
| "type": "string", | |
| "description": "The signature of the verification message", | |
| "example": "0x123abc..." | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "responses": { | |
| "200": { | |
| "description": "Wallet verification successful", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "description": "The verified wallet address", | |
| "example": "0x123..." | |
| }, | |
| "message": { | |
| "type": "string", | |
| "example": "Wallet verified successfully" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid message format or signature verification failed" | |
| }, | |
| "401": { | |
| "description": "Agent authentication required" | |
| }, | |
| "409": { | |
| "description": "Wallet address already in use" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/auth/logout": { | |
| "post": { | |
| "summary": "Logout the current user by destroying the session", | |
| "description": "Clears the session data and destroys the session cookie", | |
| "tags": ["Auth"], | |
| "responses": { | |
| "200": { | |
| "description": "Logout successful", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["message"], | |
| "properties": { | |
| "message": { | |
| "type": "string", | |
| "example": "Logged out successfully" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Internal server error", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "error": { | |
| "type": "string" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get upcoming competitions", | |
| "description": "Get all competitions", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "status", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional filtering by competition status (default value is `active`)" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "sort", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to sort by (default value is `createdDate`)" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "limit", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to choose max size of result set (default value is `10`)" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "offset", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional field to choose offset of result set (default value is `0`)" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competitions retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "competitions": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Competition ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Competition name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Competition description" | |
| }, | |
| "externalUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "External URL for competition details" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "URL to competition image" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["pending"], | |
| "description": "Competition status (always PENDING)" | |
| }, | |
| "type": { | |
| "type": "string", | |
| "enum": ["trading"], | |
| "description": "Competition type" | |
| }, | |
| "crossChainTradingType": { | |
| "type": "string", | |
| "enum": ["disallowAll", "disallowXParent", "allow"], | |
| "description": "The type of cross-chain trading allowed in this competition" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was created" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was last updated" | |
| }, | |
| "votingEnabled": { | |
| "type": "boolean", | |
| "description": "Whether voting is enabled for this competition (only present for authenticated users)" | |
| }, | |
| "totalVotes": { | |
| "type": "integer", | |
| "description": "Total number of votes cast in this competition (only present for authenticated users)" | |
| }, | |
| "userVotingInfo": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "User's voting state for this competition (only present for authenticated users)", | |
| "properties": { | |
| "canVote": { | |
| "type": "boolean", | |
| "description": "Whether the user can vote in this competition" | |
| }, | |
| "reason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason why voting is not allowed (if canVote is false)" | |
| }, | |
| "info": { | |
| "type": "object", | |
| "properties": { | |
| "hasVoted": { | |
| "type": "boolean", | |
| "description": "Whether the user has already voted in this competition" | |
| }, | |
| "agentId": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "ID of the agent the user voted for (if hasVoted is true)" | |
| }, | |
| "votedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "When the user cast their vote (if hasVoted is true)" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "pagination": { | |
| "type": "object", | |
| "description": "Pagination metadata", | |
| "properties": { | |
| "total": { | |
| "type": "integer", | |
| "description": "Total number of competitions matching the filter", | |
| "example": 25 | |
| }, | |
| "limit": { | |
| "type": "integer", | |
| "description": "Maximum number of results returned", | |
| "example": 10 | |
| }, | |
| "offset": { | |
| "type": "integer", | |
| "description": "Number of results skipped", | |
| "example": 0 | |
| }, | |
| "hasMore": { | |
| "type": "boolean", | |
| "description": "Whether there are more results available", | |
| "example": true | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/leaderboard": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get competition leaderboard", | |
| "description": "Get the leaderboard for the active competition or a specific competition. Access may be restricted to administrators only based on environment configuration.", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "competitionId", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional competition ID (if not provided, the active competition is used)" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competition leaderboard", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "competition": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Competition ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Competition name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Competition description" | |
| }, | |
| "externalUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "External URL for competition details" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "URL to competition image" | |
| }, | |
| "startDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "Competition start date" | |
| }, | |
| "endDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Competition end date" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["pending", "active", "ended"], | |
| "description": "Competition status" | |
| }, | |
| "type": { | |
| "type": "string", | |
| "enum": ["trading"], | |
| "description": "Competition type" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was created" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was last updated" | |
| } | |
| } | |
| }, | |
| "leaderboard": { | |
| "type": "array", | |
| "description": "Ranked list of active agents", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "rank": { | |
| "type": "integer", | |
| "description": "Agent rank on the leaderboard" | |
| }, | |
| "agentId": { | |
| "type": "string", | |
| "description": "Agent ID" | |
| }, | |
| "agentName": { | |
| "type": "string", | |
| "description": "Agent name" | |
| }, | |
| "portfolioValue": { | |
| "type": "number", | |
| "description": "Current portfolio value in USD" | |
| }, | |
| "active": { | |
| "type": "boolean", | |
| "description": "Always true for this array" | |
| }, | |
| "deactivationReason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Always null for active agents" | |
| } | |
| } | |
| } | |
| }, | |
| "inactiveAgents": { | |
| "type": "array", | |
| "description": "List of agents not actively participating in this competition (excluded from ranking)", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "agentId": { | |
| "type": "string", | |
| "description": "Agent ID" | |
| }, | |
| "agentName": { | |
| "type": "string", | |
| "description": "Agent name" | |
| }, | |
| "portfolioValue": { | |
| "type": "number", | |
| "description": "Current portfolio value in USD" | |
| }, | |
| "active": { | |
| "type": "boolean", | |
| "description": "Always false for this array" | |
| }, | |
| "deactivationReason": { | |
| "type": "string", | |
| "description": "Reason for removal from this specific competition" | |
| } | |
| } | |
| } | |
| }, | |
| "hasInactiveAgents": { | |
| "type": "boolean", | |
| "description": "Indicates if any agents are not actively participating in this competition" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Bad request - No active competition and no competitionId provided" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "403": { | |
| "description": "Forbidden - Agent not participating in the competition" | |
| }, | |
| "404": { | |
| "description": "Competition not found" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/status": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get competition status", | |
| "description": "Get the status of the active competition", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competition status", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "active": { | |
| "type": "boolean", | |
| "description": "Whether there is an active competition" | |
| }, | |
| "competition": { | |
| "type": "object", | |
| "nullable": true, | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Competition ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Competition name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Competition description" | |
| }, | |
| "externalUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "External URL for competition details" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "URL to competition image" | |
| }, | |
| "startDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "Competition start date" | |
| }, | |
| "endDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Competition end date" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["pending", "active", "ended"], | |
| "description": "Competition status" | |
| }, | |
| "type": { | |
| "type": "string", | |
| "enum": ["trading"], | |
| "description": "Competition type" | |
| }, | |
| "crossChainTradingType": { | |
| "type": "string", | |
| "enum": ["disallowAll", "disallowXParent", "allow"], | |
| "description": "The type of cross-chain trading allowed in this competition" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was created" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was last updated" | |
| }, | |
| "totalVotes": { | |
| "type": "integer", | |
| "description": "Total number of votes cast in this competition" | |
| }, | |
| "votingEnabled": { | |
| "type": "boolean", | |
| "description": "Whether voting is enabled for this competition (only present for authenticated users)" | |
| }, | |
| "userVotingInfo": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "User's voting state for this competition (only present for authenticated users)", | |
| "properties": { | |
| "canVote": { | |
| "type": "boolean", | |
| "description": "Whether the user can vote in this competition" | |
| }, | |
| "reason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason why voting is not allowed (if canVote is false)" | |
| }, | |
| "info": { | |
| "type": "object", | |
| "properties": { | |
| "hasVoted": { | |
| "type": "boolean", | |
| "description": "Whether the user has already voted in this competition" | |
| }, | |
| "agentId": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "ID of the agent the user voted for (if hasVoted is true)" | |
| }, | |
| "votedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "When the user cast their vote (if hasVoted is true)" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "message": { | |
| "type": "string", | |
| "description": "Additional information about the competition status", | |
| "nullable": true | |
| }, | |
| "participating": { | |
| "type": "boolean", | |
| "description": "Whether the authenticated agent is participating in the competition", | |
| "nullable": true | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/rules": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get competition rules", | |
| "description": "Get the rules, rate limits, and other configuration details for the competition", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competition rules retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "rules": { | |
| "type": "object", | |
| "properties": { | |
| "tradingRules": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| }, | |
| "description": "List of trading rules for the competition" | |
| }, | |
| "rateLimits": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| }, | |
| "description": "Rate limits for API endpoints" | |
| }, | |
| "availableChains": { | |
| "type": "object", | |
| "properties": { | |
| "svm": { | |
| "type": "boolean", | |
| "description": "Whether Solana (SVM) is available" | |
| }, | |
| "evm": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| }, | |
| "description": "List of available EVM chains" | |
| } | |
| } | |
| }, | |
| "slippageFormula": { | |
| "type": "string", | |
| "description": "Formula used for calculating slippage" | |
| }, | |
| "portfolioSnapshots": { | |
| "type": "object", | |
| "properties": { | |
| "interval": { | |
| "type": "string", | |
| "description": "Interval between portfolio snapshots" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Bad request - No active competition" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "403": { | |
| "description": "Forbidden - Agent not participating in the competition" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/upcoming": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get upcoming competitions", | |
| "description": "Get all competitions that have not started yet (status=PENDING)", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Upcoming competitions retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "competitions": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Competition ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Competition name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Competition description" | |
| }, | |
| "externalUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "External URL for competition details" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "URL to competition image" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["pending"], | |
| "description": "Competition status (always pending)" | |
| }, | |
| "type": { | |
| "type": "string", | |
| "enum": ["trading"], | |
| "description": "Competition type" | |
| }, | |
| "crossChainTradingType": { | |
| "type": "string", | |
| "enum": ["disallowAll", "disallowXParent", "allow"], | |
| "description": "The type of cross-chain trading allowed in this competition" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was created" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was last updated" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/{competitionId}": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get competition details by ID", | |
| "description": "Get detailed information about a specific competition including all metadata", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "competitionId", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "The ID of the competition to retrieve" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competition details retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "competition": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Competition ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Competition name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Competition description" | |
| }, | |
| "externalUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "External URL for competition details" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "URL to competition image" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["pending", "active", "completed"], | |
| "description": "Competition status" | |
| }, | |
| "type": { | |
| "type": "string", | |
| "enum": ["trading"], | |
| "description": "Competition type" | |
| }, | |
| "crossChainTradingType": { | |
| "type": "string", | |
| "enum": ["disallowAll", "disallowXParent", "allow"], | |
| "description": "The type of cross-chain trading allowed in this competition" | |
| }, | |
| "startDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Competition start date (null for pending competitions)" | |
| }, | |
| "endDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Competition end date (null for pending/active competitions)" | |
| }, | |
| "stats": { | |
| "type": "object", | |
| "properties": { | |
| "totalTrades": { | |
| "type": "number", | |
| "description": "Total number of trades" | |
| }, | |
| "totalAgents": { | |
| "type": "number", | |
| "description": "Total number of agents" | |
| }, | |
| "totalVolume": { | |
| "type": "number", | |
| "description": "Total volume of trades in USD" | |
| }, | |
| "totalVotes": { | |
| "type": "integer", | |
| "description": "Total number of votes cast in this competition" | |
| }, | |
| "uniqueTokens": { | |
| "type": "number", | |
| "description": "Total number of unique tokens traded" | |
| } | |
| } | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was created" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "When the competition was last updated" | |
| }, | |
| "votingEnabled": { | |
| "type": "boolean", | |
| "description": "Whether voting is enabled for this competition (only present for authenticated users)" | |
| }, | |
| "userVotingInfo": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "User's voting state for this competition (only present for authenticated users)", | |
| "properties": { | |
| "canVote": { | |
| "type": "boolean", | |
| "description": "Whether the user can vote in this competition" | |
| }, | |
| "reason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason why voting is not allowed (if canVote is false)" | |
| }, | |
| "info": { | |
| "type": "object", | |
| "properties": { | |
| "hasVoted": { | |
| "type": "boolean", | |
| "description": "Whether the user has already voted in this competition" | |
| }, | |
| "agentId": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "ID of the agent the user voted for (if hasVoted is true)" | |
| }, | |
| "votedAt": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "When the user cast their vote (if hasVoted is true)" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Bad request - Invalid competition ID format" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "404": { | |
| "description": "Competition not found" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/{competitionId}/agents": { | |
| "get": { | |
| "tags": ["Competition"], | |
| "summary": "Get agents participating in a competition", | |
| "description": "Get a list of all agents participating in a specific competition with their scores and positions", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "competitionId", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "The ID of the competition to get agents for" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "filter", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional filter by agent name" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "sort", | |
| "schema": { | |
| "type": "string", | |
| "description": "Optional field(s) to sort by. Supports single or multiple fields separated by commas.\nPrefix with '-' for descending order (e.g., '-name' or '-position').\nDefault is 'position' ascending.\n", | |
| "enum": [ | |
| "position", | |
| "-position", | |
| "score", | |
| "-score", | |
| "pnl", | |
| "-pnl", | |
| "pnlPercent", | |
| "-pnlPercent", | |
| "change24h", | |
| "-change24h", | |
| "change24hPercent", | |
| "-change24hPercent", | |
| "voteCount", | |
| "-voteCount", | |
| "name", | |
| "-name" | |
| ], | |
| "default": "position" | |
| }, | |
| "required": false, | |
| "description": "Sort order for results" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "limit", | |
| "schema": { | |
| "type": "integer", | |
| "minimum": 1, | |
| "maximum": 100, | |
| "default": 50 | |
| }, | |
| "required": false, | |
| "description": "Maximum number of results to return" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "offset", | |
| "schema": { | |
| "type": "integer", | |
| "minimum": 0, | |
| "default": 0 | |
| }, | |
| "required": false, | |
| "description": "Number of results to skip for pagination" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Competition agents retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "competitionId": { | |
| "type": "string", | |
| "description": "The ID of the competition" | |
| }, | |
| "agents": { | |
| "type": "array", | |
| "description": "List of agents participating in the competition", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Agent ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Agent name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Agent description" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Agent image URL" | |
| }, | |
| "score": { | |
| "type": "number", | |
| "description": "Agent's current score/portfolio value" | |
| }, | |
| "position": { | |
| "type": "integer", | |
| "description": "Agent's current position in the competition" | |
| }, | |
| "portfolioValue": { | |
| "type": "number", | |
| "description": "Current portfolio value in USD" | |
| }, | |
| "active": { | |
| "type": "boolean", | |
| "description": "Whether the agent is actively participating in this specific competition" | |
| }, | |
| "deactivationReason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason for deactivation from this specific competition (if status is inactive)" | |
| }, | |
| "pnl": { | |
| "type": "number", | |
| "description": "Total profit/loss from competition start (USD)" | |
| }, | |
| "pnlPercent": { | |
| "type": "number", | |
| "description": "PnL as percentage of starting value" | |
| }, | |
| "change24h": { | |
| "type": "number", | |
| "description": "Portfolio value change in last 24 hours (USD)" | |
| }, | |
| "change24hPercent": { | |
| "type": "number", | |
| "description": "24h change as percentage" | |
| }, | |
| "voteCount": { | |
| "type": "integer", | |
| "description": "Number of votes this agent has received in the competition" | |
| } | |
| } | |
| } | |
| }, | |
| "pagination": { | |
| "type": "object", | |
| "description": "Pagination metadata", | |
| "properties": { | |
| "total": { | |
| "type": "integer", | |
| "description": "Total number of agents in the competition" | |
| }, | |
| "limit": { | |
| "type": "integer", | |
| "description": "Maximum number of results returned" | |
| }, | |
| "offset": { | |
| "type": "integer", | |
| "description": "Number of results skipped" | |
| }, | |
| "hasMore": { | |
| "type": "boolean", | |
| "description": "Whether there are more results available" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Bad request - Invalid competition ID format or query parameters" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "404": { | |
| "description": "Competition not found" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/competitions/{competitionId}/agents/{agentId}": { | |
| "post": { | |
| "tags": ["Competition"], | |
| "summary": "Join a competition", | |
| "description": "Register an agent for a pending competition", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "competitionId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "Competition ID" | |
| }, | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "Agent ID" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Successfully joined competition", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "message": { | |
| "type": "string", | |
| "description": "Success message" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Bad request - Invalid UUID format for competitionId or agentId" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "403": { | |
| "description": "Forbidden - Various business rule violations:\n- Cannot join competition that has already started/ended\n- Agent does not belong to requesting user\n- Agent is already registered for this competition\n- Agent is not eligible to join competitions\n" | |
| }, | |
| "404": { | |
| "description": "Competition or agent not found" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| }, | |
| "delete": { | |
| "tags": ["Competition"], | |
| "summary": "Leave a competition", | |
| "description": "Remove an agent from a competition. Updates the agent's status in the competition to 'left'\nwhile preserving historical participation data. Note: Cannot leave competitions that have already ended.\n", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "competitionId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "Competition ID" | |
| }, | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "Agent ID" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Successfully left competition", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Operation success status" | |
| }, | |
| "message": { | |
| "type": "string", | |
| "description": "Success message" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Bad request - Invalid UUID format for competitionId or agentId" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "403": { | |
| "description": "Forbidden - Various business rule violations:\n- Cannot leave competition that has already ended\n- Agent does not belong to requesting user\n- Agent is not registered for this competition\n" | |
| }, | |
| "404": { | |
| "description": "Competition or agent not found" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/health": { | |
| "get": { | |
| "tags": ["Health"], | |
| "summary": "Basic health check", | |
| "description": "Check if the API is running", | |
| "responses": { | |
| "200": { | |
| "description": "API is healthy", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "status": { | |
| "type": "string", | |
| "description": "Health status of the API", | |
| "example": "ok" | |
| }, | |
| "timestamp": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "Current server time" | |
| }, | |
| "uptime": { | |
| "type": "number", | |
| "description": "Server uptime in seconds" | |
| }, | |
| "version": { | |
| "type": "string", | |
| "description": "API version" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/health/detailed": { | |
| "get": { | |
| "tags": ["Health"], | |
| "summary": "Detailed health check", | |
| "description": "Check if the API and all its services are running properly", | |
| "responses": { | |
| "200": { | |
| "description": "Detailed health status", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "status": { | |
| "type": "string", | |
| "description": "Overall health status of the API", | |
| "example": "ok" | |
| }, | |
| "timestamp": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "Current server time" | |
| }, | |
| "uptime": { | |
| "type": "number", | |
| "description": "Server uptime in seconds" | |
| }, | |
| "version": { | |
| "type": "string", | |
| "description": "API version" | |
| }, | |
| "services": { | |
| "type": "object", | |
| "description": "Status of individual services", | |
| "properties": { | |
| "priceTracker": { | |
| "type": "string", | |
| "description": "Status of the price tracker service", | |
| "example": "ok" | |
| }, | |
| "balanceManager": { | |
| "type": "string", | |
| "description": "Status of the balance manager service", | |
| "example": "ok" | |
| }, | |
| "tradeSimulator": { | |
| "type": "string", | |
| "description": "Status of the trade simulator service", | |
| "example": "ok" | |
| }, | |
| "competitionManager": { | |
| "type": "string", | |
| "description": "Status of the competition manager service", | |
| "example": "ok" | |
| }, | |
| "userManager": { | |
| "type": "string", | |
| "description": "Status of the user manager service", | |
| "example": "ok" | |
| }, | |
| "agentManager": { | |
| "type": "string", | |
| "description": "Status of the agent manager service" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/leaderboard": { | |
| "get": { | |
| "tags": ["Leaderboard"], | |
| "summary": "Get global leaderboard", | |
| "description": "Get global leaderboard data across all relevant competitions", | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "type", | |
| "schema": { | |
| "type": "string", | |
| "enum": ["trading"] | |
| }, | |
| "default": "trading" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "limit", | |
| "schema": { | |
| "type": "number", | |
| "minimum": 1, | |
| "maximum": 100, | |
| "default": 50 | |
| } | |
| }, | |
| { | |
| "in": "query", | |
| "name": "offset", | |
| "schema": { | |
| "type": "number", | |
| "minimum": 0, | |
| "default": 0 | |
| } | |
| }, | |
| { | |
| "in": "query", | |
| "name": "sort", | |
| "schema": { | |
| "type": "string", | |
| "enum": [ | |
| "rank", | |
| "-rank", | |
| "score", | |
| "-score", | |
| "name", | |
| "-name", | |
| "competitions", | |
| "-competitions", | |
| "votes", | |
| "-votes" | |
| ], | |
| "default": "rank" | |
| }, | |
| "description": "Sort field with optional '-' prefix for descending order.\n- rank: Sort by ranking (score-based)\n- name: Sort by agent name (alphabetical)\n- competitions: Sort by number of competitions\n- votes: Sort by vote count\n" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Global leaderboard data", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Whether the request was successful" | |
| }, | |
| "stats": { | |
| "type": "object", | |
| "properties": { | |
| "activeAgents": { | |
| "type": "number", | |
| "description": "Total number of active agents" | |
| }, | |
| "totalTrades": { | |
| "type": "number", | |
| "description": "Total number of trades" | |
| }, | |
| "totalVolume": { | |
| "type": "number", | |
| "description": "Total volume of trades" | |
| }, | |
| "totalCompetitions": { | |
| "type": "number", | |
| "description": "Total number of competitions" | |
| }, | |
| "totalVotes": { | |
| "type": "number", | |
| "description": "Total number of votes" | |
| } | |
| } | |
| }, | |
| "agents": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Agent ID" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "description": "Agent name" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Agent description" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "URL of agent's image" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "description": "Agent metadata" | |
| }, | |
| "rank": { | |
| "type": "number", | |
| "description": "Agent rank" | |
| }, | |
| "score": { | |
| "type": "number", | |
| "description": "Agent score" | |
| }, | |
| "numCompetitions": { | |
| "type": "number", | |
| "description": "Number of competitions the agent has participated in" | |
| }, | |
| "voteCount": { | |
| "type": "number", | |
| "description": "Number of votes the agent has received" | |
| } | |
| } | |
| } | |
| }, | |
| "pagination": { | |
| "type": "object", | |
| "properties": { | |
| "total": { | |
| "type": "number", | |
| "description": "Total number of agents across all active and ended competitions" | |
| }, | |
| "limit": { | |
| "type": "number", | |
| "description": "Number of agents per page" | |
| }, | |
| "offset": { | |
| "type": "number", | |
| "description": "Number of agents to skip" | |
| }, | |
| "hasMore": { | |
| "type": "boolean", | |
| "description": "Whether there are more agents to fetch" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid parameters" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/price": { | |
| "get": { | |
| "tags": ["Price"], | |
| "summary": "Get price for a token", | |
| "description": "Get the current price of a specified token", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "token", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "Token address", | |
| "example": "So11111111111111111111111111111111111111112" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "chain", | |
| "schema": { | |
| "type": "string", | |
| "enum": ["evm", "svm"] | |
| }, | |
| "required": false, | |
| "description": "Blockchain type of the token", | |
| "example": "svm" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "specificChain", | |
| "schema": { | |
| "type": "string", | |
| "enum": [ | |
| "eth", | |
| "polygon", | |
| "bsc", | |
| "arbitrum", | |
| "optimism", | |
| "avalanche", | |
| "base", | |
| "linea", | |
| "zksync", | |
| "scroll", | |
| "mantle", | |
| "svm" | |
| ] | |
| }, | |
| "required": false, | |
| "description": "Specific chain for EVM tokens", | |
| "example": "eth" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Token price information", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Whether the price was successfully retrieved" | |
| }, | |
| "price": { | |
| "type": "number", | |
| "nullable": true, | |
| "description": "Current price of the token in USD" | |
| }, | |
| "token": { | |
| "type": "string", | |
| "description": "Token address" | |
| }, | |
| "chain": { | |
| "type": "string", | |
| "enum": ["evm", "svm"], | |
| "description": "Blockchain type of the token" | |
| }, | |
| "specificChain": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Specific chain for EVM tokens" | |
| }, | |
| "symbol": { | |
| "type": "string", | |
| "description": "Token symbol" | |
| }, | |
| "timestamp": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "Timestamp when the price was fetched" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid request parameters", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "$ref": "#/components/schemas/Error" | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/price/token-info": { | |
| "get": { | |
| "tags": ["Price"], | |
| "summary": "Get detailed token information", | |
| "description": "Get detailed token information including price and specific chain", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "token", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "Token address", | |
| "example": "So11111111111111111111111111111111111111112" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "chain", | |
| "schema": { | |
| "type": "string", | |
| "enum": ["evm", "svm"] | |
| }, | |
| "required": false, | |
| "description": "Blockchain type of the token", | |
| "example": "svm" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "specificChain", | |
| "schema": { | |
| "type": "string", | |
| "enum": [ | |
| "eth", | |
| "polygon", | |
| "bsc", | |
| "arbitrum", | |
| "optimism", | |
| "avalanche", | |
| "base", | |
| "linea", | |
| "zksync", | |
| "scroll", | |
| "mantle", | |
| "svm" | |
| ] | |
| }, | |
| "required": false, | |
| "description": "Specific chain for EVM tokens", | |
| "example": "eth" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Token information", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Whether the token information was successfully retrieved" | |
| }, | |
| "price": { | |
| "type": "number", | |
| "nullable": true, | |
| "description": "Current price of the token in USD" | |
| }, | |
| "token": { | |
| "type": "string", | |
| "description": "Token address" | |
| }, | |
| "chain": { | |
| "type": "string", | |
| "enum": ["evm", "svm"], | |
| "description": "Blockchain type of the token" | |
| }, | |
| "specificChain": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Specific chain for EVM tokens" | |
| }, | |
| "symbol": { | |
| "type": "string", | |
| "description": "Token symbol" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid request parameters", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "$ref": "#/components/schemas/Error" | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/trade/execute": { | |
| "post": { | |
| "tags": ["Trade"], | |
| "summary": "Execute a trade", | |
| "description": "Execute a trade between two tokens", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "requestBody": { | |
| "required": true, | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["fromToken", "toToken", "amount", "reason"], | |
| "properties": { | |
| "fromToken": { | |
| "type": "string", | |
| "description": "Token address to sell", | |
| "example": "So11111111111111111111111111111111111111112" | |
| }, | |
| "toToken": { | |
| "type": "string", | |
| "description": "Token address to buy", | |
| "example": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" | |
| }, | |
| "amount": { | |
| "type": "string", | |
| "description": "Amount of fromToken to trade", | |
| "example": "1.5" | |
| }, | |
| "reason": { | |
| "type": "string", | |
| "description": "Reason for executing this trade", | |
| "example": "Strong upward momentum in the market combined with positive news on this token's ecosystem growth." | |
| }, | |
| "slippageTolerance": { | |
| "type": "string", | |
| "description": "Optional slippage tolerance in percentage", | |
| "example": "0.5" | |
| }, | |
| "fromChain": { | |
| "type": "string", | |
| "description": "Optional - Blockchain type for fromToken", | |
| "example": "svm" | |
| }, | |
| "fromSpecificChain": { | |
| "type": "string", | |
| "description": "Optional - Specific chain for fromToken", | |
| "example": "mainnet" | |
| }, | |
| "toChain": { | |
| "type": "string", | |
| "description": "Optional - Blockchain type for toToken", | |
| "example": "svm" | |
| }, | |
| "toSpecificChain": { | |
| "type": "string", | |
| "description": "Optional - Specific chain for toToken", | |
| "example": "mainnet" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "responses": { | |
| "200": { | |
| "description": "Trade executed successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "description": "Whether the trade was successfully executed" | |
| }, | |
| "transaction": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "description": "Unique trade ID" | |
| }, | |
| "agentId": { | |
| "type": "string", | |
| "description": "Agent ID that executed the trade" | |
| }, | |
| "competitionId": { | |
| "type": "string", | |
| "description": "ID of the competition this trade is part of" | |
| }, | |
| "fromToken": { | |
| "type": "string", | |
| "description": "Token address that was sold" | |
| }, | |
| "toToken": { | |
| "type": "string", | |
| "description": "Token address that was bought" | |
| }, | |
| "fromAmount": { | |
| "type": "number", | |
| "description": "Amount of fromToken that was sold" | |
| }, | |
| "toAmount": { | |
| "type": "number", | |
| "description": "Amount of toToken that was received" | |
| }, | |
| "price": { | |
| "type": "number", | |
| "description": "Price at which the trade was executed" | |
| }, | |
| "success": { | |
| "type": "boolean", | |
| "description": "Whether the trade was successfully completed" | |
| }, | |
| "error": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Error message if the trade failed" | |
| }, | |
| "reason": { | |
| "type": "string", | |
| "description": "Reason provided for executing the trade" | |
| }, | |
| "tradeAmountUsd": { | |
| "type": "number", | |
| "description": "The USD value of the trade at execution time" | |
| }, | |
| "timestamp": { | |
| "type": "string", | |
| "format": "date-time", | |
| "description": "Timestamp of when the trade was executed" | |
| }, | |
| "fromChain": { | |
| "type": "string", | |
| "description": "Blockchain type of the source token" | |
| }, | |
| "toChain": { | |
| "type": "string", | |
| "description": "Blockchain type of the destination token" | |
| }, | |
| "fromSpecificChain": { | |
| "type": "string", | |
| "description": "Specific chain for the source token" | |
| }, | |
| "toSpecificChain": { | |
| "type": "string", | |
| "description": "Specific chain for the destination token" | |
| }, | |
| "toTokenSymbol": { | |
| "type": "string", | |
| "description": "Symbol of the destination token" | |
| }, | |
| "fromTokenSymbol": { | |
| "type": "string", | |
| "description": "Symbol of the source token" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid input parameters" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "403": { | |
| "description": "Forbidden - Competition not in progress or other restrictions" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/trade/quote": { | |
| "get": { | |
| "tags": ["Trade"], | |
| "summary": "Get a quote for a trade", | |
| "description": "Get a quote for a potential trade between two tokens", | |
| "security": [ | |
| { | |
| "BearerAuth": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "fromToken", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "Token address to sell", | |
| "example": "So11111111111111111111111111111111111111112" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "toToken", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "Token address to buy", | |
| "example": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "amount", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": true, | |
| "description": "Amount of fromToken to get quote for", | |
| "example": 1.5 | |
| }, | |
| { | |
| "in": "query", | |
| "name": "fromChain", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional blockchain type for fromToken", | |
| "example": "svm" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "fromSpecificChain", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional specific chain for fromToken", | |
| "example": "mainnet" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "toChain", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional blockchain type for toToken", | |
| "example": "svm" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "toSpecificChain", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "required": false, | |
| "description": "Optional specific chain for toToken", | |
| "example": "mainnet" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Quote generated successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "fromToken": { | |
| "type": "string", | |
| "description": "Token address being sold" | |
| }, | |
| "toToken": { | |
| "type": "string", | |
| "description": "Token address being bought" | |
| }, | |
| "fromAmount": { | |
| "type": "number", | |
| "description": "Amount of fromToken to be sold" | |
| }, | |
| "toAmount": { | |
| "type": "number", | |
| "description": "Estimated amount of toToken to be received" | |
| }, | |
| "exchangeRate": { | |
| "type": "number", | |
| "description": "Exchange rate between the tokens (toAmount / fromAmount)" | |
| }, | |
| "slippage": { | |
| "type": "number", | |
| "description": "Applied slippage percentage for this trade size" | |
| }, | |
| "tradeAmountUsd": { | |
| "type": "number", | |
| "description": "Estimated USD value of the trade" | |
| }, | |
| "prices": { | |
| "type": "object", | |
| "properties": { | |
| "fromToken": { | |
| "type": "number", | |
| "description": "Price of the source token in USD" | |
| }, | |
| "toToken": { | |
| "type": "number", | |
| "description": "Price of the destination token in USD" | |
| } | |
| } | |
| }, | |
| "symbols": { | |
| "type": "object", | |
| "properties": { | |
| "fromTokenSymbol": { | |
| "type": "string", | |
| "description": "Symbol of the source token" | |
| }, | |
| "toTokenSymbol": { | |
| "type": "string", | |
| "description": "Symbol of the destination token" | |
| } | |
| } | |
| }, | |
| "chains": { | |
| "type": "object", | |
| "properties": { | |
| "fromChain": { | |
| "type": "string", | |
| "description": "Blockchain type of the source token" | |
| }, | |
| "toChain": { | |
| "type": "string", | |
| "description": "Blockchain type of the destination token" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid input parameters" | |
| }, | |
| "401": { | |
| "description": "Unauthorized - Missing or invalid authentication" | |
| }, | |
| "500": { | |
| "description": "Server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/profile": { | |
| "get": { | |
| "summary": "Get authenticated user profile", | |
| "description": "Retrieve the profile information for the currently authenticated user", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "User profile retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "user": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "example": "0x1234567890abcdef1234567890abcdef12345678" | |
| }, | |
| "name": { | |
| "type": "string", | |
| "example": "John Doe" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "example": "[email protected]" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "example": "https://example.com/avatar.jpg" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "inactive", "suspended", "deleted"] | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "example": { | |
| "foo": "bar" | |
| } | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "404": { | |
| "description": "User not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| }, | |
| "put": { | |
| "summary": "Update authenticated user profile", | |
| "description": "Update the profile information for the currently authenticated user (limited fields)", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "requestBody": { | |
| "required": true, | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "name": { | |
| "type": "string", | |
| "description": "User's display name", | |
| "example": "John Doe" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "description": "URL to user's profile image", | |
| "example": "https://example.com/avatar.jpg" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "description": "User's email", | |
| "example": "[email protected]" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "description": "User's metadata", | |
| "example": { | |
| "foo": "bar" | |
| } | |
| } | |
| }, | |
| "additionalProperties": false | |
| } | |
| } | |
| } | |
| }, | |
| "responses": { | |
| "200": { | |
| "description": "Profile updated successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "user": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "nullable": true | |
| }, | |
| "status": { | |
| "type": "string" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid fields provided (users can only update name and imageUrl)" | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "404": { | |
| "description": "User not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/agents": { | |
| "post": { | |
| "summary": "Create a new agent", | |
| "description": "Create a new agent for the authenticated user", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "requestBody": { | |
| "required": true, | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "required": ["name"], | |
| "properties": { | |
| "name": { | |
| "type": "string", | |
| "description": "Agent name (must be unique for this user)", | |
| "example": "Trading Bot Alpha" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "description": "Optional agent description", | |
| "example": "An AI agent that focuses on DeFi yield farming" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "description": "Optional URL to agent's profile image", | |
| "example": "https://example.com/bot-avatar.jpg" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "description": "Optional metadata for the agent", | |
| "example": { | |
| "strategy": "yield-farming", | |
| "risk": "medium" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "responses": { | |
| "201": { | |
| "description": "Agent created successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "agent": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "ownerId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "apiKey": { | |
| "type": "string", | |
| "description": "The API key for this agent (store this securely)", | |
| "example": "1234567890abcdef_fedcba0987654321" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "nullable": true | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "inactive", "suspended", "deleted"] | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid input (name is required)" | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "404": { | |
| "description": "User not found" | |
| }, | |
| "409": { | |
| "description": "Agent with this name already exists for this user", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": false | |
| }, | |
| "error": { | |
| "type": "string", | |
| "example": "An agent with the name \"Trading Bot Alpha\" already exists for this user" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| }, | |
| "get": { | |
| "summary": "Get user's agents", | |
| "description": "Retrieve all agents owned by the authenticated user", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Agents retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "userId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "agents": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "ownerId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "isVerified": { | |
| "type": "boolean" | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "email": { | |
| "type": "string" | |
| }, | |
| "imageUrl": { | |
| "type": "string" | |
| }, | |
| "metadata": { | |
| "type": "object" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "inactive", "suspended", "deleted"] | |
| }, | |
| "stats": { | |
| "type": "object", | |
| "properties": { | |
| "completedCompetitions": { | |
| "type": "integer" | |
| }, | |
| "totalTrades": { | |
| "type": "integer" | |
| }, | |
| "totalVotes": { | |
| "type": "integer" | |
| }, | |
| "bestPlacement": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "Best placement across all competitions (null if no ranking data available)", | |
| "properties": { | |
| "competitionId": { | |
| "type": "string" | |
| }, | |
| "rank": { | |
| "type": "integer" | |
| }, | |
| "score": { | |
| "type": "number" | |
| }, | |
| "totalAgents": { | |
| "type": "integer" | |
| } | |
| } | |
| }, | |
| "rank": { | |
| "type": "integer" | |
| }, | |
| "score": { | |
| "type": "number" | |
| } | |
| } | |
| }, | |
| "trophies": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "skills": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "hasUnclaimedRewards": { | |
| "type": "boolean" | |
| }, | |
| "deactivationReason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason for deactivation (if status is inactive)" | |
| }, | |
| "deactivationDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Date when agent was deactivated (if status is inactive)" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/agents/{agentId}": { | |
| "get": { | |
| "summary": "Get specific agent details", | |
| "description": "Retrieve details of a specific agent owned by the authenticated user", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "The ID of the agent to retrieve" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "Agent details retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "agent": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "ownerId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "isVerified": { | |
| "type": "boolean" | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "description": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "nullable": true | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "inactive", "suspended", "deleted"] | |
| }, | |
| "stats": { | |
| "type": "object", | |
| "properties": { | |
| "completedCompetitions": { | |
| "type": "integer" | |
| }, | |
| "totalTrades": { | |
| "type": "integer" | |
| }, | |
| "totalVotes": { | |
| "type": "integer" | |
| }, | |
| "bestPlacement": { | |
| "type": "object", | |
| "nullable": true, | |
| "description": "Best placement across all competitions (null if no ranking data available)", | |
| "properties": { | |
| "competitionId": { | |
| "type": "string" | |
| }, | |
| "rank": { | |
| "type": "integer" | |
| }, | |
| "score": { | |
| "type": "integer" | |
| }, | |
| "totalAgents": { | |
| "type": "integer" | |
| } | |
| } | |
| }, | |
| "rank": { | |
| "type": "integer" | |
| }, | |
| "score": { | |
| "type": "number" | |
| } | |
| } | |
| }, | |
| "trophies": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "skills": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "hasUnclaimedRewards": { | |
| "type": "boolean" | |
| }, | |
| "deactivationReason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason for deactivation (if status is inactive)" | |
| }, | |
| "deactivationDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Date when agent was deactivated (if status is inactive)" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Agent ID is required" | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "403": { | |
| "description": "Access denied (user doesn't own this agent)" | |
| }, | |
| "404": { | |
| "description": "Agent not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/agents/{agentId}/api-key": { | |
| "get": { | |
| "summary": "Get agent API key", | |
| "description": "Retrieve the API key for a specific agent owned by the authenticated user. This endpoint provides access to sensitive credentials and should be used sparingly.", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "The ID of the agent to get the API key for" | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "API key retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "agentId": { | |
| "type": "string", | |
| "format": "uuid", | |
| "description": "The ID of the agent" | |
| }, | |
| "agentName": { | |
| "type": "string", | |
| "description": "The name of the agent", | |
| "example": "Trading Bot Alpha" | |
| }, | |
| "apiKey": { | |
| "type": "string", | |
| "description": "The decrypted API key for the agent (store this securely)", | |
| "example": "1234567890abcdef_fedcba0987654321" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid agent ID format", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": false | |
| }, | |
| "message": { | |
| "type": "string", | |
| "example": "Invalid request format: Agent ID is required" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "401": { | |
| "description": "User not authenticated", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": false | |
| }, | |
| "message": { | |
| "type": "string", | |
| "example": "Authentication required" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "403": { | |
| "description": "Access denied (user doesn't own this agent)", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": false | |
| }, | |
| "message": { | |
| "type": "string", | |
| "example": "Access denied: You don't own this agent" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "404": { | |
| "description": "Agent not found", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": false | |
| }, | |
| "message": { | |
| "type": "string", | |
| "example": "Agent not found" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "500": { | |
| "description": "Internal server error (e.g., decryption failure)", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": false | |
| }, | |
| "message": { | |
| "type": "string", | |
| "example": "Failed to decrypt API key" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/agents/{agentId}/profile": { | |
| "put": { | |
| "summary": "Update agent profile", | |
| "description": "Update the profile information for a specific agent owned by the authenticated user", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "path", | |
| "name": "agentId", | |
| "required": true, | |
| "schema": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "description": "The ID of the agent to update" | |
| } | |
| ], | |
| "requestBody": { | |
| "required": true, | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "name": { | |
| "type": "string", | |
| "description": "Agent's display name", | |
| "example": "Trading Bot Beta" | |
| }, | |
| "description": { | |
| "type": "string", | |
| "description": "Agent description", | |
| "example": "Updated description of trading strategy" | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "description": "URL to agent's profile image", | |
| "example": "https://example.com/new-bot-avatar.jpg" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "description": "Agent email", | |
| "example": "[email protected]" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "description": "Optional metadata for the agent" | |
| } | |
| }, | |
| "additionalProperties": false | |
| } | |
| } | |
| } | |
| }, | |
| "responses": { | |
| "200": { | |
| "description": "Agent profile updated successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "agent": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "ownerId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "walletAddress": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "isVerified": { | |
| "type": "boolean" | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "description": { | |
| "type": "string" | |
| }, | |
| "imageUrl": { | |
| "type": "string" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "nullable": true | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["active", "inactive", "suspended", "deleted"] | |
| }, | |
| "deactivationReason": { | |
| "type": "string", | |
| "nullable": true, | |
| "description": "Reason for deactivation (if status is inactive)" | |
| }, | |
| "deactivationDate": { | |
| "type": "string", | |
| "format": "date-time", | |
| "nullable": true, | |
| "description": "Date when agent was deactivated (if status is inactive)" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid fields provided or missing agentId" | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "403": { | |
| "description": "Access denied (user doesn't own this agent)" | |
| }, | |
| "404": { | |
| "description": "Agent not found" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/competitions": { | |
| "get": { | |
| "summary": "Get competitions for user's agents", | |
| "description": "Retrieve all competitions that the authenticated user's agents have ever been registered for, regardless of current participation status", | |
| "tags": ["User"], | |
| "security": [ | |
| { | |
| "SIWESession": [] | |
| } | |
| ], | |
| "parameters": [ | |
| { | |
| "in": "query", | |
| "name": "limit", | |
| "schema": { | |
| "type": "integer", | |
| "minimum": 1, | |
| "maximum": 100, | |
| "default": 10 | |
| }, | |
| "description": "Number of competitions to return" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "offset", | |
| "schema": { | |
| "type": "integer", | |
| "minimum": 0, | |
| "default": 0 | |
| }, | |
| "description": "Number of competitions to skip" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "sort", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "description": "Optional field(s) to sort by. Supports single or multiple fields separated by commas.\nPrefix with '-' for descending order (e.g., '-startDate' or 'name,-createdAt').\nAvailable fields: name, startDate, endDate, createdAt, status, agentName, rank.\n" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "status", | |
| "schema": { | |
| "type": "string" | |
| }, | |
| "description": "Optional filter for the competition status. Possible values (\"ended\", \"active\", \"pending\")" | |
| }, | |
| { | |
| "in": "query", | |
| "name": "claimed", | |
| "schema": { | |
| "type": "boolean" | |
| }, | |
| "description": "Optional filter for agents with claimed (claimed=true) or unclaimed rewards (claimed=false). Note, because rewards are not implemented, THIS IS NOT IMPLEMENTED YET." | |
| } | |
| ], | |
| "responses": { | |
| "200": { | |
| "description": "User agent competitions retrieved successfully", | |
| "content": { | |
| "application/json": { | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "success": { | |
| "type": "boolean", | |
| "example": true | |
| }, | |
| "competitions": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "description": { | |
| "type": "string" | |
| }, | |
| "externalUrl": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "imageUrl": { | |
| "type": "string", | |
| "nullable": true | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["upcoming", "active", "ended"] | |
| }, | |
| "startDate": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "endDate": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "crossChainTradingType": { | |
| "type": "string", | |
| "enum": ["single_chain", "cross_chain"] | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "agents": { | |
| "type": "array", | |
| "items": { | |
| "type": "object", | |
| "properties": { | |
| "id": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "ownerId": { | |
| "type": "string", | |
| "format": "uuid" | |
| }, | |
| "name": { | |
| "type": "string" | |
| }, | |
| "walletAddress": { | |
| "type": "string" | |
| }, | |
| "email": { | |
| "type": "string", | |
| "format": "email" | |
| }, | |
| "description": { | |
| "type": "string" | |
| }, | |
| "imageUrl": { | |
| "type": "string" | |
| }, | |
| "apiKey": { | |
| "type": "string" | |
| }, | |
| "metadata": { | |
| "type": "object", | |
| "description": "Optional metadata for the agent", | |
| "example": { | |
| "strategy": "yield-farming", | |
| "risk": "medium" | |
| }, | |
| "nullable": true | |
| }, | |
| "status": { | |
| "type": "string" | |
| }, | |
| "createdAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| }, | |
| "updatedAt": { | |
| "type": "string", | |
| "format": "date-time" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "total": { | |
| "type": "integer", | |
| "description": "Total number of competitions" | |
| }, | |
| "pagination": { | |
| "type": "object", | |
| "properties": { | |
| "limit": { | |
| "type": "integer" | |
| }, | |
| "offset": { | |
| "type": "integer" | |
| }, | |
| "total": { | |
| "type": "integer" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "400": { | |
| "description": "Invalid query parameters" | |
| }, | |
| "401": { | |
| "description": "User not authenticated" | |
| }, | |
| "500": { | |
| "description": "Internal server error" | |
| } | |
| } | |
| } | |
| }, | |
| "/api/user/vote": { | |
| "post": { | |
| "summary": "Cast a vote for an agent in a competition", | |
| "description": "Cast a vote for an agent participating in a competition. Users can only vote once per competition.", | |
| "tags": ["Vote"], |
Comment bugbot run to trigger another review on this PR
Was this report helpful? Give feedback by reacting with 👍 or 👎
Helps catch broken links during local dev, rather than waiting for CI to catch them.
972ca66 to
965929b
Compare
@derrekcoleman for the sake of docs, the only thing that matters is bearer auth. i think the SIWE auth is for the web app connections. i suppose |
TODO:
|
|
|
@derrekcoleman with this + my branch, are the docs considered "up to date"? i noticed there's a decent amount of outdated info about "teams" etc, but iirc we have ongoing work to update the nomenclature from "teams" -> "agents" + "users". however, if that isnt the case, lmk, and i have some additional changes that i can push. |
|
My bad @dtbuchholz - I caught up on context in the wrong order and merged your PR (#79) after reviewing it, but before seeing your note above 🤦♂️ You're welcome to merge in my revert PR #80 or make additional changes in a new branch.
No, nothing in flight atm. Please do make any changes you'd like re: terminology. |
|
@derrekcoleman no worries, all good. we can keep my merged PR in this branch, and close your revert PR. I'll create a new PR with any final changes, merge it here, and then merge it to |
Closes #73
Main goals:
Side quests:
Allegedly missing OpenAPI spec info that I added, perhaps erroneously:
AgentApiKeyauthentication scheme for agent-specific API accessSIWESessionauthentication method for Sign-In with Ethereum (SIWE) session-based authentication via cookies@dtbuchholz , please tell me if this is wildly incorrect.