accountDeleted
The accountDeleted webhook event is triggered when an email account is removed from EmailEngine. It is the final event in the account lifecycle and means the account configuration and its cached data have been deleted.
When This Event is Triggered
The accountDeleted event fires when:
- An account is deleted via the Delete Account API
- An account is removed through the admin interface
Both paths go through the same deletion routine. The account record, its stored credentials, mailbox listing, cached message index, queued outbound messages and access tokens are removed from Redis first, then the main process sends this webhook and tells the worker that held the connection to tear it down.
This is the one event that is still delivered for an account that no longer exists. Every other webhook is dropped when its account cannot be found at delivery time.
Payload Schema
Top-Level Fields
| Field | Type | Required | Description |
|---|---|---|---|
serviceUrl | string or null | Yes | The configured EmailEngine service URL. null when the serviceUrl setting is empty |
account | string | Yes | The account ID of the deleted account |
date | string | Yes | ISO 8601 timestamp when the webhook was generated |
event | string | Yes | Always accountDeleted |
data | object | Yes | Event data object |
Event Data Fields (data object)
| Field | Type | Required | Description |
|---|---|---|---|
account | string | Yes | The account ID, the same value as the top-level account field |
There is no event ID in the body. EmailEngine sends it in the X-EE-Wh-Event-Id request header, which is what to deduplicate on. See Delivery and Retries.
Example Payload
{
"serviceUrl": "https://emailengine.example.com",
"account": "user123",
"date": "2025-10-17T14:32:45.892Z",
"event": "accountDeleted",
"data": {
"account": "user123"
}
}
Example Payload (Without Service URL)
When no service URL is configured:
{
"serviceUrl": null,
"account": "gmail-user456",
"date": "2025-10-17T16:45:00.000Z",
"event": "accountDeleted",
"data": {
"account": "gmail-user456"
}
}
Handling the Event
A failed or timed-out delivery is retried, so the same event can arrive more than once. Make the handler tolerate an account that is already gone from your records:
async function handleAccountDeleted(event, headers) {
const { account, date } = event;
const eventId = headers['x-ee-wh-event-id'];
const accountRecord = await db.accounts.findUnique({
where: { emailEngineId: account }
});
if (!accountRecord) {
// Already removed by an earlier delivery of this event
return;
}
await db.accounts.delete({
where: { emailEngineId: account }
});
await auditLog.create({
event: 'account_deleted',
account,
timestamp: date,
eventId
});
}
Event Sequence
When an account is deleted, you receive only:
accountDeleted- Account is removed (this event)
No other events follow, because the account no longer exists. Events for the same account that were still queued when it was deleted are dropped rather than delivered.
Complete Account Lifecycle
A typical complete account lifecycle includes:
accountAdded- Account is registeredauthenticationSuccess- Account successfully authenticatesaccountInitialized- Initial mailbox sync is complete- (Account is active, various message and mailbox events may occur)
accountDeleted- Account is removed (final event)
Important Considerations
Data Already Deleted
When you receive the accountDeleted webhook, the account data has already been removed from EmailEngine. Get Account returns a 404 for it. If you need account metadata for cleanup purposes, store it in your own database when the account is created.
Timing
The webhook is queued as part of the deletion, so it arrives as soon as delivery succeeds. There is no delay between the deletion and the notification other than queue and network time.
Related Events
- accountAdded - Triggered when a new account is registered
- accountInitialized - Triggered when initial sync completes
- authenticationSuccess - Triggered when authentication succeeds
- authenticationError - Triggered when authentication fails
- connectError - Triggered when connection fails
See Also
- Webhooks Overview - Delivery, retries and the
webhookEventsallowlist - Account Management - Deleting accounts and what deletion removes
- Delete Account API - The request that triggers this event
- Get Account API - What to store before the account is gone