When an error occurs, the API returns a JSON response with the following structure:
{
"error" : {
"code" : "invalid_api_key" ,
"message" : "The API key provided is invalid or has been revoked." ,
"status" : 401 ,
"details" : {
"api_key_prefix" : "un_xxx..."
}
}
}
Field Type Description codestring Machine-readable error identifier messagestring Human-readable error description statusnumber HTTP status code detailsobject Additional context (optional)
HTTP Status Codes
2xx Success Request was successful
4xx Client Error Something was wrong with the request
5xx Server Error Something went wrong on our end
Authentication Errors
Code Status Description missing_api_key401 No API key provided in request invalid_api_key401 API key is invalid or revoked api_key_expired401 API key has expired insufficient_permissions403 API key lacks required permissions
How to Fix
# Correct format: Include API key in Authorization header
curl -X POST "https://www.unosend.co/api/v1/emails" \
-H "Authorization: Bearer un_your_api_key" \
-H "Content-Type: application/json" \
-d '{"from": "[email protected] ", "to": "[email protected] ", "subject": "Test", "html": "<p>Hello</p>"}'
Common mistake: Make sure you’re using Bearer prefix before your API key.
The format should be Authorization: Bearer un_your_api_key.
Validation Errors
Code Status Description validation_error400 Request body failed validation missing_required_field400 Required field is missing invalid_email_address400 Email address format is invalid invalid_from_address400 From address domain not verified invalid_template_variables400 Template variables don’t match schema attachment_too_large400 Attachment exceeds size limit (10MB) invalid_json400 Request body is not valid JSON
Example Validation Error
{
"error" : {
"code" : "validation_error" ,
"message" : "Request validation failed" ,
"status" : 400 ,
"details" : {
"errors" : [
{
"field" : "to" ,
"message" : "must be a valid email address" ,
"value" : "not-an-email"
},
{
"field" : "subject" ,
"message" : "is required" ,
"value" : null
}
]
}
}
}
Handling Validation Errors
const response = await fetch ( 'https://www.unosend.co/api/v1/emails' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( payload )
});
if ( response . status === 400 ) {
const error = await response . json ();
if ( error . error . code === 'validation_error' ) {
// Log each field error
error . error . details . errors . forEach (( e : any ) => {
console . error ( `Field ' ${ e . field } ': ${ e . message } ` );
});
}
}
Resource Errors
Code Status Description not_found404 Resource doesn’t exist email_not_found404 Email ID not found domain_not_found404 Domain not found in workspace template_not_found404 Template ID not found audience_not_found404 Audience not found contact_not_found404 Contact not found webhook_not_found404 Webhook not found
Example 404 Response
{
"error" : {
"code" : "email_not_found" ,
"message" : "Email with ID 'em_abc123' not found" ,
"status" : 404 ,
"details" : {
"email_id" : "em_abc123"
}
}
}
Rate Limit Errors
Code Status Description rate_limit_exceeded429 Too many requests per second daily_limit_exceeded429 Daily email limit reached quota_exceeded429 Monthly quota exceeded
Rate Limit Response
{
"error" : {
"code" : "rate_limit_exceeded" ,
"message" : "Rate limit exceeded. Retry after 60 seconds." ,
"status" : 429 ,
"details" : {
"retry_after" : 60 ,
"limit" : 100 ,
"remaining" : 0 ,
"reset_at" : "2024-01-15T10:30:00Z"
}
}
}
See the Rate Limits documentation for handling strategies and retry logic examples.
Domain Errors
Code Status Description domain_not_verified400 Domain has not been verified yet domain_verification_failed400 DNS records not found or incorrect domain_already_exists409 Domain already registered in another workspace dkim_verification_failed400 DKIM record not found or invalid spf_verification_failed400 SPF record not found or invalid
Server Errors
Code Status Description internal_server_error500 Unexpected server error service_unavailable503 Service temporarily unavailable gateway_timeout504 Request timed out email_delivery_failed500 Failed to deliver email to mail server
5xx errors are rare and usually temporary. Implement retry logic with exponential backoff for these errors.
Complete Error Handling Example
JavaScript/TypeScript
Python
cURL Error Checking
interface UnosendError {
error : {
code : string ;
message : string ;
status : number ;
details ?: Record < string , any >;
};
}
async function sendEmail ( payload : EmailPayload ) : Promise < EmailResponse > {
const response = await fetch ( 'https://www.unosend.co/api/v1/emails' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( payload )
});
if ( ! response . ok ) {
const error : UnosendError = await response . json ();
switch ( error . error . code ) {
case 'invalid_api_key' :
case 'missing_api_key' :
throw new Error ( 'Authentication failed. Check your API key.' );
case 'validation_error' :
const fields = error . error . details ?. errors
?. map (( e : any ) => ` ${ e . field } : ${ e . message } ` )
. join ( ', ' );
throw new Error ( `Validation failed: ${ fields } ` );
case 'rate_limit_exceeded' :
const retryAfter = error . error . details ?. retry_after || 60 ;
// Implement retry logic
await sleep ( retryAfter * 1000 );
return sendEmail ( payload ); // Retry once
case 'domain_not_verified' :
throw new Error ( 'Verify your domain before sending emails.' );
case 'quota_exceeded' :
throw new Error ( 'Monthly email quota exceeded. Upgrade your plan.' );
case 'internal_server_error' :
case 'service_unavailable' :
// Retry with exponential backoff
throw new Error ( 'Service temporarily unavailable. Please retry.' );
default :
throw new Error ( error . error . message );
}
}
return response . json ();
}
Quick Reference
Retryable Errors
429 Rate limit exceeded
500 Internal server error
503 Service unavailable
504 Gateway timeout
Non-Retryable Errors
400 Validation error
401 Authentication error
403 Permission denied
404 Resource not found