Skip to content

Error Handling

The MailShield API uses conventional HTTP response codes and returns errors in a consistent JSON format.

Error Response Format

All errors follow this structure:

json
{
  "error": {
    "code": "error_code",
    "message": "Human-readable error message",
    "details": {}  // Optional additional information
  }
}

HTTP Status Codes

CodeDescription
200Success
201Created (for POST requests)
400Bad Request - Invalid parameters or request body
401Unauthorized - Invalid or missing authentication
403Forbidden - Valid auth but insufficient permissions
404Not Found - Resource doesn't exist
409Conflict - Resource already exists
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Something went wrong on our end

Error Codes

Authentication Errors

CodeStatusDescription
unauthorized401Missing or invalid Authorization header
unauthorized401Invalid API token format
unauthorized401API token has expired

Authorization Errors

CodeStatusDescription
forbidden403IP address not allowed for this token
forbidden403API access not enabled for organization
forbidden403Domain limit reached

Resource Errors

CodeStatusDescription
not_found404Domain not found
conflict409Domain already exists

Validation Errors

CodeStatusDescription
validation_error400Invalid request body or parameters

Validation errors include a details array with specific field errors:

json
{
  "error": {
    "code": "validation_error",
    "message": "Invalid request body",
    "details": [
      {
        "path": ["domain"],
        "message": "Invalid domain format"
      },
      {
        "path": ["testEmailLocalPart"],
        "message": "testEmailLocalPart is required for domains that receive email"
      }
    ]
  }
}

Rate Limiting Errors

CodeStatusDescription
rate_limited429Too many requests

Rate limit errors include a Retry-After header with seconds to wait.

Handling Errors

Python Example

python
import requests

def api_request(url, headers):
    response = requests.get(url, headers=headers)

    if response.ok:
        return response.json()["data"]

    error = response.json()["error"]

    if response.status_code == 401:
        raise AuthenticationError(error["message"])
    elif response.status_code == 403:
        raise PermissionError(error["message"])
    elif response.status_code == 404:
        raise NotFoundError(error["message"])
    elif response.status_code == 429:
        retry_after = response.headers.get("Retry-After", 60)
        raise RateLimitError(f"Rate limited. Retry after {retry_after}s")
    else:
        raise APIError(error["message"])

Node.js Example

javascript
async function apiRequest(url, headers) {
  const response = await fetch(url, { headers });
  const body = await response.json();

  if (response.ok) {
    return body.data;
  }

  const { code, message, details } = body.error;

  switch (response.status) {
    case 401:
      throw new AuthenticationError(message);
    case 403:
      throw new PermissionError(message);
    case 404:
      throw new NotFoundError(message);
    case 429:
      const retryAfter = response.headers.get('Retry-After');
      throw new RateLimitError(message, retryAfter);
    case 400:
      throw new ValidationError(message, details);
    default:
      throw new APIError(message);
  }
}

Debugging Tips

  1. Check the error code - It tells you exactly what went wrong

  2. Read the message - It's human-readable and often actionable

  3. Look at details - For validation errors, check which fields failed

  4. Verify your token - Most 401 errors are token-related

  5. Check IP allowlist - 403 with "IP not allowed" means your IP isn't whitelisted

  6. Review rate limits - 429 means you're making too many requests

Monitor and secure your email domains.