Error Handling
Understanding how to handle errors properly is crucial for building robust applications with the Turnpike API.
Error Response Format
All errors follow a consistent JSON structure:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": {
"additionalInfo": "contextual information"
}
},
"timestamp": 1697234567890
}HTTP Status Codes
400
Bad Request
Invalid parameters, malformed JSON
401
Unauthorized
Missing or invalid API key
403
Forbidden
Insufficient permissions
404
Not Found
Resource doesn't exist
429
Too Many Requests
Rate limit exceeded
500
Internal Server Error
Server-side issue
503
Service Unavailable
Temporary service disruption
Common Error Codes
Authentication Errors
UNAUTHORIZED
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}Solution: Verify your API key is correct and included in the Authorization header.
FORBIDDEN
{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Insufficient permissions for this resource"
}
}Solution: Upgrade your plan to access this endpoint.
Validation Errors
INVALID_PARAMETERS
{
"success": false,
"error": {
"code": "INVALID_PARAMETERS",
"message": "Invalid request parameters",
"details": {
"amount": "Must be between 0.001 and 100"
}
}
}Solution: Check the details object for specific parameter issues.
INVALID_PUBLIC_KEY
{
"success": false,
"error": {
"code": "INVALID_PUBLIC_KEY",
"message": "Public key is not a valid Solana address"
}
}Solution: Ensure you're providing a valid base58-encoded Solana public key.
INVALID_MINT
{
"success": false,
"error": {
"code": "INVALID_MINT",
"message": "Token mint address does not exist or is invalid"
}
}Solution: Verify the token mint address is correct and the token exists.
Trading Errors
INSUFFICIENT_BALANCE
{
"success": false,
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Insufficient SOL balance for transaction",
"details": {
"required": 0.01,
"available": 0.005,
"includesFees": true
}
}
}Solution: Ensure your wallet has enough SOL to cover the transaction amount plus fees.
SLIPPAGE_EXCEEDED
{
"success": false,
"error": {
"code": "SLIPPAGE_EXCEEDED",
"message": "Price moved beyond acceptable slippage",
"details": {
"requestedSlippage": 10,
"actualSlippage": 15.2,
"expectedPrice": 0.00001,
"currentPrice": 0.0000115
}
}
}Solution: Increase slippage tolerance or retry the transaction when market is less volatile.
INSUFFICIENT_LIQUIDITY
{
"success": false,
"error": {
"code": "INSUFFICIENT_LIQUIDITY",
"message": "Not enough liquidity to execute this trade",
"details": {
"requestedAmount": 100,
"availableLiquidity": 50
}
}
}Solution: Reduce trade size or wait for liquidity to improve.
Rate Limiting
RATE_LIMIT_EXCEEDED
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after 30 seconds.",
"retryAfter": 30
}
}Solution: Implement exponential backoff and respect the retryAfter value.
Network Errors
NETWORK_ERROR
{
"success": false,
"error": {
"code": "NETWORK_ERROR",
"message": "Failed to connect to Solana network",
"details": {
"rpcEndpoint": "https://...",
"retryable": true
}
}
}Solution: Retry the request. If the issue persists, check the status page.
TRANSACTION_FAILED
{
"success": false,
"error": {
"code": "TRANSACTION_FAILED",
"message": "Transaction simulation failed",
"details": {
"logs": ["Program log: Error: ...", "..."],
"retryable": false
}
}
}Solution: Review the logs for specific failure reasons. May require parameter adjustments.
Implementing Error Handling
JavaScript/TypeScript Example
async function executeTrade(params) {
try {
const response = await fetch('https://api.turnpike.dev/trade/buy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.TURNPIKE_API_KEY}`
},
body: JSON.stringify(params)
});
const data = await response.json();
if (!response.ok) {
throw new APIError(data.error, response.status);
}
return data;
} catch (error) {
if (error instanceof APIError) {
switch (error.code) {
case 'INSUFFICIENT_BALANCE':
console.error('Not enough SOL:', error.details);
break;
case 'SLIPPAGE_EXCEEDED':
console.warn('Slippage too high, retrying with higher tolerance...');
return executeTrade({ ...params, slippage: params.slippage * 1.5 });
case 'RATE_LIMIT_EXCEEDED':
console.log('Rate limited, waiting...');
await new Promise(resolve => setTimeout(resolve, error.retryAfter * 1000));
return executeTrade(params);
default:
console.error('API Error:', error);
}
} else {
console.error('Network error:', error);
}
throw error;
}
}
class APIError extends Error {
constructor(error, status) {
super(error.message);
this.code = error.code;
this.details = error.details;
this.status = status;
this.retryAfter = error.retryAfter;
}
}Python Example
import requests
import time
from typing import Dict, Any
class TurnpikeAPIError(Exception):
def __init__(self, error_data: Dict[str, Any], status_code: int):
self.code = error_data.get('code')
self.message = error_data.get('message')
self.details = error_data.get('details', {})
self.status_code = status_code
self.retry_after = error_data.get('retryAfter', 0)
super().__init__(self.message)
def execute_trade(params: Dict[str, Any], max_retries: int = 3):
for attempt in range(max_retries):
try:
response = requests.post(
'https://api.turnpike.dev/trade/buy',
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {os.getenv("TURNPIKE_API_KEY")}'
},
json=params
)
data = response.json()
if not response.ok:
raise TurnpikeAPIError(data['error'], response.status_code)
return data
except TurnpikeAPIError as e:
if e.code == 'RATE_LIMIT_EXCEEDED':
time.sleep(e.retry_after)
continue
elif e.code == 'SLIPPAGE_EXCEEDED' and attempt < max_retries - 1:
params['slippage'] *= 1.5
continue
else:
raise
except requests.RequestException as e:
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
raise
raise Exception(f'Failed after {max_retries} attempts')Best Practices
Always Check Response Status: Don't assume requests succeeded
Handle Rate Limits Gracefully: Implement exponential backoff
Log Errors: Keep detailed logs for debugging
Retry Transient Errors: Network issues and rate limits are retryable
Don't Retry Non-Retryable Errors: Invalid parameters won't succeed on retry
Monitor Error Rates: High error rates may indicate issues with your integration
Use Timeouts: Don't let requests hang indefinitely
Getting Help
If you encounter persistent errors:
Check the Status Page for system issues
Review your code against the examples
Contact support with error details and request IDs
Join our community on Discord for help from other developers
Last updated