Command Palette

Search for a command to run...

Reference

Error Codes

Complete reference of error codes returned by the Unosend API and how to handle them.

Error Response Format

When an error occurs, the API returns a JSON response with the following structure:

error-response.json
{
  "error": {
    "code": "invalid_api_key",
    "message": "The API key provided is invalid or has been revoked.",
    "status": 401,
    "details": {
      "api_key_prefix": "un_xxx..."
    }
  }
}
FieldTypeDescription
codestringMachine-readable error identifier
messagestringHuman-readable error description
statusnumberHTTP status code
detailsobjectAdditional 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

CodeStatusDescription
missing_api_key401No API key provided in request
invalid_api_key401API key is invalid or revoked
api_key_expired401API key has expired
insufficient_permissions403API key lacks required permissions

How to Fix

terminal
# Correct format: Include API key in Authorization header
curl -X POST "https://www.unosend.co/api/v1/emails" \
  -H "Authorization: Bearer un_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"from": "hello@yourdomain.com", "to": "user@example.com", "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_xxxxxxxx.

Validation Errors

CodeStatusDescription
validation_error400Request body failed validation
missing_required_field400Required field is missing
invalid_email_address400Email address format is invalid
invalid_from_address400From address domain not verified
invalid_template_variables400Template variables don't match schema
attachment_too_large400Attachment exceeds size limit (10MB)
invalid_json400Request body is not valid JSON

Example Validation Error

validation-error.json
{
  "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

handle-validation.ts
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

CodeStatusDescription
not_found404Resource doesn't exist
email_not_found404Email ID not found
domain_not_found404Domain not found in workspace
template_not_found404Template ID not found
audience_not_found404Audience not found
contact_not_found404Contact not found
webhook_not_found404Webhook not found

Example 404 Response

not-found.json
{
  "error": {
    "code": "email_not_found",
    "message": "Email with ID 'em_abc123' not found",
    "status": 404,
    "details": {
      "email_id": "em_abc123"
    }
  }
}

Rate Limit Errors

CodeStatusDescription
rate_limit_exceeded429Too many requests per second
daily_limit_exceeded429Daily email limit reached
quota_exceeded429Monthly quota exceeded

Rate Limit Response

rate-limit.json
{
  "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

CodeStatusDescription
domain_not_verified400Domain has not been verified yet
domain_verification_failed400DNS records not found or incorrect
domain_already_exists409Domain already registered in another workspace
dkim_verification_failed400DKIM record not found or invalid
spf_verification_failed400SPF record not found or invalid

See Domain Verification guide for setting up DNS records correctly.

Server Errors

CodeStatusDescription
internal_server_error500Unexpected server error
service_unavailable503Service temporarily unavailable
gateway_timeout504Request timed out
email_delivery_failed500Failed 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

error-handling.ts
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();
}

Python

error_handling.py
import requests
import time

class UnosendError(Exception):
    def __init__(self, code, message, status, details=None):
        self.code = code
        self.message = message
        self.status = status
        self.details = details or {}
        super().__init__(message)

def send_email(payload):
    api_key = "un_xxxxxxxx"
    
    response = requests.post(
        "https://www.unosend.co/api/v1/emails",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        },
        json=payload
    )
    
    if not response.ok:
        error = response.json()["error"]
        
        if error["code"] == "rate_limit_exceeded":
            retry_after = error.get("details", {}).get("retry_after", 60)
            time.sleep(retry_after)
            return send_email(payload)  # Retry
        
        if error["code"] == "validation_error":
            errors = error.get("details", {}).get("errors", [])
            fields = ", ".join([f"{e['field']}: {e['message']}" for e in errors])
            raise UnosendError(
                error["code"],
                f"Validation failed: {fields}",
                error["status"],
                error.get("details")
            )
        
        raise UnosendError(
            error["code"],
            error["message"],
            error["status"],
            error.get("details")
        )
    
    return response.json()

cURL Error Checking

terminal
# Check HTTP status code and response
response=$(curl -s -w "\n%{http_code}" -X POST "https://www.unosend.co/api/v1/emails" \
  -H "Authorization: Bearer un_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"from": "hello@yourdomain.com", "to": "user@example.com", "subject": "Test", "html": "<p>Hello</p>"}')

status=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

if [ "$status" -ge 400 ]; then
  echo "Error ($status): $body"
else
  echo "Success: $body"
fi

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