Skip to main content

Accounts API

The Accounts API allows you to programmatically manage email accounts in EmailEngine. You can register new accounts, update settings, monitor connection status, and handle OAuth2 authentication.

Overview

Email accounts are the core resource in EmailEngine. Each account represents a connection to an email service (Gmail, Outlook, IMAP/SMTP server) and maintains:

  • Connection credentials (OAuth2 tokens or passwords)
  • Mailbox synchronization state
  • Account-specific settings
  • Connection status and health

Account Object Structure

{
"account": "user@example.com",
"name": "John Doe",
"email": "user@example.com",
"state": "connected",
"syncTime": 1640995200000,
"notifyFrom": "2025-01-01T00:00:00.000Z",
"lastError": null,
"imap": {
"host": "imap.gmail.com",
"port": 993,
"secure": true,
"disabled": false
},
"smtp": {
"host": "smtp.gmail.com",
"port": 465,
"secure": true,
"disabled": false
},
"oauth2": {
"enabled": true,
"provider": "gmail",
"auth": {
"user": "user@example.com"
}
}
}

Account States

StateDescription
initAccount registered, connection not yet attempted
connectingAttempting to connect to mail server
syncingConnected and synchronizing mailboxes
connectedSuccessfully connected and fully synced
authenticationErrorAuthentication failed (invalid credentials or expired token)
connectErrorConnection failed (network or server issue)
disconnectedConnection closed or lost
unsetInitial state before any connection attempt (internal)

Common Operations

1. Register Account

Register a new email account with EmailEngine.

Endpoint: POST /v1/account

Request Parameters:

FieldTypeRequiredDescription
accountstringYesUnique account identifier (usually email address)
namestringYesDisplay name for the account
emailstringNoEmail address (defaults to account)
imapobjectYes*IMAP connection settings
smtpobjectNoSMTP connection settings
oauth2objectNoOAuth2 settings
notifyFromstringNoISO date to send webhooks from (default: account creation time)

*Either imap or oauth2 is required.

IMAP Configuration:

{
"host": "imap.example.com",
"port": 993,
"secure": true,
"auth": {
"user": "username",
"pass": "password"
}
}

SMTP Configuration:

{
"host": "smtp.example.com",
"port": 465,
"secure": true,
"auth": {
"user": "username",
"pass": "password"
}
}

Examples:

curl -X POST http://localhost:3000/v1/account \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": "user@example.com",
"name": "John Doe",
"imap": {
"host": "imap.example.com",
"port": 993,
"secure": true,
"auth": {
"user": "user@example.com",
"pass": "password"
}
}
}'

Pseudo code:

// Register a new email account
response = HTTP_POST("http://localhost:3000/v1/account", {
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: {
account: "user@example.com",
name: "John Doe",
imap: {
host: "imap.example.com",
port: 993,
secure: true,
auth: {
user: "user@example.com",
pass: "password"
}
},
smtp: {
host: "smtp.example.com",
port: 465,
secure: true,
auth: {
user: "user@example.com",
pass: "password"
}
}
}
})

result = PARSE_JSON(response.body)
PRINT("Account registered: " + result.account)

Response:

{
"account": "user@example.com",
"state": "init"
}

Use Cases:

  • Onboarding new users to your application
  • Allowing users to connect multiple email accounts
  • Automated account provisioning in bulk

Detailed API reference →


2. List Accounts

Retrieve all registered accounts.

Endpoint: GET /v1/accounts

Query Parameters:

ParameterTypeDescription
pagenumberPage number (0-indexed)
pageSizenumberItems per page (default 20)
statestringFilter by account state
querystringFilter accounts by string match

Examples:

curl "http://localhost:3000/v1/accounts?pageSize=50" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"total": 2,
"page": 0,
"pages": 1,
"accounts": [
{
"account": "user1@example.com",
"name": "John Doe",
"email": "user1@example.com",
"state": "connected"
},
{
"account": "user2@example.com",
"name": "Jane Smith",
"email": "user2@example.com",
"state": "authenticationError"
}
]
}

Use Cases:

  • Dashboard displaying all connected accounts
  • Health monitoring across accounts
  • Bulk operations on multiple accounts

Detailed API reference →


3. Get Account Details

Retrieve detailed information about a specific account.

Endpoint: GET /v1/account/:account

Path Parameters:

ParameterDescription
accountAccount identifier

Examples:

curl "http://localhost:3000/v1/account/user@example.com" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"account": "user@example.com",
"name": "John Doe",
"email": "user@example.com",
"state": "connected",
"syncTime": 1640995200000,
"lastError": null,
"counters": {
"sent": 42,
"received": 128
}
}

Use Cases:

  • Displaying account status in user interface
  • Checking connection health
  • Retrieving account statistics

Detailed API reference →


4. Update Account

Update account settings or credentials.

Endpoint: PUT /v1/account/:account

Request Body:

