API Endpoints

Complete reference for the Spray and Play REST API. All endpoints, request formats, and response examples.

API Endpoints

> Complete reference for the Spray and Play REST API. All endpoints return JSON responses

> with consistent success/error formats and include rate limit headers.

Base URL

https://app.playtrenches.xyz/api

For local development:

http://localhost:3000/api

---

User Endpoints

Get User Profile

GET /api/user

Returns information about the authenticated user.

Auth: Session cookie required

Response:

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "handle": "@sprayer_username",
    "email": "user@example.com",
    "wallet": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
    "walletEvm": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
    "walletSol": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "balance": 1000.50,
    "beliefScore": 45,
    "boostPoints": 250,
    "referralCode": "ABC123",
    "createdAt": "2026-01-01T00:00:00Z",
    "updatedAt": "2026-02-16T10:30:00Z"
  }
}

TypeScript Example:

interface User {
  id: string;
  handle: string;
  email: string;
  wallet: string;
  walletEvm: string;
  walletSol: string;
  balance: number;
  beliefScore: number;
  boostPoints: number;
  referralCode: string;
  createdAt: string;
  updatedAt: string;
}

const getUser = async (): Promise<User> => {
  const response = await fetch('/api/user', {
    credentials: 'include'
  });
  
  if (!response.ok) {
    throw new Error('Failed to fetch user');
  }
  
  const { data } = await response.json();
  return data;
};

---

Update User Profile

POST /api/user

Update wallet addresses and profile information.

Auth: Session cookie required

Request Body:

{
  "wallet": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
  "walletEvm": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
  "walletSol": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
}

Response:

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "wallet": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
    "walletEvm": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
    "walletSol": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "updatedAt": "2026-02-16T10:35:00Z"
  }
}

---

Get Payout Preference

GET /api/user/payout-preference

Returns the user's current payout preference (balance credit vs wallet payout).

Auth: Session cookie required

Response:

{
  "payoutToBalance": false
}

---

Update Payout Preference

POST /api/user/payout-preference

Toggle whether rewards are credited to balance or sent to withdrawal wallet.

Auth: Session cookie required

Security: CSRF token required

Request Body:

{
  "payoutToBalance": true
}

Response:

{
  "success": true,
  "payoutToBalance": true
}

Behavior:

  • true → Rewards added to platform balance (for re-spraying)
  • false → Rewards sent to withdrawal wallet (default)

---

Get User Positions

GET /api/user/positions

Returns user's active positions across all trenches.

Auth: Session cookie required

Response:

{
  "success": true,
  "data": [
    {
      "id": "pos_123",
      "trenchId": "cuid_rapid_001",
      "trenchName": "Rapid Fire",
      "trenchLevel": "RAPID",
      "status": "ACTIVE",
      "entryAmount": 1000.00,
      "expectedPayout": 2500.00,
      "expectedPayoutAt": "2026-03-03T00:00:00Z",
      "autoBoostEnabled": false,
      "createdAt": "2026-02-01T00:00:00Z",
      "tokens": [
        { "symbol": "BLT", "amount": 333.33, "usdValue": 333.33 },
        { "symbol": "SPRAY", "amount": 333.33, "usdValue": 333.33 },
        { "symbol": "PLAY", "amount": 333.34, "usdValue": 333.34 }
      ]
    }
  ]
}

---

Get User Stats

GET /api/user/stats

Returns user statistics and historical performance.

Auth: Session cookie required

Response:

{
  "success": true,
  "data": {
    "totalSprayed": 15000.00,
    "totalEarned": 2250.00,
    "avgApy": 42.5,
    "totalPositions": 12,
    "activePositions": 3,
    "tasksCompleted": 45,
    "raidsParticipated": 23,
    "referrals": 8,
    "referralEarnings": 120.00
  }
}

---

Trench Endpoints

List All Trenches

GET /api/trenches/v2

Returns all 3 perpetual trenches with full details.

Auth: None (public endpoint)

Rate Limit: 100 req/min

Response:

