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

Error Response Formats

REST API Errors

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

GraphQL Errors

GraphQL errors follow the standard GraphQL error format:
{
  "errors": [
    {
      "message": "Error message",
      "extensions": {
        "code": "ERROR_CODE",
        "field": "fieldName",
        "details": {}
      },
      "path": ["queryName", "fieldName"]
    }
  ],
  "data": null
}

HTTP Status Codes

CodeMeaningDescription
200OKRequest succeeded
400Bad RequestInvalid request parameters or GraphQL validation error
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": "Validation error",
  "details": [
    {
      "path": ["date_from"],
      "message": "Invalid date format. Expected YYYY-MM-DD"
    }
  ]
}
GraphQL Example:
{
  "errors": [
    {
      "message": "Invalid date format. Expected YYYY-MM-DD",
      "extensions": {
        "code": "VALIDATION_ERROR",
        "field": "filters.dateRange.start"
      },
      "path": ["transactions"]
    }
  ],
  "data": null
}
Common Causes:
  • Invalid date format
  • Invalid parameter values
  • Missing required parameters
  • Parameter out of range
  • Invalid GraphQL query syntax

404 Not Found

Resource not found. REST API Example:
{
  "error": "Not Found",
  "message": "Transaction not found"
}
GraphQL Example:
{
  "errors": [
    {
      "message": "Transaction not found",
      "extensions": {
        "code": "NOT_FOUND"
      },
      "path": ["signature"]
    }
  ],
  "data": {
    "signature": 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. Complexity budget exhausted."
}
GraphQL Example:
{
  "errors": [
    {
      "message": "Rate limit exceeded",
      "extensions": {
        "code": "RATE_LIMIT_EXCEEDED",
        "retryAfter": 5,
        "complexity": 1200,
        "limit": 1000
      }
    }
  ],
  "data": null
}
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"
}
GraphQL Example:
{
  "errors": [
    {
      "message": "An unexpected error occurred",
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR"
      }
    }
  ],
  "data": null
}
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."
}
GraphQL Example:
{
  "errors": [
    {
      "message": "Service is temporarily unavailable",
      "extensions": {
        "code": "SERVICE_UNAVAILABLE"
      }
    }
  ],
  "data": null
}
Solution: Retry after a delay. Check service status.

GraphQL-Specific Error Codes

COMPLEXITY_EXCEEDED

Query complexity exceeds the maximum allowed (1000).
{
  "errors": [
    {
      "message": "Query complexity exceeds limit",
      "extensions": {
        "code": "COMPLEXITY_EXCEEDED",
        "complexity": 1200,
        "limit": 1000,
        "recommendations": [
          "Add date range filter to reduce estimated rows",
          "Reduce group by dimensions",
          "Use pagination for large result sets"
        ]
      }
    }
  ],
  "data": null
}
Solution: Use queryComplexity query to check before execution. Optimize query by adding filters, reducing group by dimensions, or using pagination.

PAGINATION_REQUIRED

Query returns more than 10k rows without pagination.
{
  "errors": [
    {
      "message": "Pagination required for queries returning >10k rows",
      "extensions": {
        "code": "PAGINATION_REQUIRED",
        "estimatedRows": 50000
      }
    }
  ],
  "data": null
}
Solution: Add pagination: { first: 1000 } to your query.

INVALID_FILTER

Invalid filter value or combination.
{
  "errors": [
    {
      "message": "Invalid filter: dateRange.end must be after dateRange.start",
      "extensions": {
        "code": "INVALID_FILTER",
        "field": "filters.dateRange"
      }
    }
  ],
  "data": null
}
Solution: Check filter values and ensure they’re valid.

VALIDATION_ERROR

Input validation failed.
{
  "errors": [
    {
      "message": "Invalid Signature format",
      "extensions": {
        "code": "VALIDATION_ERROR",
        "field": "signature"
      }
    }
  ],
  "data": null
}
Solution: Ensure input values match expected formats (see GraphQL API Reference).

Error Handling Examples

JavaScript/TypeScript (REST API)

