API Reference
Base URL: https://api.degensquest.xyz/api/v1
All responses are JSON. Authenticated endpoints require Authorization: Bearer <accessToken>.
Authentication
POST /auth/telegram
Authenticate using Telegram Mini App initData. Called from inside the Telegram Mini App on load.
Request:
{
"initData": "<telegram_web_app_init_data string>"
}Response 200 OK:
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900,
"user": {
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXY",
"handle": "degen_king",
"displayName": "Degen King",
"level": 12,
"xp": 58200,
"guild": {
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXZ",
"name": "Moon Guild",
"slug": "moon-guild",
"tier": "GOLD"
},
"walletAddress": "0x1234...abcd",
"avatarUrl": "https://cdn.degensquest.xyz/avatars/01HZ...XY.png"
}
}The refreshToken is set as an httpOnly cookie (dq_refresh).
POST /auth/wallet/nonce
Get a nonce for SIWE authentication. The nonce expires in 5 minutes.
Request: (no body)
Response 200 OK:
{
"nonce": "a1b2c3d4e5f6g7h8i9j0",
"expiresAt": "2024-01-01T00:05:00.000Z"
}POST /auth/wallet/verify
Verify a SIWE signature and authenticate.
Request:
{
"message": "app.degensquest.xyz wants you to sign in with your Ethereum account:\n0x1234...abcd\n\nSign in to DegensQuest...\n\nNonce: a1b2c3d4e5f6g7h8i9j0\nIssued At: 2024-01-01T00:00:00Z\nExpiration Time: 2024-01-01T00:05:00Z",
"signature": "0xabc123...def456",
"address": "0x1234...abcd"
}Response 200 OK: Same as /auth/telegram.
POST /auth/refresh
Refresh the access token using the httpOnly refresh cookie.
Request: (no body — cookie sent automatically)
Response 200 OK:
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900
}POST /auth/logout
Invalidate the current session and clear the refresh cookie.
Request: (no body)
Response 204 No Content
Users
GET /users/me (auth required)
Returns the authenticated user’s full profile.
Response 200 OK:
{
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXY",
"handle": "degen_king",
"displayName": "Degen King",
"bio": "Here for the gains and the raids",
"level": 12,
"xp": 58200,
"xpToNextLevel": 5800,
"guild": {
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXZ",
"name": "Moon Guild",
"slug": "moon-guild",
"tier": "GOLD"
},
"walletAddresses": ["0x1234...abcd"],
"avatarUrl": "https://cdn.degensquest.xyz/avatars/01HZ...XY.png",
"titles": ["Trivia Master", "Raid MVP"],
"activeTitleIndex": 0,
"battlePass": {
"season": 1,
"tier": 47,
"isPremium": true,
"xp": 234500
},
"stats": {
"gamesPlayed": 312,
"gamesWon": 148,
"winRate": 0.474,
"totalXpEarned": 580000
},
"createdAt": "2024-01-01T00:00:00.000Z"
}GET /users/:handle
Public profile for a given handle.
Response 200 OK:
{
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXY",
"handle": "degen_king",
"displayName": "Degen King",
"level": 12,
"guild": {
"name": "Moon Guild",
"tier": "GOLD"
},
"titles": ["Trivia Master"],
"activeTitle": "Trivia Master",
"achievementCount": 34,
"avatarUrl": "https://cdn.degensquest.xyz/avatars/01HZ...XY.png"
}GET /users/:handle/stats
Extended gameplay statistics for a public profile.
Response 200 OK:
{
"handle": "degen_king",
"gamesPlayed": 312,
"gamesWon": 148,
"winRate": 0.474,
"totalXpEarned": 580000,
"byGame": {
"TRIVIA": { "played": 120, "won": 65, "avgScore": 4230 },
"MAFIA": { "played": 58, "won": 28, "roles": { "MAFIA": 14, "CITIZEN": 30, "DETECTIVE": 8, "DOCTOR": 6 } },
"PREDICTION": { "participated": 88, "correct": 51, "accuracy": 0.58 },
"RAID": { "participated": 34, "topDamage": 12, "totalDamage": 1240000 },
"REACTION": { "played": 12, "won": 4, "avgReactionMs": 412, "personalBestMs": 289 }
},
"achievementCount": 34,
"xpHistory": [
{ "date": "2024-01-01", "xp": 12400 },
{ "date": "2024-01-02", "xp": 8700 }
]
}Guilds
GET /guilds
Paginated list of guilds.
Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
tier | string | — | Filter by tier: BRONZE, SILVER, GOLD, DIAMOND, LEGENDARY |
search | string | — | Search by guild name |
sort | string | xp | Sort by: xp, members, created |
Response 200 OK:
{
"data": [
{
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXZ",
"name": "Moon Guild",
"slug": "moon-guild",
"tier": "GOLD",
"memberCount": 47,
"totalXp": 2840000,
"seasonRank": 3,
"avatarUrl": "https://cdn.degensquest.xyz/guilds/moon-guild.png"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 842,
"totalPages": 43
}
}GET /guilds/:slug
Full guild details.
Response 200 OK:
{
"id": "01HZ3K9M2N4P5Q6R7S8T9UVWXZ",
"name": "Moon Guild",
"slug": "moon-guild",
"description": "We play to win. Join us.",
"tier": "GOLD",
"tierMultiplier": 1.5,
"memberCount": 47,
"memberLimit": 100,
"totalXp": 2840000,
"seasonRank": 3,
"leader": { "handle": "degen_king", "displayName": "Degen King" },
"telegramGroupId": "-1001234567890",
"createdAt": "2024-01-01T00:00:00.000Z"
}Economy
GET /economy/balance (auth required)
Current $DEGEN and QUEST balance for the authenticated user.
Response 200 OK:
{
"degen": "15000",
"qbot": "0.5",
"qbotWeiEquivalent": "500000000000000000",
"walletAddress": "0x1234...abcd"
}qbot is the human-readable QUEST balance at 18 decimals. qbotWeiEquivalent is the raw uint256 value.
GET /economy/degen-ledger (auth required)
Paginated $DEGEN transaction history.
Query parameters: page, limit (max 100), type (CREDIT or DEBIT)
Response 200 OK:
{
"data": [
{
"id": "01HZ...",
"amount": "500",
"type": "CREDIT",
"reason": "QUEST_COMPLETE",
"referenceId": "quest_01HZ...",
"balance": "15000",
"createdAt": "2024-01-01T12:00:00.000Z"
}
],
"meta": { "page": 1, "limit": 20, "total": 234, "totalPages": 12 }
}Quests
GET /quests
List all currently active quests.
Query parameters: type (DAILY, WEEKLY, SEASON), game (TRIVIA, MAFIA, PREDICTION, RAID, REACTION, ALL)
Response 200 OK:
{
"data": [
{
"id": "quest_01HZ...",
"title": "Trivia Champion",
"description": "Win 3 Trivia Quest games today",
"type": "DAILY",
"game": "TRIVIA",
"reward": { "xp": 1500, "degen": "300" },
"requirement": { "metric": "WINS", "target": 3 },
"expiresAt": "2024-01-02T00:00:00.000Z"
}
]
}GET /quests/progress (auth required)
User’s progress on all active quests.
Response 200 OK:
{
"data": [
{
"questId": "quest_01HZ...",
"title": "Trivia Champion",
"progress": 2,
"target": 3,
"percentComplete": 66.7,
"completed": false,
"claimed": false
}
]
}Leaderboards
GET /leaderboards
Query parameters:
| Param | Type | Options | Default |
|---|---|---|---|
scope | string | GLOBAL, GUILD, GAME | GLOBAL |
period | string | DAILY, WEEKLY, SEASON, ALLTIME | SEASON |
game | string | TRIVIA, MAFIA, PREDICTION, RAID, REACTION | — (required if scope=GAME) |
guildSlug | string | — | — (required if scope=GUILD) |
limit | integer | 1–100 | 50 |
Response 200 OK:
{
"scope": "GLOBAL",
"period": "SEASON",
"season": 1,
"data": [
{
"rank": 1,
"user": {
"handle": "degen_king",
"displayName": "Degen King",
"level": 12,
"guild": { "name": "Moon Guild", "tier": "GOLD" },
"avatarUrl": "https://cdn.degensquest.xyz/avatars/..."
},
"score": 840000,
"gamesPlayed": 312
}
],
"userRank": {
"rank": 47,
"score": 234500
}
}userRank is only present when the request is authenticated.
Error Codes
All errors follow this format:
{
"statusCode": 400,
"error": "Bad Request",
"message": "initData is missing or invalid",
"code": "AUTH_INVALID_INIT_DATA"
}| HTTP Status | Error | Common Causes |
|---|---|---|
400 Bad Request | Bad Request | Missing required fields, invalid format, invalid query params |
401 Unauthorized | Unauthorized | Missing, expired, or invalid access token |
403 Forbidden | Forbidden | Valid token but insufficient permissions (e.g., non-admin hitting admin route) |
404 Not Found | Not Found | Resource does not exist (user handle, guild slug, quest ID, etc.) |
409 Conflict | Conflict | Duplicate resource creation (e.g., handle already taken) |
422 Unprocessable Entity | Unprocessable Entity | Validation failed (e.g., bet below minimum, invalid prediction end date) |
429 Too Many Requests | Too Many Requests | Rate limit exceeded — back off and retry after Retry-After header |
500 Internal Server Error | Internal Server Error | Unexpected server error — report to developers@degensquest.xyz |
Rate limit headers (included on every response):
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1704067260
Retry-After: 45 (only on 429 responses)