{
  "success": true,
  "data": {
    "trenches": [
      {
        "level": "RAPID",
        "name": "Rapid Fire",
        "description": "24h cycle, high frequency",
        "totalReserveUsd": 1500000,
        "insuranceBuffer": 150000,
        "minThreshold": 300000,
        "status": "ACTIVE",
        "canSpray": true,
        "riskLevel": "low",
        "riskIndicators": ["🟢"],
        "featuredProjects": [
          { "id": "proj_1", "name": "Token A", "apy": 45.2 }
        ],
        "participantCount": 1250,
        "totalSprayed": 5000000,
        "avgApy": 45.5,
        "duration": "24h",
        "entryRange": "$5 - $1,000",
        "themeColor": "#10b981"
      },
      {
        "level": "MID",
        "name": "Mid Strike",
        "description": "7-day lock for balanced returns",
        "totalReserveUsd": 2500000,
        "insuranceBuffer": 250000,
        "minThreshold": 500000,
        "status": "ACTIVE",
        "canSpray": true,
        "riskLevel": "medium",
        "riskIndicators": ["🟡"],
        "featuredProjects": [
          { "id": "proj_2", "name": "Token B", "apy": 65.8 }
        ],
        "participantCount": 890,
        "totalSprayed": 8000000,
        "avgApy": 62.3,
        "duration": "7d",
        "entryRange": "$100 - $10,000",
        "themeColor": "#f59e0b"
      },
      {
        "level": "DEEP",
        "name": "Deep Vault",
        "description": "30-day lock for maximum yield",
        "totalReserveUsd": 4000000,
        "insuranceBuffer": 400000,
        "minThreshold": 800000,
        "status": "ACTIVE",
        "canSpray": true,
        "riskLevel": "high",
        "riskIndicators": ["🟠"],
        "featuredProjects": [
          { "id": "proj_3", "name": "Token C", "apy": 95.5 }
        ],
        "participantCount": 450,
        "totalSprayed": 12000000,
        "avgApy": 88.7,
        "duration": "30d",
        "entryRange": "$1,000 - $100,000",
        "themeColor": "#ef4444"
      }
    ],
    "platformStats": {
      "totalReserveUsd": 8000000,
      "totalSprayers": 3200,
      "featuredProjectCount": 15,
      "avgPlatformApy": 58.2
    }
  }
}

TypeScript Example:

interface Trench {
  level: 'RAPID' | 'MID' | 'DEEP';
  name: string;
  description: string;
  totalReserveUsd: number;
  insuranceBuffer: number;
  status: 'ACTIVE' | 'PAUSED' | 'EMERGENCY';
  canSpray: boolean;
  riskLevel: string;
  avgApy: number;
  duration: string;
  entryRange: string;
  themeColor: string;
}

const getTrenches = async (): Promise<Trench[]> => {
  const response = await fetch('/api/trenches/v2');
  const { data } = await response.json();
  return data.trenches;
};

---

Get Trench Details

GET /api/trenches/:id

Returns detailed information for a specific trench.

Parameters:

ParameterTypeDescription
idstringTrench UUID

---

Get Trench Queue

GET /api/trenches/:id/queue

Returns trench queue position data and waiting list information.

---

Spray Endpoints

Create Spray

POST /api/spray/v2

Creates a new spray position with 0.5% fee and proportional allocation.

Auth: Session cookie required

Rate Limit: 10 req/min

Request Body:

{
  "trenchId": "cuid_rapid_001",
  "amount": 1000
}

Preview Mode:

{
  "trenchId": "cuid_rapid_001",
  "amount": 1000,
  "action": "preview"
}

Response:

{
  "success": true,
  "data": {
    "sprayId": "spray_abc123",
    "amount": 1000,
    "fee": 5,
    "effectiveAmount": 995,
    "allocation": [
      { "tokenSymbol": "BLT", "amount": 331.67, "usdValue": 331.67 },
      { "tokenSymbol": "SPRAY", "amount": 331.67, "usdValue": 331.67 },
      { "tokenSymbol": "PLAY", "amount": 331.66, "usdValue": 331.66 }
    ],
    "expectedPayout": 1194,
    "payoutDate": "2026-02-17T22:00:00Z",
    "insuranceApplied": false,
    "trench": {
      "level": "RAPID",
      "duration": "24h"
    }
  }
}

TypeScript Example:

interface SprayRequest {
  trenchId: string;
  amount: number;
  action?: 'preview' | 'execute';
}

interface SprayResponse {
  sprayId: string;
  amount: number;
  fee: number;
  effectiveAmount: number;
  allocation: Array<{
    tokenSymbol: string;
    amount: number;
    usdValue: number;
  }>;
  expectedPayout: number;
  payoutDate: string;
}

const createSpray = async (
  trenchId: string, 
  amount: number,
  preview: boolean = false
): Promise<SprayResponse> => {
  const response = await fetch('/api/spray/v2', {
    method: 'POST',
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      trenchId,
      amount,
      action: preview ? 'preview' : 'execute'
    })
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error.message);
  }

  const { data } = await response.json();
  return data;
};

