Skip to main content
The API uses standard HTTP status codes and returns error messages in a consistent format. JSON-RPC errors follow the JSON-RPC 2.0 error specification.

Error Response Formats

REST API Errors

All REST API errors follow this structure:
{
  "error": "Error Type",
  "message": "Human-readable error message",
  "details": {}
}

JSON-RPC Errors

JSON-RPC errors follow the JSON-RPC 2.0 specification:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "Server error",
    "data": "Error details"
  }
}

JSON-RPC Error Codes

CodeMeaningDescription
-32600Invalid RequestThe JSON sent is not a valid Request object
-32601Method not foundThe method does not exist / is not available
-32602Invalid paramsInvalid method parameter(s)
-32603Internal errorInternal JSON-RPC error
-32000Server errorGeneric server error

HTTP Status Codes

CodeMeaningDescription
200OKRequest succeeded
400Bad RequestInvalid request parameters or query validation error
401UnauthorizedMissing or invalid API key
404Not FoundResource not found
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error
503Service UnavailableService temporarily unavailable

Error Types

400 Bad Request

Invalid request parameters or validation errors. REST API Example:
{
  "error": "Invalid query",
  "message": "Only SELECT queries are allowed"
}
JSON-RPC Example:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Invalid params",
    "data": "getTransactionsForAddress requires address as first parameter"
  }
}
Common Causes:
  • Invalid SQL query syntax
  • Invalid parameter values
  • Missing required parameters
  • Parameter out of range
  • Invalid JSON-RPC request format

401 Unauthorized

Missing or invalid API key. REST API Example:
{
  "error": "Unauthorized",
  "message": "API key is required. Provide it via x-api-key header or api-key query parameter."
}
JSON-RPC Example:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "Unauthorized",
    "data": "Invalid or inactive API key."
  }
}
Common Causes:
  • Missing API key header
  • Invalid API key
  • Inactive or revoked API key
Solution: Ensure you’re including a valid API key in the x-api-key header or api-key query parameter.

404 Not Found

Resource not found. REST API Example:
{
  "error": "Not Found",
  "message": "Transaction not found"
}
JSON-RPC Example:
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}
Common Causes:
  • Transaction signature doesn’t exist
  • Invalid endpoint
  • Resource was deleted

429 Too Many Requests

Rate limit exceeded. REST API Example:
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded for plan 'free'. Limit: 100 requests/minute, Used: 100. Retry after 60 seconds.",
  "plan": "free",
  "limit": 100,
  "used": 100,
  "retryAfter": 60
}
JSON-RPC Example:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "Too Many Requests",
    "data": "Rate limit exceeded for plan 'free'. Limit: 100 requests/minute, Used: 100. Retry after 60 seconds."
  }
}
Solution: Implement exponential backoff and respect rate limit headers. See Rate Limiting for details.

500 Internal Server Error

Server error. REST API Example:
{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred"
}
JSON-RPC Example:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Internal error",
    "data": "An unexpected error occurred"
  }
}
Solution: Retry the request. If the error persists, contact support.

503 Service Unavailable

Service temporarily unavailable. REST API Example:
{
  "error": "Service Unavailable",
  "message": "Service is temporarily unavailable. Please try again later."
}
JSON-RPC Example:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Internal error",
    "data": "Service is temporarily unavailable"
  }
}
Solution: Retry after a delay. Check service status via /health endpoint.

SQL Query Errors

Invalid Query

{
  "error": "Invalid query",
  "message": "Only SELECT queries are allowed"
}
Status Code: 400 Bad Request

LIMIT Exceeded

{
  "error": "Invalid query",
  "message": "LIMIT value cannot exceed 10,000 rows. Please reduce the limit."
}
Status Code: 400 Bad Request

Query Too Long

{
  "error": "Invalid query",
  "message": "Query is too long. Maximum length is 100,000 characters."
}
Status Code: 400 Bad Request

Error Handling Examples

JavaScript/TypeScript (REST API)

async function handleRequest(url: string, apiKey: string, body: any) {
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify(body)
    });
    
    if (!response.ok) {
      const error = await response.json();
      
      switch (response.status) {
        case 400:
          console.error('Validation error:', error.message);
          break;
        case 401:
          console.error('Authentication error:', error.message);
          break;
        case 404:
          console.error('Resource not found');
          break;
        case 429:
          const retryAfter = error.retryAfter || response.headers.get('Retry-After');
          console.error(`Rate limit exceeded. Retry after ${retryAfter}s`);
          break;
        case 500:
        case 503:
          console.error('Server error. Retrying...');
          // Implement retry logic
          break;
        default:
          console.error('Unexpected error:', error);
      }
      
      throw new Error(error.message);
    }
    
    return await response.json();
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

JavaScript/TypeScript (JSON-RPC)

