Error Response Format
All errors return a consistent JSON structure:
{
"error": {
"code": "invalid_coordinates",
"message": "Latitude must be between -90 and 90",
"param": "coordinates.latitude",
"request_id": "req_abc123xyz"
}
}
| Field |
Description |
code |
Machine-readable error code |
message |
Human-readable error description |
param |
The parameter that caused the error (if applicable) |
request_id |
Unique identifier for the request (useful for support) |
Authentication Errors (401)
| Code |
Description |
Resolution |
missing_api_key |
No API key provided in request |
Include Authorization: Bearer YOUR_KEY header |
invalid_api_key |
API key is invalid or has been revoked |
Check your API key or create a new one |
expired_api_key |
API key has expired |
Create a new API key from your dashboard |
Payment Errors (402)
| Code |
Description |
Resolution |
insufficient_balance |
Not enough credits to complete the operation |
Add more credits from your dashboard |
Example Response
{
"error": {
"code": "insufficient_balance",
"message": "Insufficient credit balance. Current balance: 0, required: 1",
"current_balance": 0,
"required_credits": 1,
"purchase_url": "https://developers.sealegs.ai/dashboard#billing"
}
}
Authorization Errors (403)
| Code |
Description |
Resolution |
key_suspended |
API key has been suspended |
Contact support for assistance |
account_suspended |
Developer account has been suspended |
Contact support for assistance |
permission_denied |
API key lacks permission for this operation |
Check your API key permissions |
Not Found Errors (404)
| Code |
Description |
Resolution |
spotcast_not_found |
The specified SpotCast does not exist |
Verify the SpotCast ID |
forecast_not_found |
The specified forecast does not exist |
Verify the forecast ID |
resource_not_found |
The requested resource was not found |
Check the endpoint URL |
Validation Errors (400)
| Code |
Description |
Resolution |
invalid_coordinates |
Coordinates are out of valid range |
Latitude: -90 to 90, Longitude: -180 to 180 |
invalid_date_range |
Date range is invalid |
Ensure end_date is after start_date and within 14 days |
invalid_date_format |
Date format is invalid |
Use ISO 8601 format (e.g., 2025-12-05T00:00:00Z) |
invalid_webhook_url |
Webhook URL is invalid |
Must be a valid HTTPS URL |
invalid_preferences |
Preferences format is invalid |
preferences must be an object |
invalid_language |
Language code is not supported |
Use: en, es, fr, pt, it, ja |
invalid_distance_units |
Distance units not supported |
Use: nm, mi, km |
invalid_speed_units |
Speed units not supported |
Use: kts, mph, ms |
missing_required_field |
A required field is missing |
Check the error message for the missing field |
invalid_json |
Request body is not valid JSON |
Verify your JSON syntax |
Rate Limit Errors (429)
| Code |
Description |
Resolution |
rate_limit_exceeded |
Too many requests |
Wait and retry. Check Retry-After header. |
Example Response
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please wait before making more requests.",
"retry_after": 30
}
}
Rate limit responses include helpful headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1701432060
Retry-After: 30
Server Errors (500)
| Code |
Description |
Resolution |
internal_error |
An unexpected error occurred |
Retry the request. If it persists, contact support. |
service_unavailable |
Service is temporarily unavailable |
Wait and retry. Check status page. |
weather_data_unavailable |
Unable to fetch weather data |
Retry the request. Weather data source may be temporarily unavailable. |
processing_failed |
Forecast processing failed |
Retry creating the SpotCast. |
Handling Errors
Best Practices
- Always check the HTTP status code first
- Use the
error.code field for programmatic handling
- Display
error.message to users when appropriate
- Log the
request_id for debugging and support
- Implement exponential backoff for retries
Example Error Handling (Python)
import requests
import time
def create_spotcast(data):
response = requests.post(
"https://api.sealegs.ai/v3/spotcast",
headers={"Authorization": f"Bearer {API_KEY}"},
json=data
)
if response.status_code == 202:
return response.json()
error = response.json().get("error", {})
if response.status_code == 401:
raise AuthenticationError(error.get("message"))
if response.status_code == 402:
raise InsufficientBalanceError(
error.get("message"),
balance=error.get("current_balance")
)
if response.status_code == 429:
retry_after = error.get("retry_after", 60)
time.sleep(retry_after)
return create_spotcast(data) # Retry
if response.status_code >= 500:
# Server error - retry with backoff
raise ServerError(error.get("message"))
# Validation or other client error
raise APIError(error.get("code"), error.get("message"))
Example Error Handling (JavaScript)
async function createSpotcast(data) {
const response = await fetch('https://api.sealegs.ai/v3/spotcast', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (response.status === 202) {
return response.json();
}
const { error } = await response.json();
switch (response.status) {
case 401:
throw new AuthenticationError(error.message);
case 402:
throw new InsufficientBalanceError(error.message, error.current_balance);
case 429:
const retryAfter = error.retry_after || 60;
await new Promise(r => setTimeout(r, retryAfter * 1000));
return createSpotcast(data); // Retry
case 500:
case 502:
case 503:
throw new ServerError(error.message);
default:
throw new APIError(error.code, error.message);
}
}