// Preview before spraying
const preview = await createSpray('trench_123', 1000, true);
console.log(`Fee: $${preview.fee}, Expected payout: $${preview.expectedPayout}`);

// Execute spray
const spray = await createSpray('trench_123', 1000);
console.log(`Spray created: ${spray.sprayId}`);

Error Codes:

CodeStatusDescription
TRENCH_INACTIVE400Trench is paused or in emergency mode
MIN_AMOUNT_NOT_MET400Below minimum spray amount ($50)
MAX_AMOUNT_EXCEEDED400Above maximum spray amount for trench
INSUFFICIENT_BALANCE400User balance too low
RATE_LIMITED429Too many spray requests

---

Task Endpoints

List Available Tasks

GET /api/tasks

Returns available tasks that users can complete for boost points.

Auth: Session cookie required

Rate Limit: 30 req/min

Response:

{
  "success": true,
  "data": [
    {
      "id": "task_1",
      "title": "Follow on Twitter",
      "description": "Follow @playtrenches on Twitter",
      "reward": 50,
      "taskType": "ONE_TIME",
      "category": "SOCIAL",
      "link": "https://x.com/spraytrenches",
      "order": 1,
      "isActive": true,
      "maxCompletions": 1,
      "currentCompletions": 0
    },
    {
      "id": "task_2",
      "title": "Join Discord",
      "description": "Join our Discord community",
      "reward": 75,
      "taskType": "ONE_TIME",
      "category": "COMMUNITY",
      "link": "https://discord.gg/MQeZDKZWC9",
      "order": 2,
      "isActive": true
    }
  ]
}

---

Complete Task

POST /api/tasks/v2/:id/complete

Submit task completion with proof.

Auth: Session cookie required

Rate Limit: Tier-based with velocity check

Request Body:

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "proofUrl": "https://twitter.com/user/status/123456789"
}

Response Headers:

HeaderDescription
X-AntiGaming-RiskScore0-100 risk score
X-AntiGaming-FlagsFLAGGED_FOR_REVIEW if suspicious

---

Raid Endpoints

List Active Raids

GET /api/raid-center

Returns active raids that users can participate in.

Auth: Session cookie required

Rate Limit: 10 req/min per IP

Response:

{
  "success": true,
  "data": [
    {
      "id": "raid_1",
      "projectId": "proj_123",
      "projectName": "Token Launch",
      "actionType": "LIKE",
      "platform": "TWITTER",
      "reward": 100,
      "maxParticipants": 500,
      "currentParticipants": 234,
      "deadline": "2026-02-17T00:00:00Z",
      "status": "ACTIVE"
    }
  ]
}

---

Execute Raid

POST /api/raid-center

Execute a raid action.

Auth: Session cookie required

Rate Limit: Tier-based with velocity check

Request Body:

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "raidCenterId": "raid_1",
  "actionType": "LIKE",
  "proofUrl": "https://twitter.com/user/status/123456789"
}

---

Waiting List Endpoints

Join Waiting List

POST /api/waiting-list

Join a project waiting list.

Auth: Session cookie required

Rate Limit: 1 req/min per user

Request Body:

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "waitingListId": "wl_abc123"
}

---

Jump Queue Position

POST /api/waiting-list/jump

Jump queue position using completed tasks.

Auth: Session cookie required

Rate Limit: 1 req/min per user

Request Body:

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "waitingListId": "wl_abc123",
  "taskId": "task_1"
}

---

Secure Spot

POST /api/waiting-list/secure

Secure a spot with deposit verification.

Auth: Session cookie required

Rate Limit: 1 req/min per user

Security: On-chain verification required

Request Body:

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "waitingListId": "wl_abc123",
  "txHash": "5VERq8X7KYP6HQ...",
  "expectedAmount": 10
}

---

Project Onboarding

Submit Application

POST /api/projects/apply

Self-service project onboarding.

Rate Limit: 1 req/min (IP-based)

Request Body:

{
  "name": "My Token Project",
  "tokenSymbol": "MTP",
  "chainId": 1,
  "contractAddress": "0x742d35Cc6634C0532925a3b8D4C9db96590f6C7E",
  "promisedApy": 45.5,
  "initialReserve": 5000,
  "contactEmail": "admin@project.com",
  "website": "https://myproject.com",
  "description": "A revolutionary DeFi protocol"
}

