send.devGuides

The Send.dev API uses conventional HTTP status codes and returns detailed error information in JSON format. This page covers all error types and how to handle them.

Error Response Format

All errors follow a consistent format:

{
  "error": {
    "code": "error_code",
    "message": "Human-readable error message",
    "details": [...],
    "docs_url": "https://send.dev/docs/guides/errors#error_code"
  }
}
FieldDescription
codeMachine-readable error code
messageHuman-readable description
detailsAdditional context (validation errors, etc.)
docs_urlLink to relevant documentation

HTTP Status Codes

StatusMeaning
200Success
201Created
400Bad Request - Invalid parameters
401Unauthorized - Invalid/missing API key
403Forbidden - Valid key, insufficient permissions
404Not Found - Resource doesn't exist
409Conflict - Resource already exists
422Unprocessable Entity - Validation failed
429Too Many Requests - Rate limited
500Internal Server Error - Our fault
503Service Unavailable - Temporary outage

Common Error Codes

Authentication Errors

unauthorized

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key provided"
  }
}

Cause: Missing or invalid API key in Authorization header.

Solution: Verify your API key is correct and properly formatted as Bearer sk_live_...

forbidden

{
  "error": {
    "code": "forbidden",
    "message": "API key not authorized for this action"
  }
}

Cause: Valid API key but lacks permission (e.g., domain-restricted key).

Solution: Check API key permissions or use a key with appropriate access.

Validation Errors

validation_error

{
  "error": {
    "code": "validation_error",
    "message": "Invalid request parameters",
    "details": [
      { "field": "to", "message": "Invalid email address format" },
      { "field": "subject", "message": "Subject is required" }
    ]
  }
}

Cause: Request body contains invalid data.

Solution: Fix the fields listed in details and retry.

Domain Errors

domain_not_verified

{
  "error": {
    "code": "domain_not_verified",
    "message": "Domain 'mail.example.com' is not verified"
  }
}

Cause: Trying to send from an unverified domain.

Solution: Complete domain verification at Domains.

domain_not_authorized

{
  "error": {
    "code": "domain_not_authorized",
    "message": "API key not authorized to send from 'other.domain.com'",
    "authorized_domains": ["mail.yourdomain.com"]
  }
}

Cause: API key is restricted to specific domains.

Solution: Use an authorized domain or update API key permissions.

Rate Limiting

rate_limited

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded",
    "retry_after": 60
  }
}

Cause: Too many requests in the current time window.

Solution: Wait retry_after seconds before retrying. See Rate Limits.

Resource Errors

not_found

{
  "error": {
    "code": "not_found",
    "message": "Email not found",
    "resource_type": "email",
    "resource_id": "email_01HXYZ123456789"
  }
}

Cause: The requested resource doesn't exist.

Solution: Verify the resource ID is correct.

already_exists

{
  "error": {
    "code": "already_exists",
    "message": "Domain already exists",
    "resource_type": "domain",
    "existing_id": "dom_01HXYZ123456789"
  }
}

Cause: Attempting to create a duplicate resource.

Solution: Use the existing resource or choose a different identifier.

Email Errors

attachment_too_large

{
  "error": {
    "code": "attachment_too_large",
    "message": "Attachment exceeds maximum size",
    "max_size_bytes": 10485760,
    "actual_size_bytes": 15728640
  }
}

Cause: File attachment exceeds the 10 MB limit.

Solution: Compress the file or host it externally.

invalid_recipient

{
  "error": {
    "code": "invalid_recipient",
    "message": "Recipient address is invalid or blocked",
    "recipient": "bounced@example.com",
    "reason": "hard_bounce"
  }
}

Cause: Recipient address is invalid or has been blocked.

Solution: Remove the address from your list.

Server Errors

internal_error

{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred",
    "request_id": "req_01HXYZ123456789"
  }
}

Cause: Something went wrong on our end.

Solution: Retry with exponential backoff. If persistent, contact support with the request_id.

Error Handling Examples

Node.js / TypeScript

import { SendDev, SendDevError } from '@send.dev/sdk';

const send = new SendDev({ apiKey: process.env.SEND_API_KEY });

try {
  const email = await send.emails.send({
    from: 'hello@mail.yourdomain.com',
    to: 'user@example.com',
    subject: 'Hello',
    html: '<p>Hello!</p>',
  });
} catch (error) {
  if (error instanceof SendDevError) {
    switch (error.code) {
      case 'rate_limited':
        await sleep(error.retryAfter * 1000);
        // Retry the request
        break;
      case 'validation_error':
        console.error('Validation failed:', error.details);
        break;
      case 'domain_not_verified':
        console.error('Please verify your domain first');
        break;
      default:
        console.error(`Error: ${error.message}`);
    }
  }
}

Python

from senddev import SendDev, SendDevError
import time

send = SendDev(api_key="sk_live_your_api_key")

try:
    email = send.emails.send(
        from_="hello@mail.yourdomain.com",
        to="user@example.com",
        subject="Hello",
        html="<p>Hello!</p>",
    )
except SendDevError as error:
    if error.code == "rate_limited":
        time.sleep(error.retry_after)
        # Retry the request
    elif error.code == "validation_error":
        print(f"Validation failed: {error.details}")
    elif error.code == "domain_not_verified":
        print("Please verify your domain first")
    else:
        print(f"Error: {error.message}")

Best Practices

  1. Always check error codes - Use code for programmatic handling
  2. Log request IDs - Include request_id in error logs for debugging
  3. Implement retries - Use exponential backoff for transient errors
  4. Handle rate limits gracefully - Queue requests and respect retry_after
  5. Validate before sending - Catch validation errors early
  6. Monitor error rates - Set up alerts for unusual error spikes

Getting Help

If you encounter persistent errors:

  1. Check the Status Page for service issues
  2. Search our documentation for solutions
  3. Contact us or email help@do.dev with:
    • Error code and message
    • Request ID (if available)
    • Request payload (sanitize sensitive data)
    • Timestamp of the error

On this page