async function handleRequest(url: string, options: RequestInit) {
  try {
    const response = await fetch(url, options);
    
    if (!response.ok) {
      const error = await response.json();
      
      switch (response.status) {
        case 400:
          console.error('Validation error:', error.details);
          break;
        case 404:
          console.error('Resource not found');
          break;
        case 429:
          const resetTime = response.headers.get('X-RateLimit-Reset');
          console.error('Rate limit exceeded. Reset at:', resetTime);
          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 (GraphQL)

async function handleGraphQLRequest(query: string, variables?: any) {
  try {
    const response = await fetch('https://api.solixdb.xyz/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query, variables }),
    });
    
    const result = await response.json();
    
    if (result.errors) {
      for (const error of result.errors) {
        const code = error.extensions?.code;
        
        switch (code) {
          case 'COMPLEXITY_EXCEEDED':
            console.error('Query too complex:', error.extensions.recommendations);
            break;
          case 'PAGINATION_REQUIRED':
            console.error('Pagination required for large result sets');
            break;
          case 'RATE_LIMIT_EXCEEDED':
            const retryAfter = error.extensions.retryAfter;
            console.error(`Rate limited. Retry after ${retryAfter}s`);
            break;
          case 'VALIDATION_ERROR':
            console.error('Validation error:', error.extensions.field);
            break;
          default:
            console.error('GraphQL error:', error.message);
        }
      }
      
      throw new Error(result.errors[0].message);
    }
    
    return result.data;
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

Python (REST API)

import requests
from typing import Dict, Any

def handle_request(url: str, headers: Dict[str, str]) -> Any:
    try:
        response = requests.get(url, headers=headers)
        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('details'))
        elif response.status_code == 404:
            print('Resource not found')
        elif response.status_code == 429:
            reset_time = response.headers.get('X-RateLimit-Reset')
            print(f'Rate limit exceeded. Reset at: {reset_time}')
        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 (GraphQL)

import requests
from typing import Dict, Any, Optional

def handle_graphql_request(query: str, variables: Optional[Dict] = None) -> Any:
    try:
        response = requests.post(
            'https://api.solixdb.xyz/graphql',
            json={'query': query, 'variables': variables or {}}
        )
        result = response.json()
        
        if 'errors' in result:
            for error in result['errors']:
                code = error.get('extensions', {}).get('code')
                
                if code == 'COMPLEXITY_EXCEEDED':
                    print('Query too complex:', error['extensions'].get('recommendations'))
                elif code == 'PAGINATION_REQUIRED':
                    print('Pagination required for large result sets')
                elif code == 'RATE_LIMIT_EXCEEDED':
                    retry_after = error['extensions'].get('retryAfter')
                    print(f'Rate limited. Retry after {retry_after}s')
                elif code == 'VALIDATION_ERROR':
                    print('Validation error:', error['extensions'].get('field'))
                else:
                    print('GraphQL error:', error['message'])
            
            raise Exception(result['errors'][0]['message'])
        
        return result.get('data')
    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,
  options: RequestInit,
  maxRetries = 3
): Promise<Response> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        const resetTime = response.headers.get('X-RateLimit-Reset');
        const waitTime = 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');
}

GraphQL

async function retryGraphQLRequest(
  query: string,
  variables?: any,
  maxRetries = 3
): Promise<any> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://api.solixdb.xyz/graphql', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ query, variables }),
      });
      
      const result = await response.json();
      
      if (result.errors) {
        const error = result.errors[0];
        const code = error.extensions?.code;
        
        if (code === 'RATE_LIMIT_EXCEEDED') {
          const retryAfter = error.extensions.retryAfter || Math.pow(2, i);
          await new Promise(resolve => setTimeout(resolve, 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.errors) {
        throw new Error(result.errors[0].message);
      }
      
      return result.data;
    } 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 GraphQL responses before accessing data.
Handle specific error codes (COMPLEXITY_EXCEEDED, PAGINATION_REQUIRED) with appropriate actions.
Retry transient errors (500, 503, 429) with exponential backoff.
Log error details for debugging, including error codes and extensions.
Translate technical error messages to user-friendly messages in your UI.
For more information on handling rate limits, see our Rate Limiting guide.
For GraphQL query examples, see our GraphQL API Reference.