Reference

Error Codes

PostMTA uses standard HTTP status codes and structured error objects with machine-readable codes.

Error Response Format

{"error":{"code":"INVALID_RECIPIENT","message":"The recipient address is not valid.","status":400,"details":{"field":"to[0].address","value":"bad@x"},"docs_url":"https://docs.postmta.com/errors/INVALID_RECIPIENT"}}

HTTP Status Codes

CodeMeaning
200OK (includes suppression cases)
201Created
400Bad Request - invalid JSON or missing required field
401Unauthorized - missing or invalid API key
403Forbidden - valid key but insufficient scopes
404Not Found - resource does not exist
422Unprocessable Entity - validation failure
429Too Many Requests - rate limit exceeded
500Internal Server Error
503Service Unavailable - retry with backoff

API Error Codes

CodeStatusDescription
INVALID_API_KEY401API key is invalid or revoked
INSUFFICIENT_SCOPES403Key lacks required scope
INVALID_RECIPIENT400Recipient address is malformed
UNVERIFIED_DOMAIN400Sending domain not verified
DOMAIN_ALREADY_EXISTS409Domain already added
RATE_LIMIT_EXCEEDED429Request rate limit hit
VOLUME_LIMIT_EXCEEDED429Monthly or daily volume quota exceeded
INVALID_TEMPLATE400Template ID not found
MESSAGE_TOO_LARGE400Message exceeds 25 MB limit

Handling Errors

async function sendWithRetry(message, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await postmta.messages.send(message);
    } catch (err) {
      if (err.status >= 500) {
        await new Promise(r => setTimeout(r, Math.min(1000 * 2 ** attempt, 30000)));
        continue;
      }
      throw err;
    }
  }
}