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 →


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