Back to Documentation
Error Codes
Complete reference of API error codes with descriptions and resolution steps.
Error Response Format
All error responses follow a consistent JSON structure:
Error Response
{
"error": {
"code": "INVALID_EMAIL",
"message": "The email address format is invalid",
"details": {
"field": "to",
"value": "invalid-email"
},
"request_id": "req_abc123xyz"
}
}Response Fields
code- Machine-readable error codemessage- Human-readable error descriptiondetails- Additional context (optional)request_id- Unique request identifier for support
Authentication Errors (401)
| Code | Message | Resolution |
|---|---|---|
INVALID_API_KEY | The API key provided is invalid | Check that your API key is correct and starts with 'ek_live_' or 'ek_test_' |
EXPIRED_API_KEY | The API key has expired | Generate a new API key from your dashboard settings |
REVOKED_API_KEY | The API key has been revoked | Generate a new API key from your dashboard settings |
MISSING_API_KEY | No API key was provided | Include your API key in the Authorization header |
Validation Errors (400)
| Code | Message | Resolution |
|---|---|---|
INVALID_EMAIL | The email address format is invalid | Ensure the 'to' field contains a valid email address |
INVALID_PHONE | The phone number format is invalid | Use E.164 format for phone numbers (e.g., +14155552671) |
MISSING_REQUIRED_FIELD | A required field is missing | Check the error details for the missing field name |
INVALID_TEMPLATE_ID | The specified template does not exist | Verify the template ID in your dashboard |
INVALID_ATTACHMENT | The attachment is invalid or too large | Ensure attachments are base64 encoded and under 25MB |
INVALID_SCHEDULE_TIME | The scheduled time is in the past | Set scheduled_at to a future timestamp |
Permission Errors (403)
| Code | Message | Resolution |
|---|---|---|
INSUFFICIENT_PERMISSIONS | Your API key lacks the required scope | Generate a new API key with the needed scopes |
DOMAIN_NOT_VERIFIED | The sending domain is not verified | Verify your domain in the dashboard settings |
PHONE_NOT_REGISTERED | The sending phone number is not registered | Purchase or register a phone number in your account |
FEATURE_NOT_AVAILABLE | This feature is not available on your plan | Upgrade your plan to access this feature |
Resource Errors (404)
| Code | Message | Resolution |
|---|---|---|
EMAIL_NOT_FOUND | The specified email does not exist | Verify the email ID is correct |
SMS_NOT_FOUND | The specified SMS does not exist | Verify the SMS ID is correct |
CALL_NOT_FOUND | The specified call does not exist | Verify the call ID is correct |
TEMPLATE_NOT_FOUND | The specified template does not exist | Check the template ID in your dashboard |
WEBHOOK_NOT_FOUND | The specified webhook does not exist | Verify the webhook ID is correct |
Rate Limit Errors (429)
| Code | Message | Resolution |
|---|---|---|
RATE_LIMIT_EXCEEDED | Too many requests | Wait for the Retry-After period and implement backoff |
DAILY_LIMIT_EXCEEDED | Daily sending limit exceeded | Wait until the limit resets or upgrade your plan |
MONTHLY_LIMIT_EXCEEDED | Monthly sending limit exceeded | Upgrade your plan for higher limits |
Server Errors (500)
| Code | Message | Resolution |
|---|---|---|
INTERNAL_ERROR | An unexpected error occurred | Retry the request. If it persists, contact support |
SERVICE_UNAVAILABLE | The service is temporarily unavailable | Wait and retry with exponential backoff |
GATEWAY_TIMEOUT | The request timed out | Retry the request with a smaller payload |
Handling Errors
JavaScript
javascript
async function sendEmail(data) {
try {
const response = await fetch('/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer ek_live_xxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (!response.ok) {
const error = await response.json();
switch (error.error.code) {
case 'INVALID_EMAIL':
console.error('Invalid email:', error.error.details.value);
break;
case 'RATE_LIMIT_EXCEEDED':
const retryAfter = response.headers.get('Retry-After');
console.log(`Retry after ${retryAfter} seconds`);
break;
case 'DOMAIN_NOT_VERIFIED':
console.error('Please verify your domain first');
break;
default:
console.error('API Error:', error.error.message);
}
return null;
}
return response.json();
} catch (err) {
console.error('Network error:', err);
return null;
}
}Python
python
from ekdsend import EKDSend
from ekdsend.exceptions import (
ValidationError,
AuthenticationError,
RateLimitError,
APIError
)
client = EKDSend('ek_live_xxxxxxxxxxxxx')
try:
email = client.emails.send(
from_email='hello@yourdomain.com',
to='user@example.com',
subject='Hello',
html='<p>World</p>'
)
except ValidationError as e:
print(f"Validation error: {e.code}")
print(f"Details: {e.details}")
except AuthenticationError as e:
print(f"Auth error: {e.message}")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except APIError as e:
print(f"API error ({e.status_code}): {e.message}")
print(f"Request ID: {e.request_id}")Need Help?
If you encounter an error that you cannot resolve, please include the request_id from the error response when contacting support. This helps us quickly identify and resolve your issue.