Skip to main content

authenticationError

The authenticationError webhook event is triggered when EmailEngine fails to authenticate an email account. This event helps you monitor account health and take action when credentials become invalid or authentication issues arise.

When This Event is Triggered

The authenticationError event fires when:

  • IMAP authentication fails due to invalid credentials
  • OAuth2 access token renewal fails
  • OAuth2 API request returns an authentication error (Gmail API, Microsoft Graph API)
  • The email server rejects the login attempt

EmailEngine uses intelligent error tracking to avoid spamming your webhook endpoint. The event is only sent on the first occurrence of an authentication error for an account. Subsequent identical errors are suppressed until the account successfully authenticates again or the error state changes.

Common Use Cases

  • Account monitoring - Alert administrators when user accounts fail authentication
  • Credential rotation - Trigger workflows to refresh or request new credentials
  • User notification - Inform users that their email connection needs attention
  • Dashboard updates - Update account status in your application's UI
  • Automated remediation - Attempt to refresh OAuth2 tokens or re-authenticate
  • Compliance logging - Track authentication failures for security audits

Payload Schema

Top-Level Fields

FieldTypeRequiredDescription
serviceUrlstringNoThe configured EmailEngine service URL
accountstringYesAccount ID that failed authentication
datestringYesISO 8601 timestamp when the webhook was generated
eventstringYesEvent type, always "authenticationError" for this event
eventIdstringYesUnique identifier for this webhook delivery
dataobjectYesError details object (see below)

Error Data Fields (data object)

FieldTypeRequiredDescription
responsestringYesError message describing the authentication failure
serverResponseCodestringNoServer or API error code identifying the failure type
tokenRequestobjectNoOAuth2 token request details (for OAuth2 errors only)

Token Request Object (tokenRequest)

When OAuth2 token renewal fails, additional details may be included:

FieldTypeDescription
grantstringOAuth2 grant type used (e.g., "refresh_token")
providerstringOAuth2 provider (e.g., "gmail", "outlook", "mailRu")
statusnumberHTTP status code from the token endpoint
clientIdstringOAuth2 client ID used (partially masked)
scopesarrayOAuth2 scopes requested

Server Response Codes

Common serverResponseCode values you may encounter:

CodeDescription
AUTHENTICATIONFAILEDIMAP server rejected the credentials
OauthRenewErrorFailed to renew OAuth2 access token
ApiRequestErrorAPI request returned an authentication error
AUTHORIZATIONFAILEDAuthorization was denied by the server
WEBALERTGmail requires web login for security verification

Example Payload (IMAP Authentication)

{
"serviceUrl": "https://emailengine.example.com",
"account": "user123",
"date": "2025-10-17T14:30:00.000Z",
"event": "authenticationError",
"eventId": "b8f3c2a1-9d4e-4f5a-8b7c-6d5e4f3a2b1c",
"data": {
"response": "Invalid credentials (Failure)",
"serverResponseCode": "AUTHENTICATIONFAILED"
}
}

Example Payload (OAuth2 Token Renewal)

{
"serviceUrl": "https://emailengine.example.com",
"account": "gmail-user456",
"date": "2025-10-17T15:45:00.000Z",
"event": "authenticationError",
"eventId": "c9d4e5f6-1a2b-3c4d-5e6f-7a8b9c0d1e2f",
"data": {
"response": "Token has been expired or revoked.",
"serverResponseCode": "OauthRenewError",
"tokenRequest": {
"grant": "refresh_token",
"provider": "gmail",
"status": 400,
"clientId": "12345...apps.googleusercontent.com",
"scopes": [
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.send"
]
}
}
}

Example Payload (API Request Error)

For Gmail API or Microsoft Graph API accounts:

{
"serviceUrl": "https://emailengine.example.com",
"account": "outlook-user789",
"date": "2025-10-17T16:20:00.000Z",
"event": "authenticationError",
"eventId": "d0e1f2a3-4b5c-6d7e-8f9a-0b1c2d3e4f5a",
"data": {
"response": "The access token has expired or is not yet valid.",
"serverResponseCode": "ApiRequestError"
}
}

Handling the Event

Basic Handler

async function handleAuthenticationError(event) {
const { account, data } = event;

console.error(`Authentication failed for account ${account}:`);
console.error(` Error: ${data.response}`);
console.error(` Code: ${data.serverResponseCode || 'N/A'}`);

// Take appropriate action based on error type
switch (data.serverResponseCode) {
case 'OauthRenewError':
await handleOAuthError(account, data);
break;
case 'AUTHENTICATIONFAILED':
await handleCredentialError(account, data);
break;
default:
await notifyAdmin(account, data);
}
}

async function handleOAuthError(account, data) {
// OAuth token expired - may need user re-authorization
console.log(`OAuth token expired for ${account}`);

// Option 1: Notify user to re-authenticate
await sendUserNotification(account, 'Please reconnect your email account');

// Option 2: If using service account, attempt refresh
// await refreshServiceAccountToken(account);
}

async function handleCredentialError(account, data) {
// Password may have changed
console.log(`Credentials invalid for ${account}`);
await sendUserNotification(account, 'Please update your email password');
}

Alerting Administrators

async function handleAuthenticationError(event) {
const { account, data, date } = event;

// Send alert to monitoring system
await sendAlert({
severity: 'warning',
title: 'Email Authentication Failed',
message: `Account ${account} failed to authenticate`,
details: {
account,
error: data.response,
code: data.serverResponseCode,
timestamp: date
}
});
}

Updating Account Status in Database

async function handleAuthenticationError(event) {
const { account, data, date } = event;

// Update account status in your database
await db.accounts.update({
where: { emailEngineId: account },
data: {
status: 'authentication_error',
lastError: data.response,
lastErrorCode: data.serverResponseCode,
lastErrorAt: new Date(date)
}
});

// Trigger UI notification if user is online
await notifyConnectedUser(account, {
type: 'account_error',
message: 'Email connection lost - please reconnect'
});
}

Error Recovery

Automatic IMAP Disabling

EmailEngine has built-in protection against repeated authentication failures. If an account continues to fail authentication over an extended period (default: 3 days), EmailEngine will automatically disable IMAP for that account to prevent:

  • Continued failed login attempts that may trigger account lockouts
  • Unnecessary load on the mail server
  • Repeated webhook spam

When this happens, the account's IMAP configuration will be marked as disabled: true. To re-enable:

  1. Fix the underlying credential issue
  2. Update the account credentials via API
  3. The account will attempt to reconnect automatically

Re-authenticating an Account

If you need to update credentials after an authentication error:

# Update IMAP credentials
curl -X PUT "https://your-emailengine.com/v1/account/user123" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"imap": {
"auth": {
"user": "user@example.com",
"pass": "new-password"
}
}
}'

For OAuth2 accounts, the user typically needs to go through the authentication flow again to obtain new tokens.

Webhook Deduplication

EmailEngine tracks error states to prevent webhook flooding. Key behaviors:

  1. First occurrence - Webhook is sent immediately when authentication first fails
  2. Repeated failures - Subsequent identical errors do NOT trigger new webhooks
  3. State change - A new webhook is sent only when:
    • The account successfully authenticates (triggers authenticationSuccess)
    • The error message or code changes
    • The account is reconnected after being disabled

This means you can rely on receiving exactly one authenticationError webhook per failure episode, making it safe to trigger alerts without rate limiting on your end.

See Also