{
"name": "New Display Name",
"imap": {
"partial": true,
"port": 993
},
"smtp": {
"partial": true,
"port": 465
}
}
Partial Updates

Use "partial": true inside imap, smtp, or oauth2 objects to update only the specified fields instead of replacing the entire configuration. Without this flag, the entire object will be replaced, potentially losing existing settings.

Note: The partial flag only works for main-level objects (imap, smtp, oauth2), not for nested objects like imap.auth.

Examples:

curl -X PUT "http://localhost:3000/v1/account/user@example.com" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Name",
"imap": {
"partial": true,
"port": 993
}
}'

Use Cases:

  • Updating account credentials after password change
  • Changing display names
  • Modifying connection settings

Detailed API reference →


5. Delete Account

Remove an account and stop synchronization.

Endpoint: DELETE /v1/account/:account

Examples:

curl -X DELETE "http://localhost:3000/v1/account/user@example.com" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"success": true,
"account": "user@example.com"
}

Use Cases:

  • User disconnecting their email account
  • Removing inactive accounts
  • Cleanup during offboarding

Detailed API reference →


6. Reconnect Account

Force reconnection to mail server (useful after credential updates).

Endpoint: PUT /v1/account/:account/reconnect

Examples:

curl -X PUT "http://localhost:3000/v1/account/user@example.com/reconnect" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Use Cases:

  • Testing connection after credential update
  • Recovering from connection errors
  • Manual reconnection trigger

Detailed API reference →


7. Account Operations: Reconnect vs Sync vs Flush

EmailEngine provides three distinct operations for managing account connections, each suited for different scenarios.

Reconnect

Endpoint: PUT /v1/account/:account/reconnect

Closes the existing IMAP connection entirely and opens a new one. This is a full disconnect/reconnect cycle.

curl -X PUT "http://localhost:3000/v1/account/user@example.com/reconnect" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

When to use:

  • After updating account credentials (password change, OAuth2 token update)
  • To recover from persistent connection errors
  • When you need a fresh IMAP session (e.g., after server-side configuration changes)

Detailed API reference -->


Sync

Endpoint: PUT /v1/account/:account/sync

Triggers an immediate mailbox synchronization without disconnecting. Refreshes the folder list and syncs all monitored mailboxes.

curl -X PUT "http://localhost:3000/v1/account/user@example.com/sync" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

When to use:

  • When you need the latest messages immediately without waiting for the next poll cycle
  • After bulk operations on the mail server (e.g., importing messages via another client)
  • To ensure webhooks are triggered for recently arrived messages

Detailed API reference -->


Flush

Endpoint: PUT /v1/account/:account/flush

Deletes all cached email data (message indexes, folder lists, bounce data) from Redis and Elasticsearch, then triggers a full re-sync from scratch. The account is paused during the operation and automatically resumed after completion.

curl -X PUT "http://localhost:3000/v1/account/user@example.com/flush" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Destructive Operation

Flush deletes all cached data for the account. This triggers a complete re-indexing of all messages, which may take significant time for large mailboxes and will re-trigger messageNew webhooks unless notifyFrom is set appropriately. Only one flush operation can run at a time across all accounts.

When to use:

  • To fix data corruption or synchronization issues
  • After major mailbox reorganization on the server
  • When message listings show stale or incorrect data
  • As a last resort when reconnect and sync don't resolve issues

Detailed API reference -->


Comparison

OperationConnectionDataDurationImpact
ReconnectCloses and reopensPreservedSecondsBrief interruption
SyncStays connectedPreservedSeconds to minutesNo interruption
FlushPaused temporarilyDeleted and rebuiltMinutes to hoursRe-indexes everything

Decision guide:

  1. Try sync first -- it's the least disruptive way to get fresh data
  2. Use reconnect if the connection itself seems broken or after credential changes
  3. Use flush only when cached data is corrupted or fundamentally out of sync

8. Verify Account Credentials

Pre-validate IMAP and SMTP credentials before creating an account.

Endpoint: POST /v1/verifyAccount

Tests IMAP and/or SMTP connections without creating or modifying any account. Both protocols are tested in parallel.

curl -X POST "http://localhost:3000/v1/verifyAccount" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"imap": {
"host": "imap.example.com",
"port": 993,
"secure": true,
"auth": {
"user": "john@example.com",
"pass": "password"
}
},
"smtp": {
"host": "smtp.example.com",
"port": 587,
"secure": false,
"auth": {
"user": "john@example.com",
"pass": "password"
}
}
}'

Success response:

{
"imap": { "success": true },
"smtp": { "success": true }
}

Failure response (bad IMAP credentials):

{
"imap": {
"success": false,
"error": "Authentication failed",
"code": "AUTHENTICATIONFAILED",
"responseText": "NO [AUTHENTICATIONFAILED] Invalid credentials"
},
"smtp": { "success": true }
}

Use Cases:

  • Validate credentials in your onboarding flow before creating the account
  • Build a "test connection" button in your UI
  • Verify server settings returned by the autoconfig endpoint

