How to handle errors and troubleshoot issues with the API
All error responses follow a consistent envelope that matches our OpenAPI schema:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid query parameters",
"details": { /* optional */ }
}
}success - Always false for error responseserror.code - Machine-readable code (e.g., VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, NOT_FOUND, RATE_LIMITED, INTERNAL_ERROR)error.message - Human-readable error messageerror.details - Additional context about the error (optional)The request was invalid. Check your parameters and request body.
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid stock symbol format",
"details": null
}
}Authentication failed. Check your API key.
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key",
"details": null
}
}You don't have permission to access this resource.
{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Missing required scope",
"details": null
}
}The requested resource doesn't exist.
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Alert not found",
"details": null
}
}Rate limit exceeded. See Rate Limits documentation.
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests",
"details": {
"limit": 200,
"remaining": 0,
"reset": 1736180400000
}
}
}Something went wrong on our end. Please try again later.
{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error",
"details": null
}
}The service is temporarily unavailable. Please retry.
{
"success": false,
"error": "Service temporarily unavailable",
"code": "SERVICE_UNAVAILABLE"
}| Error Code | Description |
|---|---|
INVALID_PARAMETER | One or more parameters are invalid |
MISSING_PARAMETER | A required parameter is missing |
INVALID_API_KEY | The API key is invalid or expired |
RATE_LIMIT_EXCEEDED | Too many requests in a given time period |
RESOURCE_NOT_FOUND | The requested resource doesn't exist |
LIMIT_EXCEEDED | Account limit reached (alerts, API keys, etc.) |
INVALID_STOCK_SYMBOL | Stock symbol not found or not supported |
DUPLICATE_ALERT | An identical alert already exists |
async function createAlert(alertData) {
try {
const response = await fetch('https://stockalert.pro/api/v1/alerts', {
method: 'POST',
headers: {
'X-API-Key': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(alertData)
});
const data = await response.json();
if (!response.ok) {
// Handle specific error codes
switch (data.code) {
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
const retryAfter = data.details?.reset || 60;
await sleep(retryAfter * 1000);
return createAlert(alertData); // Retry
case 'INVALID_STOCK_SYMBOL':
// Show user-friendly error
throw new Error('Stock symbol not found. Please check and try again.');
default:
// Generic error handling
throw new Error(data.error || 'An error occurred');
}
}
return data;
} catch (error) {
console.error('API Error:', error);
throw error;
}
}import requests
import time
def create_alert(alert_data, max_retries=3):
url = 'https://stockalert.pro/api/v1/alerts'
headers = {
'X-API-Key': os.environ['API_KEY'],
'Content-Type': 'application/json'
}
for attempt in range(max_retries):
try:
response = requests.post(url, json=alert_data, headers=headers)
data = response.json()
if response.status_code == 429:
# Rate limited - wait and retry
retry_after = data.get('details', {}).get('reset', 60)
time.sleep(retry_after)
continue
if not response.ok:
# Handle specific errors
error_code = data.get('code')
if error_code == 'INVALID_STOCK_SYMBOL':
raise ValueError('Invalid stock symbol')
else:
raise Exception(data.get('error', 'Unknown error'))
return data
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
if attempt == max_retries - 1:
raise
raise Exception("Max retries exceeded")