async function handleRPCRequest(method: string, params: any[], apiKey: string) {
  try {
    const response = await fetch('https://api.solixdb.xyz/v1/rpc', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 1,
        method,
        params
      })
    });
    
    const result = await response.json();
    
    if (result.error) {
      const { code, message, data } = result.error;
      
      switch (code) {
        case -32600:
          console.error('Invalid request:', message);
          break;
        case -32601:
          console.error('Method not found:', method);
          break;
        case -32602:
          console.error('Invalid params:', data);
          break;
        case -32000:
          if (message.includes('Rate limit')) {
            console.error('Rate limit exceeded:', data);
          } else {
            console.error('Server error:', message);
          }
          break;
        default:
          console.error('RPC error:', message);
      }
      
      throw new Error(message);
    }
    
    return result.result;
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

Python (REST API)

import requests
from typing import Dict, Any

def handle_request(url: str, api_key: str, body: Dict[str, Any]) -> Any:
    try:
        response = requests.post(
            url,
            headers={
                'Content-Type': 'application/json',
                'x-api-key': api_key
            },
            json=body
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.HTTPError as e:
        error = response.json()
        
        if response.status_code == 400:
            print('Validation error:', error.get('message'))
        elif response.status_code == 401:
            print('Authentication error:', error.get('message'))
        elif response.status_code == 404:
            print('Resource not found')
        elif response.status_code == 429:
            retry_after = error.get('retryAfter') or response.headers.get('Retry-After')
            print(f'Rate limit exceeded. Retry after {retry_after}s')
        elif response.status_code in [500, 503]:
            print('Server error. Retrying...')
            # Implement retry logic
        
        raise Exception(error.get('message', 'Request failed'))
    except requests.exceptions.RequestException as e:
        print(f'Request failed: {e}')
        raise

Python (JSON-RPC)

import requests
from typing import List, Any, Dict

def handle_rpc_request(method: str, params: List[Any], api_key: str) -> Any:
    try:
        response = requests.post(
            'https://api.solixdb.xyz/v1/rpc',
            headers={
                'Content-Type': 'application/json',
                'x-api-key': api_key
            },
            json={
                'jsonrpc': '2.0',
                'id': 1,
                'method': method,
                'params': params
            }
        )
        result = response.json()
        
        if 'error' in result:
            error = result['error']
            code = error.get('code')
            message = error.get('message')
            data = error.get('data')
            
            if code == -32600:
                print('Invalid request:', message)
            elif code == -32601:
                print('Method not found:', method)
            elif code == -32602:
                print('Invalid params:', data)
            elif code == -32000:
                if 'Rate limit' in message:
                    print('Rate limit exceeded:', data)
                else:
                    print('Server error:', message)
            else:
                print('RPC error:', message)
            
            raise Exception(message)
        
        return result.get('result')
    except requests.exceptions.RequestException as e:
        print(f'Request failed: {e}')
        raise

Retry Logic

Implement retry logic for transient errors (500, 503, 429):

REST API

async function retryRequest(
  url: string,
  apiKey: string,
  body: any,
  maxRetries = 3
): Promise<Response> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': apiKey
        },
        body: JSON.stringify(body)
      });
      
      if (response.status === 429) {
        const error = await response.json();
        const retryAfter = error.retryAfter || response.headers.get('Retry-After');
        const waitTime = retryAfter 
          ? parseInt(retryAfter) * 1000 
          : Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      
      if (response.status >= 500 && response.status < 600) {
        if (i < maxRetries - 1) {
          await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
          continue;
        }
      }
      
      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
  
  throw new Error('Max retries exceeded');
}

JSON-RPC

async function retryRPCRequest(
  method: string,
  params: any[],
  apiKey: string,
  maxRetries = 3
): Promise<any> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://api.solixdb.xyz/v1/rpc', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': apiKey
        },
        body: JSON.stringify({
          jsonrpc: '2.0',
          id: 1,
          method,
          params
        })
      });
      
      const result = await response.json();
      
      if (result.error) {
        const error = result.error;
        
        if (error.message.includes('Rate limit')) {
          const retryAfter = error.data?.match(/Retry after (\d+)/)?.[1] || Math.pow(2, i);
          await new Promise(resolve => setTimeout(resolve, parseInt(retryAfter) * 1000));
          continue;
        }
        
        if (response.status >= 500 && response.status < 600) {
          if (i < maxRetries - 1) {
            await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
            continue;
          }
        }
      }
      
      if (result.error) {
        throw new Error(result.error.message);
      }
      
      return result.result;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
  
  throw new Error('Max retries exceeded');
}

Error Handling Best Practices

Always check for errors in JSON-RPC responses before accessing result data.
Handle specific error codes (-32600, -32601, -32602, -32000) with appropriate actions.
Retry transient errors (500, 503, 429) with exponential backoff.
Log error details for debugging, including error codes and data fields.
Translate technical error messages to user-friendly messages in your UI.
Monitor rate limit headers and implement backoff when approaching limits.
For more information on handling rate limits, see our Rate Limiting guide.
For API method examples, see our JSON-RPC API Reference.