Detailed API reference -->


Account Object Reference

Complete Field Reference

FieldTypeDescription
accountstringUnique account identifier
namestringDisplay name
emailstringEmail address
statestringConnection state (see Account States)
syncTimenumberUnix timestamp of last sync
notifyFromstringISO date to send webhooks from
lastErrorobjectLast error details (if any)
imapobjectIMAP connection settings
smtpobjectSMTP connection settings
oauth2objectOAuth2 configuration
countersobjectMessage statistics

Account States

Detailed state descriptions:

init

  • Account just registered
  • No connection attempt made yet
  • Waiting for initial connection

connecting

  • Attempting to establish connection
  • Authenticating credentials
  • Retrieving mailbox list

connected

  • Successfully connected
  • Actively syncing messages
  • Healthy state

authenticationError

  • Invalid credentials
  • OAuth2 token expired
  • Action required: update credentials

connectError

  • Network connectivity issues
  • Mail server unavailable
  • Temporary state, will auto-retry

disconnected

  • Manually disconnected via API
  • Not syncing messages
  • Can be reconnected

Common Patterns

Bulk Account Registration

Register multiple accounts efficiently:

// Pseudo code: Register multiple accounts in parallel
function registerAccounts(accounts) {
results = []

// Process accounts in parallel
for each acc in accounts {
response = HTTP_POST("http://localhost:3000/v1/account", {
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: acc
})

result = PARSE_JSON(response.body)
results = results + [result]
}

return results
}

// Example usage
accounts = [
{ account: "user1@example.com", name: "User 1", imap: { /* ... */ } },
{ account: "user2@example.com", name: "User 2", imap: { /* ... */ } }
]

results = registerAccounts(accounts)
PRINT("Registered " + LENGTH(results) + " accounts")

Health Monitoring

Monitor account connection health:

// Pseudo code: Monitor account health
function checkAccountHealth() {
// Get all accounts
response = HTTP_GET("http://localhost:3000/v1/accounts", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})

accounts = PARSE_JSON(response.body).accounts

// Find unhealthy accounts
unhealthy = []
for each acc in accounts {
if (acc.state != "connected" AND acc.state != "connecting") {
unhealthy = unhealthy + [acc]
}
}

// Alert if issues found
if (LENGTH(unhealthy) > 0) {
PRINT("WARNING: Unhealthy accounts found")
for each acc in unhealthy {
PRINT(" - " + acc.account + ": " + acc.state)
}
// Send alerts, attempt reconnection, etc.
}

// Return summary
connected = FILTER(accounts, state == "connected")
return {
total: LENGTH(accounts),
connected: LENGTH(connected),
unhealthy: LENGTH(unhealthy)
}
}

// Run periodically (every 5 minutes)
SCHEDULE(checkAccountHealth, interval: 5 * 60 * 1000)

Credential Rotation

Update passwords programmatically:

// Pseudo code: Rotate account credentials
function rotateCredentials(account, newPassword) {
// Step 1: Update credentials
HTTP_PUT(
"http://localhost:3000/v1/account/" + URL_ENCODE(account),
{
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: {
imap: { auth: { pass: newPassword } },
smtp: { auth: { pass: newPassword } }
}
}
)

// Step 2: Force reconnection to apply new credentials
HTTP_PUT(
"http://localhost:3000/v1/account/" + URL_ENCODE(account) + "/reconnect",
{
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
}
)

PRINT("Credentials rotated and reconnected")
}

Account Synchronization Status

Track sync progress:

// Pseudo code: Get account sync status
function getSyncStatus(account) {
// Get account details
response = HTTP_GET(
"http://localhost:3000/v1/account/" + URL_ENCODE(account),
{
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
}
)

details = PARSE_JSON(response.body)

// Calculate status
currentTime = CURRENT_TIMESTAMP()
timeSinceSync = currentTime - details.syncTime
isHealthy = (details.state == "connected" AND details.lastError == null)

return {
state: details.state,
lastSync: details.syncTime,
timeSinceSync: timeSinceSync,
isHealthy: isHealthy
}
}

Error Handling

Common Errors

Account Already Exists:

{
"error": "Another account for the same OAuth2 user already exists",
"code": "AccountAlreadyExists",
"statusCode": 400
}

Solution: Use PUT to update existing account or choose different account ID.

Authentication Failed:

{
"error": "Authentication failed",
"code": "AuthenticationError",
"statusCode": 400
}

Solution: Verify credentials, check if 2FA/app passwords are required.

Account Not Found:

{
"error": "Account record was not found for requested ID",
"statusCode": 404
}

Solution: Verify account ID is correct and account exists.

Troubleshooting

For accounts stuck in error states:

  1. Check lastError field for details
  2. Verify credentials are current
  3. Test connection with manual reconnect
  4. Check mail server accessibility
  5. Review OAuth2 token expiration