---

Get Onboarding Config

GET /api/projects/apply

Returns supported chains, min/max reserves, and constraints.

Response:

{
  "success": true,
  "data": {
    "supportedChains": [
      { "id": 1, "name": "Ethereum", "currency": "ETH" },
      { "id": 56, "name": "BSC", "currency": "BNB" },
      { "id": 137, "name": "Polygon", "currency": "MATIC" },
      { "id": 8453, "name": "Base", "currency": "ETH" }
    ],
    "minReserve": 5000,
    "maxReserve": 1000000,
    "minApy": 10,
    "maxApy": 200
  }
}

---

System Endpoints

Health Check

GET /api/health

System health check. No authentication required.

Response:

{
  "overall": "healthy",
  "timestamp": "2026-02-16T15:30:00Z",
  "uptime": 302400,
  "version": "abc1234",
  "environment": "production",
  "checks": {
    "database": { 
      "status": "connected", 
      "latency": 15 
    },
    "redis": { 
      "status": "connected", 
      "latency": 45 
    },
    "rpc": { 
      "status": "healthy", 
      "chains": ["ethereum", "solana", "base"] 
    }
  }
}

---

Get Metrics

GET /api/metrics

Performance metrics (requires API key).

Headers: Authorization: Bearer API_KEY

Query Parameters:

ParameterTypeDefaultDescription
windownumber5Time window in minutes
rawbooleanfalseInclude raw data
limitnumber100Limit for raw data

Response:

{
  "success": true,
  "data": {
    "requests": {
      "total": 15420,
      "successful": 15280,
      "failed": 140,
      "avgLatency": 45
    },
    "errors": {
      "rateLimited": 89,
      "unauthorized": 32,
      "serverError": 19
    }
  }
}

---

Real-Time Updates (SSE)

Server-Sent Events

GET /api/sse?userId=USER_ID

Real-time updates stream for live data.

Auth: Session cookie recommended

Event Types:

TypeDescriptionPayload
PRICE_UPDATEToken price updates{ token, price, change24h }
TRENCH_UPDATETrench status changes{ trenchId, status, stats }
PAYOUT_COMPLETEDPayout notifications{ positionId, amount, txHash }
POSITION_UPDATEPosition changes{ positionId, status, value }

JavaScript Example:

const connectToSSE = (userId: string) => {
  const eventSource = new EventSource(`/api/sse?userId=${userId}`);

  eventSource.addEventListener('PRICE_UPDATE', (event) => {
    const data = JSON.parse(event.data);
    updatePriceDisplay(data);
  });

  eventSource.addEventListener('PAYOUT_COMPLETED', (event) => {
    const data = JSON.parse(event.data);
    showNotification(`Payout received: $${data.amount}`);
  });

  eventSource.onerror = (error) => {
    console.error('SSE error:', error);
    eventSource.close();
    // Reconnect after delay
    setTimeout(() => connectToSSE(userId), 5000);
  };

  return () => eventSource.close();
};

---

Error Codes Reference

HTTP Status Codes

CodeDescription
200Success
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
409Conflict (duplicate)
429Rate Limited
500Internal Server Error
503Service Unavailable

Application Error Codes

CodeDescription
TRENCH_INACTIVETrench is paused or emergency mode
MIN_AMOUNT_NOT_METBelow minimum spray amount
MAX_AMOUNT_EXCEEDEDAbove maximum spray amount
INSUFFICIENT_BALANCEUser balance too low
RATE_LIMITEDToo many requests
INVALID_PROOFTask proof validation failed
ALREADY_COMPLETEDTask already completed
WAITING_LIST_FULLNo spots available
DEPOSIT_NOT_FOUNDTransaction not found on-chain
REORG_DETECTEDBlockchain reorg detected
INVALID_SIGNATUREWebhook signature invalid
SESSION_EXPIREDUser session has expired

---

Rate Limits Summary

Public API

EndpointLimit
/api/trenches/*100 req/min
/api/spray/*10 req/min
/api/user/*60 req/min
/api/waiting-list1 req/min
/api/waiting-list/jump1 req/min
/api/waiting-list/secure1 req/min
/api/tasks/*30 req/min
/api/raid-center10 req/min (GET), Tier-based (POST)
/api/deposits/*20 req/min

---

> 📢 Important Note

>

> All payouts are now fully automated. Legacy manual

> claiming endpoints have been removed. Users receive payouts directly to their registered wallets.