REST API reference for Proteus. All data is fetched from blockchain.
/api/chain/
Wallet-based JWT authentication:
- Connect wallet (MetaMask/Coinbase)
- Sign authentication message
- Receive JWT token
- Include in header:
Authorization: Bearer <token>
GET /auth/nonce/{address}Response:
{
"nonce": "abc123...",
"message": "Sign this message to authenticate with Proteus: abc123..."
}POST /auth/verifyBody:
{
"address": "0x123...",
"signature": "0x456...",
"message": "Sign this message..."
}Response:
{
"success": true,
"token": "eyJhbGc...",
"address": "0x123..."
}POST /auth/refresh
Authorization: Bearer <token>Response:
{
"success": true,
"token": "eyJhbGc..."
}POST /auth/logout
Authorization: Bearer <token>Response: 200 OK
POST /api/embedded/request-otpBody:
{
"identifier": "user@example.com",
"auth_method": "email"
}Response:
{
"success": true
}POST /api/embedded/verify-otpBody:
{
"identifier": "user@example.com",
"otp_code": "123456"
}Response:
{
"success": true,
"wallet_address": "0x789..."
}Test Mode: When
FLASK_ENV=testing, OTP code123456is accepted for any email.
GET /api/healthResponse:
{
"status": "healthy",
"service": "proteus-node"
}Integration Tests: All chain endpoints are covered by integration tests in
tests/integration/test_api_chain.py
GET /api/chain/actorsResponse:
{
"actors": [
{
"id": 1,
"name": "Elon Musk",
"handle": "@elonmusk",
"verified": true,
"market_count": 15
}
],
"source": "blockchain",
"total": 1
}GET /api/chain/marketsQuery Parameters:
| Param | Type | Description |
|---|---|---|
| status | string | "active", "resolved", or "all" |
| actor_id | int | Filter by actor |
| limit | int | Max results (default: 100) |
Response:
{
"markets": [
{
"id": 1,
"actor_id": 1,
"description": "Will say 'Mars' in next tweet",
"end_time": 1735689600,
"total_pool": "1000000000000000000",
"status": "active",
"submission_count": 5,
"bet_count": 23
}
],
"source": "blockchain",
"total": 1
}GET /api/chain/markets/<market_id>Response:
{
"market": {
"id": 1,
"actor": {
"name": "Elon Musk",
"handle": "@elonmusk"
},
"submissions": [
{
"id": 1,
"predicted_text": "Mars is the future",
"submitter": "0x123...",
"stake": "100000000000000000",
"odds": 3.5
}
],
"bets": [
{
"submission_id": 1,
"bettor": "0x456...",
"amount": "50000000000000000"
}
]
},
"source": "blockchain"
}GET /api/chain/statsResponse:
{
"stats": {
"total_markets": 150,
"active_markets": 45,
"total_volume": "15000000000000000000000",
"total_users": 1234,
"genesis_holders": 60,
"chain": "base-sepolia"
},
"source": "blockchain"
}GET /api/chain/genesisResponse:
{
"genesis": {
"total_supply": 100,
"minted": 60,
"holders": [
{
"address": "0x789...",
"token_ids": [1, 5, 12],
"count": 3
}
],
"payout_percentage": 1.4
},
"source": "blockchain"
}GET /api/chain/oracle/<market_id>Response:
{
"oracle": {
"market_id": 1,
"submissions": [
{
"oracle": "0xABC...",
"actual_text": "Mars is definitely the future",
"verified": true
}
],
"consensus_text": "Mars is definitely the future",
"consensus_reached": true
},
"source": "blockchain"
}Endpoints for managing PredictionMarketV2 market resolution. Requires admin authentication.
Dashboard: Web UI available at
/proteus/admin/resolution
GET /api/admin/resolution-statsResponse:
{
"total_markets": 10,
"resolved_markets": 5,
"pending_resolution": 3,
"active_markets": 2,
"total_pool": "15.5",
"pending_platform_fees": "0.75",
"owner_address": "0x21a85AD98641827BFd89F4d5bC2fEB72F98aaecA",
"owner_key_configured": true,
"xcom_api_configured": false
}GET /api/admin/pending-marketsResponse:
{
"pending_markets": [
{
"id": 1,
"actor_handle": "elonmusk",
"end_time": 1733270400,
"end_time_formatted": "2024-12-03 18:00",
"total_pool": "2.5",
"submission_count": 3,
"can_resolve": true
}
]
}GET /api/admin/market/<market_id>/detailsResponse:
{
"market": {
"id": 1,
"actor_handle": "elonmusk",
"end_time": 1733270400,
"total_pool": "2.5",
"resolved": false,
"submissions": [
{
"id": 1,
"submitter": "0x123...",
"predicted_text": "Mars is the future!",
"amount": "1.0"
}
],
"can_resolve": true
}
}POST /api/admin/resolve-market/<market_id>Body:
{
"actual_text": "The actual tweet text that was posted",
"tweet_url": "https://x.com/user/status/123456789"
}Response (Success):
{
"success": true,
"tx_hash": "0xabc123...",
"gas_used": 1500000,
"market_id": 1
}Response (Error):
{
"success": false,
"error": "Market has not ended yet",
"market_id": 1
}POST /api/admin/auto-resolve-market/<market_id>Body:
{
"tweet_url": "https://x.com/user/status/123456789"
}Note: Requires
X_BEARER_TOKENenvironment variable for X.com API access. X now offers pay-per-use API pricing -- credit-based billing, no subscriptions or monthly caps. Generate a bearer token at the X Developer Portal.
Response:
{
"success": true,
"tx_hash": "0xabc123...",
"tweet_text": "The fetched tweet text",
"market_id": 1
}POST /api/admin/withdraw-feesResponse (Success):
{
"success": true,
"tx_hash": "0xdef456...",
"amount": "0.75"
}Response (No Fees):
{
"success": false,
"error": "No fees to withdraw"
}All API endpoints return standardized error responses:
Error Response Format:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human readable error message",
"details": {}
}
}Success Response Format:
{
"success": true,
"data": {},
"message": "Optional success message"
}| Code | HTTP Status | Description |
|---|---|---|
VALIDATION_ERROR |
400 | Invalid input data or missing required fields |
INVALID_REQUEST |
400 | Malformed request |
UNAUTHORIZED |
401 | Invalid or missing authentication |
INVALID_TOKEN |
401 | JWT token is invalid |
TOKEN_EXPIRED |
401 | JWT token or OTP has expired |
INVALID_SIGNATURE |
401 | Wallet signature verification failed |
FORBIDDEN |
403 | Permission denied |
NOT_FOUND |
404 | Resource not found |
RATE_LIMITED |
429 | Too many requests |
INTERNAL_ERROR |
500 | Unexpected server error |
BLOCKCHAIN_ERROR |
500 | RPC or chain interaction failed |
CONTRACT_ERROR |
500 | Smart contract call failed |
WALLET_ERROR |
500 | Wallet operation failed |
SERVICE_UNAVAILABLE |
503 | Service temporarily unavailable |
| Code | Description |
|---|---|
MARKET_NOT_FOUND |
Market does not exist |
MARKET_ENDED |
Market has already ended |
MARKET_NOT_ENDED |
Market has not ended yet |
MARKET_RESOLVED |
Market is already resolved |
INSUFFICIENT_FUNDS |
Not enough ETH for operation |
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "actual_text is required (or provide tweet_url)",
"details": {
"field": "actual_text"
}
}
}| User Type | Limit |
|---|---|
| Default | 100 req/min |
| Genesis Holder | 500 req/min |
Responses are cached in Redis:
| Data | TTL |
|---|---|
| Actors | 5 min |
| Markets | 30 sec |
| Stats | 10 sec |
| Genesis | 1 min |
| Contract | Address | Status |
|---|---|---|
| PredictionMarketV2 | 0x5174Da96BCA87c78591038DEe9DB1811288c9286 |
Recommended |
| PredictionMarket (V1) | 0x667121e8f22570F2c521454D93D6A87e44488d93 |
Deprecated |
| GenesisNFT | 0x1A5D4475881B93e876251303757E60E524286A24 |
Active |
| EnhancedPredictionMarket | 0x6b67cb0daaf78f63bd11195df0fd9ffe4361b93c |
Requires governance |
| ActorRegistry | 0xC71CC19C5573C5E1E144829800cD0005D0eDB723 |
Active |
| NodeRegistry | 0xA69C842F335dfE1F69288a70054A34018282218d |
Active |
| PayoutManager | 0x88d399C949Ff2f1aaa8eA5a859Ae4d97c74f6871 |
Active |
| DecentralizedOracle | 0x7EF22e27D44E3f4Cc2f133BB4ab2065D180be3C1 |
Active |
Note: Use PredictionMarketV2 for all new development. It has complete market lifecycle with on-chain resolution.
Not yet deployed.