Skip to main content

Error Response Format

All API errors follow a consistent JSON format:
{
  "error": "Error message describing what went wrong"
}
The HTTP status code indicates the error category, and the error message provides specific details.

HTTP Status Codes

Success Codes

200
OK
Request successful, data returned

Client Error Codes

400
Bad Request
The request was malformed or contains invalid parametersCommon causes:
  • Missing required query parameters
  • Invalid ticker_id format
  • Malformed request body
404
Not Found
The requested resource does not existCommon causes:
  • Invalid endpoint path
  • Ticker not found
  • DAO does not exist
429
Too Many Requests
Rate limit exceededDetails:
  • Limit: 60 requests per minute per IP
  • Reset: Wait until the next minute window

Server Error Codes

500
Internal Server Error
An unexpected error occurred on the serverCommon causes:
  • RPC connection issues
  • Blockchain data unavailable
  • Service temporarily down
502
Bad Gateway
Upstream service (RPC) is unavailable
503
Service Unavailable
API is temporarily unavailable (maintenance or overload)

Common Error Scenarios

Rate Limit Exceeded

When you exceed 60 requests per minute:
{
  "error": "Rate limit exceeded. Please try again later."
}
Solution:
1

Implement Retry Logic

Wait 60 seconds before retrying
2

Use Exponential Backoff

Gradually increase wait time between retries
3

Cache Responses

Store frequently accessed data locally
Example Implementation:
async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url);
      
      if (response.status === 429) {
        const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
        console.log(`Rate limited. Waiting ${waitTime}ms...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${await response.text()}`);
      }
      
      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}

// Usage
const tickers = await fetchWithRetry('https://your-api-domain.com/api/tickers');

Ticker Not Found

When requesting a specific ticker that doesn’t exist:
{
  "error": "Ticker not found: INVALID_MINT_ADDRESS"
}
Solutions:
  • Verify the ticker_id format: {BASE_MINT}_{QUOTE_MINT}
  • Ensure both mint addresses are valid Solana PublicKeys
  • Check if the DAO is excluded via EXCLUDED_DAOS
  • Verify the DAO has active pools with reserves

RPC Connection Issues

When the Solana RPC is unavailable:
{
  "error": "Failed to fetch DAO data from blockchain"
}
Solutions:

Check RPC Status

Verify your RPC provider is operational

Use Fallback RPC

Configure multiple RPC endpoints

Upgrade RPC Tier

Use a premium RPC provider

Retry Request

Implement automatic retry logic

Invalid Configuration

When required environment variables are missing:
{
  "error": "FACTORY_ADDRESS not configured"
}
Solution: Ensure all required environment variables are set in your .env file:
FACTORY_ADDRESS=YOUR_FACTORY_PROGRAM_ID
ROUTER_ADDRESS=YOUR_ROUTER_PROGRAM_ID

Error Handling Best Practices

Never assume requests will succeed. Wrap all API calls in try-catch blocks.
try {
  const data = await fetch('/api/tickers').then(r => r.json());
} catch (error) {
  console.error('API request failed:', error);
  // Handle error appropriately
}
Set reasonable timeouts to prevent hanging requests.
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000); // 10s timeout

try {
  const response = await fetch('/api/tickers', { 
    signal: controller.signal 
  });
  clearTimeout(timeout);
} catch (error) {
  if (error.name === 'AbortError') {
    console.error('Request timed out');
  }
}
Implement exponential backoff for transient errors.See code examples above for implementation details.
Cache successful responses to reduce API load and improve resilience.
const cache = new Map();
const CACHE_TTL = 10000; // 10 seconds

async function getCached(url) {
  const cached = cache.get(url);
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }
  
  const data = await fetch(url).then(r => r.json());
  cache.set(url, { data, timestamp: Date.now() });
  return data;
}
Log all errors for debugging and monitoring.
async function fetchAPI(url) {
  try {
    return await fetch(url).then(r => r.json());
  } catch (error) {
    console.error({
      timestamp: new Date().toISOString(),
      url,
      error: error.message,
      stack: error.stack
    });
    throw error;
  }
}

Monitoring API Health

Use the health check endpoint to monitor API status:
curl https://your-api-domain.com/health
Healthy Response:
{
  "status": "healthy",
  "timestamp": "2024-01-01T00:00:00.000Z",
  "uptime": 3600.5
}
Set up automated health checks every 1-5 minutes to detect issues early.

Getting Support

If you encounter persistent errors:

Error Response Examples

{
  "error": "Invalid ticker_id format. Expected: BASE_MINT_QUOTE_MINT"
}