ImapFlow Client API

Complete API reference for the ImapFlow client class.
Constructor
new ImapFlow(options)
Creates a new IMAP client instance.
Parameters:
options(Object) - Configuration optionshost(String) - IMAP server hostname (required, defaults tolocalhost)port(Number) - Port number (defaults to 993 ifsecure: true, otherwise 110)secure(Boolean) - Iftrue, establishes the connection directly over TLS. Iffalse(default), uses plain TCP and may upgrade via STARTTLS unlessdoSTARTTLS: falseis set. Settingport: 993withoutsecureimpliessecure: true.doSTARTTLS(Boolean) - Force STARTTLS behavior.truerequires STARTTLS upgrade (fails if not supported),falsedisables STARTTLS entirely. Cannot be combined withsecure: true.servername(String) - Servername for SNI (for IP addresses or custom names)auth(Object) - Authentication credentialsuser(String) - Usernamepass(String) - PasswordaccessToken(String) - OAuth2 access token (alternative to pass)loginMethod(String) - Optional override: 'LOGIN', 'AUTH=LOGIN', or 'AUTH=PLAIN'authzid(String) - Authorization identity for SASL PLAIN (admin impersonation)
logger(Object|Boolean) - Logger instance or false to disabletls(Object) - Additional TLS optionsproxy(String) - Proxy URL (socks://, socks4://, socks5://, http://)clientInfo(Object) - Client identification for ID extensiondisableAutoIdle(Boolean) - Disable automatic IDLE modedisableCompression(Boolean) - Disable COMPRESS=DEFLATEdisableBinary(Boolean) - Disable BINARY extensiondisableAutoEnable(Boolean) - Do not auto-enable extensionsqresync(Boolean) - Enable QRESYNC supportmaxIdleTime(Number) - Restart IDLE after this many msmissingIdleCommand(String) - Command if IDLE unsupported: 'NOOP', 'SELECT', or 'STATUS'connectionTimeout(Number) - Connection timeout in ms (default: 90000)greetingTimeout(Number) - Greeting timeout in ms (default: 16000)socketTimeout(Number) - Socket inactivity timeout in ms (default: 300000)emitLogs(Boolean) - Emit log events instead of logginglogRaw(Boolean) - Log raw socket data in base64verifyOnly(Boolean) - Connect and disconnect immediatelyincludeMailboxes(Boolean) - With verifyOnly, also list mailboxesexpungeHandler(Function) - Custom EXPUNGE event handlerid(String) - Custom instance ID for logs
Returns: ImapFlow instance
Example:
const client = new ImapFlow({
host: 'imap.example.com',
port: 993,
secure: true,
auth: {
user: 'user@example.com',
pass: 'password'
}
});
Connection Methods
connect()
Establishes connection to the IMAP server and authenticates.
Returns: Promise<void>
Example:
await client.connect();
console.log('Connected and authenticated');
logout()
Closes the connection to the IMAP server gracefully using LOGOUT command.
Returns: Promise<void>
Example:
await client.logout();
close()
Closes the connection immediately without sending LOGOUT.
Returns: void
Example:
client.close();
closeAfter()
Schedules close() to run via setImmediate(), returning immediately so the caller can complete its current synchronous flow before the socket is torn down. Useful inside error handlers where calling close() directly would interfere with the rest of the function.
Returns: void
Example:
// Non-blocking close
client.closeAfter();
stats(reset)
Returns byte counters for the current connection.
Parameters:
reset(Boolean) - Iftrue, the counters are reset to zero after reading.
Returns: { sent: number, received: number }
Example:
let { sent, received } = client.stats();
console.log(`Sent ${sent} bytes, received ${received} bytes`);
unbind()
Detaches the underlying sockets from the IMAP pipeline and returns the read and write sockets. After calling this, ImapFlow no longer interacts with the connection.
Returns: { readSocket, writeSocket }
noop()
Sends NOOP command to keep connection alive.
Returns: Promise<void>
Example:
await client.noop();
idle()
Enters IDLE mode to wait for server notifications. Automatically called when disableAutoIdle is false.
Returns: Promise<boolean>
Example:
// Manually enter IDLE
await client.idle();
upgradeToSTARTTLS()
Upgrades the current connection to TLS using STARTTLS. This is typically called automatically when secure: false and the server supports STARTTLS.
Returns: Promise<Boolean> - Returns true if upgrade succeeded, false if already using TLS or STARTTLS not supported.
Example:
// Manual STARTTLS upgrade (usually not needed)
const upgraded = await client.upgradeToSTARTTLS();
if (upgraded) {
console.log('Connection upgraded to TLS');
}
Mailbox Methods
getMailboxLock(path, options)
Selects a mailbox and acquires a lock for safe operations. Recommended over mailboxOpen() for transactional safety.
Parameters:
path(String|Array) - Mailbox path (e.g., 'INBOX', ['INBOX', 'Subfolder'])options(Object) - Optional settingsreadOnly(Boolean) - Open in read-only modedescription(String) - Description for debugging/logging
Returns: Promise<MailboxLockObject>
path(String) - Opened mailbox pathrelease()- Function to release the lock
Example:
let lock = await client.getMailboxLock('INBOX');
try {
// Perform operations safely
console.log('Messages:', client.mailbox.exists);
} finally {
lock.release();
}
mailboxOpen(path, options)
Opens a mailbox directly without locking. Use getMailboxLock() for safer operations.
Parameters:
path(String|Array) - Mailbox pathoptions(Object) - Optional settingsreadOnly(Boolean) - Open in read-only mode (uses IMAPEXAMINEinstead ofSELECT)description(String) - Optional description used in lock-tracking trace logs
Returns: Promise<MailboxObject>
mailboxClose()
Closes the currently open mailbox.
Returns: Promise<Boolean>
list(options)
Lists available mailboxes.
Parameters:
options(Object) - Optional settingsstatusQuery(Object) - Request status for each mailboxmessages(Boolean) - Include message countrecent(Boolean) - Include recent countuidNext(Boolean) - Include next UIDuidValidity(Boolean) - Include UIDVALIDITYunseen(Boolean) - Include unseen counthighestModseq(Boolean) - Include highest modseq
specialUseHints(Object) - Hints for special-use folderssent(String) - Path to Sent foldertrash(String) - Path to Trash folderjunk(String) - Path to Junk folderdrafts(String) - Path to Drafts folder
Returns: Promise<Array<ListResponse>>
Example:
let mailboxes = await client.list();
for (let mailbox of mailboxes) {
console.log(mailbox.path, mailbox.specialUse || '');
}
// With status query
let mailboxes = await client.list({
statusQuery: { messages: true, unseen: true }
});
listTree(options)
Gets mailboxes organized as a tree structure.
Parameters:
options(Object) - Same as list()
Returns: Promise<ListTreeResponse>
Example:
let tree = await client.listTree();
function printTree(node, indent = '') {
if (node.path) {
console.log(indent + node.name);
}
if (node.folders) {
for (let folder of node.folders) {
printTree(folder, indent + ' ');
}
}
}
printTree(tree);
mailboxCreate(path)
Creates a new mailbox.
Parameters:
path(String|Array) - Path for the new mailbox
Returns: Promise<MailboxCreateResponse>
path(String) - Full mailbox pathmailboxId(String) - Unique ID (if OBJECTID extension)created(Boolean) - True if created, false if already existed
Example:
let result = await client.mailboxCreate('Projects/2024');
console.log('Created:', result.created);
mailboxRename(oldPath, newPath)
Renames a mailbox.
Parameters:
oldPath(String|Array) - Current mailbox pathnewPath(String|Array) - New mailbox path
Returns: Promise<MailboxRenameResponse>
Example:
await client.mailboxRename('Old', 'New');
mailboxDelete(path)
Deletes a mailbox and all its messages.
Parameters:
path(String|Array) - Mailbox path to delete
Returns: Promise<MailboxDeleteResponse>
Example:
await client.mailboxDelete('Temporary');
mailboxSubscribe(path)
Subscribes to a mailbox.
Parameters:
path(String|Array) - Mailbox path
Returns: Promise<Boolean>
mailboxUnsubscribe(path)
Unsubscribes from a mailbox.
Parameters:
path(String|Array) - Mailbox path
Returns: Promise<Boolean>
status(path, query)
Gets mailbox status without selecting it.
Parameters:
path(String) - Mailbox pathquery(Object) - Status items to fetchmessages(Boolean) - Total message countrecent(Boolean) - Recent message countuidNext(Boolean) - Next UID valueuidValidity(Boolean) - UIDVALIDITY valueunseen(Boolean) - Unseen message counthighestModseq(Boolean) - Highest modseq value
Returns: Promise<StatusObject>
Example:
let status = await client.status('INBOX', {
messages: true,
unseen: true,
highestModseq: true
});
console.log(`${status.unseen}/${status.messages} unseen`);
getQuota(path)
Gets quota information for a mailbox. Defaults to INBOX if no path is provided.
Parameters:
path(String) - Optional mailbox path (defaults to'INBOX')
Returns: Promise<QuotaResponse|false> - false if the server does not support the QUOTA extension or the path does not exist
Example:
let quota = await client.getQuota('INBOX');
if (quota && quota.storage) {
console.log(`Used: ${quota.storage.used}/${quota.storage.limit} bytes`);
}
Message Fetch Methods
fetch(range, query, options)
Fetches messages from the currently selected mailbox. Returns an async iterator.
Do not run any other IMAP commands inside the fetch loop. This will cause a deadlock. Use fetchAll() if you need to process messages after fetching.
Parameters:
range(String|Array|SearchObject) - Message range or search query- String: '1:10', '1:', ':-10'
- Array: [1, 2, 3, 10]
- SearchObject:
{ seen: false }
query(FetchQueryObject) - Fetch query optionsuid(Boolean) - Include UIDflags(Boolean) - Include flagsenvelope(Boolean) - Include envelopebodyStructure(Boolean) - Include MIME structureinternalDate(Boolean) - Include internal datesize(Boolean) - Include message sizesource(Boolean|Object) - Include message sourceheaders(Boolean|Array) - Include headersbodyParts(Array) - Include specific body partsthreadId(Boolean) - Include thread IDlabels(Boolean) - Include Gmail labelsfast(Boolean) - Macro: flags, internalDate, sizeall(Boolean) - Macro: fast + envelopefull(Boolean) - Macro: all + bodyStructure
options(Object) - Additional optionsuid(Boolean) - Range contains UIDschangedSince(BigInt) - Only messages with higher modseqbinary(Boolean) - Request binary response
Returns: AsyncGenerator<FetchMessageObject>
Example:
for await (let message of client.fetch('1:*', {
envelope: true,
flags: true
})) {
console.log(message.uid, message.envelope.subject);
}
fetchAll(range, query, options)
Fetches all messages and returns an array. Safer for processing but uses more memory.
Parameters: Same as fetch()
Returns: Promise<Array<FetchMessageObject>>
Example:
let messages = await client.fetchAll('1:100', { envelope: true });
for (let message of messages) {
await client.messageFlagsAdd(message.uid, ['\\Seen'], { uid: true });
}
fetchOne(seq, query, options)
Fetches a single message.
Parameters:
seq(String|Number) - Sequence number or UID, or '*' for latestquery(FetchQueryObject) - Fetch query optionsoptions(Object) - Additional optionsuid(Boolean) - seq is a UIDbinary(Boolean) - Request binary response
Returns: Promise<FetchMessageObject|Boolean>
Example:
let message = await client.fetchOne('*', {
envelope: true,
source: true
});
if (message) {
console.log(message.envelope.subject);
}
download(range, part, options)
Downloads a message or specific body part as a stream.
Parameters:
range(String|Number) - Message sequence number or UIDpart(String) - Body part identifier (optional, omit for full message)options(Object) - Download optionsuid(Boolean) - Range is a UIDmaxBytes(Number) - Maximum bytes to downloadchunkSize(Number) - Chunk size (default: 65536)
Returns: Promise<DownloadObject>
meta(Object) - Content metadataexpectedSize(Number) - Expected sizecontentType(String) - Content-Typecharset(String) - Character setdisposition(String) - Content-Dispositionfilename(String) - Filenameencoding(String) - Transfer encoding
content(ReadableStream) - Streamed content
Example:
let { meta, content } = await client.download(12345, '2', { uid: true });
console.log('Downloading:', meta.filename);
const fs = require('fs');
content.pipe(fs.createWriteStream(meta.filename));
downloadMany(range, parts, options)
Downloads multiple body parts as Buffers.
Parameters:
range(String|Number) - Message sequence number or UIDparts(Array) - Array of part identifiersoptions(Object) - Download optionsuid(Boolean) - Range is a UID
Returns: Promise<Object> - Object with part IDs as keys
Example:
let parts = await client.downloadMany(12345, ['1', '2', '3'], { uid: true });
for (let [id, data] of Object.entries(parts)) {
console.log(`Part ${id}:`, data.meta.contentType);
}
Search Methods
search(query, options)
Searches for messages in the currently selected mailbox.
Parameters:
query(SearchObject) - Search criteriaseq(String) - Sequence rangeuid(String) - UID rangeanswered(Boolean) - Has \Answered flagdeleted(Boolean) - Has \Deleted flagdraft(Boolean) - Has \Draft flagflagged(Boolean) - Has \Flagged flagseen(Boolean) - Has \Seen flagall(Boolean) - All messagesnew(Boolean) - Recent but unseenold(Boolean) - Not recentrecent(Boolean) - Has \Recent flagfrom(String) - From address containsto(String) - To address containscc(String) - Cc address containsbcc(String) - Bcc address containssubject(String) - Subject containsbody(String) - Body containslarger(Number) - Size larger than bytessmaller(Number) - Size smaller than bytesbefore(Date|String) - Internal date beforeon(Date|String) - Internal date onsince(Date|String) - Internal date sincesentBefore(Date|String) - Sent date beforesentOn(Date|String) - Sent date onsentSince(Date|String) - Sent date sincekeyword(String) - Has custom keywordunKeyword(String) - Does not have keywordheader(Object) - Header field matchesmodseq(BigInt) - Modified since modseqemailId(String) - Email ID (OBJECTID extension)threadId(String) - Thread ID (OBJECTID extension)or(Array) - OR of search criterianot(SearchObject) - Negationgmraw(String) - Gmail raw search querygmailraw(String) - Alias for gmraw
options(Object) - Search optionsuid(Boolean) - Return UIDs instead of sequence numbersreturnOptions(Array) - Request ESEARCH (RFC 4731) result. Each entry is one of'MIN','MAX','COUNT','ALL', or{ partial: '1:100' }(RFC 9394). When provided, returns anESearchResultinstead of a plain array (the client falls back to derivingmin/max/count/allif the server lacks ESEARCH).
Returns: Promise<Number[] | ESearchResult | false>
Example:
// Simple search
let uids = await client.search({ seen: false }, { uid: true });
// Complex search
let uids = await client.search({
or: [
{ from: 'alice@example.com' },
{ from: 'bob@example.com' }
],
since: new Date('2024-01-01'),
larger: 10000
}, { uid: true });
// Gmail raw search
let uids = await client.search({
gmraw: 'has:attachment larger:5M'
}, { uid: true });
// ESEARCH: get only the count and highest matching UID
let result = await client.search({ seen: false }, {
uid: true,
returnOptions: ['COUNT', 'MAX']
});
console.log(result.count, result.max);
Message Manipulation Methods
messageDelete(range, options)
Deletes messages by marking them as deleted and expunging.
Parameters:
range(String|Array|SearchObject) - Message range or searchoptions(Object) - Optionsuid(Boolean) - Range contains UIDs
Returns: Promise<Boolean>
Example:
await client.messageDelete('1:10', { uid: true });
messageCopy(range, destination, options)
Copies messages to another mailbox.
Parameters:
range(String|Array|SearchObject) - Message range or searchdestination(String|Array) - Destination mailbox pathoptions(Object) - Optionsuid(Boolean) - Range contains UIDs
Returns: Promise<CopyResponseObject>
path(String) - Destination pathuidValidity(BigInt) - Destination UIDVALIDITYuidMap(Map) - Mapping of source UIDs to destination UIDs
Example:
let result = await client.messageCopy('1:10', 'Archive', { uid: true });
console.log('Copied to UIDs:', result.uidMap);
messageMove(range, destination, options)
Moves messages to another mailbox.
Parameters:
range(String|Array|SearchObject) - Message range or searchdestination(String|Array) - Destination mailbox pathoptions(Object) - Optionsuid(Boolean) - Range contains UIDs
Returns: Promise<CopyResponseObject|Boolean>
Example:
await client.messageMove('1:10', 'Spam', { uid: true });
messageFlagsAdd(range, flags, options)
Adds flags to messages.
Parameters:
range(String|Array|SearchObject) - Message range or searchflags(String[]) - Flags to add (e.g.,['\\Seen', '\\Flagged', 'custom'])options(Object) - Optionsuid(Boolean) - Range contains UIDsunchangedSince(BigInt) - Only if modseq has not changed since (CONDSTORE)useLabels(Boolean) - Iftrue, modify Gmail labels instead of flags (requiresX-GM-EXT-1)silent(Boolean) - Iftrue, do not emit aflagsevent for this update
Returns: Promise<Boolean>
Example:
await client.messageFlagsAdd([100, 200, 300], ['\\Seen'], { uid: true });
messageFlagsRemove(range, flags, options)
Removes flags from messages.
Parameters:
range(String|Array|SearchObject) - Message range or searchflags(String[]) - Flags to removeoptions(Object) - Optionsuid(Boolean) - Range contains UIDsunchangedSince(BigInt) - Only if modseq has not changed since (CONDSTORE)useLabels(Boolean) - Iftrue, remove Gmail labels instead of flagssilent(Boolean) - Iftrue, do not emit aflagsevent for this update
Returns: Promise<Boolean>
Example:
await client.messageFlagsRemove('1:*', ['\\Seen'], { uid: true });
messageFlagsSet(range, flags, options)
Sets exact flags for messages, replacing existing flags.
Parameters:
range(String|Array|SearchObject) - Message range or searchflags(String[]) - Flags to setoptions(Object) - Optionsuid(Boolean) - Range contains UIDsunchangedSince(BigInt) - Only if modseq has not changed since (CONDSTORE)useLabels(Boolean) - Iftrue, replace Gmail labels instead of flagssilent(Boolean) - Iftrue, do not emit aflagsevent for this update
Returns: Promise<Boolean>
Example:
await client.messageFlagsSet('12345', ['\\Seen', '\\Flagged'], { uid: true });
setFlagColor(range, color, options)
Sets the flag color for messages using special color flags.
Parameters:
range(String|Array|SearchObject) - Message rangecolor(String) - Color name:'red','orange','yellow','green','blue','purple','grey', or a falsy value to remove the coloroptions(Object) - Optionsuid(Boolean) - Range contains UIDsunchangedSince(BigInt) - Only update if modseq has not changed since this value (CONDSTORE)
Returns: Promise<Boolean>
Example:
await client.setFlagColor('12345', 'red', { uid: true });
Gmail Labels
Gmail labels are managed via the regular flag methods (messageFlagsAdd, messageFlagsRemove, messageFlagsSet) by passing useLabels: true in the options. There are no dedicated label methods. This requires the server to support the X-GM-EXT-1 extension.
Example:
// Add a Gmail label
await client.messageFlagsAdd('12345', ['MyLabel'], { uid: true, useLabels: true });
// Remove a Gmail label
await client.messageFlagsRemove('12345', ['OldLabel'], { uid: true, useLabels: true });
// Replace all labels for a message
await client.messageFlagsSet('12345', ['Inbox', 'Important'], { uid: true, useLabels: true });
Append Methods
append(path, content, flags, idate)
Appends a message to a mailbox.
Parameters:
path(String|Array) - Destination mailboxcontent(String|Buffer|Readable) - Message content (RFC822 format)flags(Array) - Optional flagsidate(Date) - Optional internal date
Returns: Promise<AppendResponseObject | false>
path(String) - Mailbox pathuid(Number) - UID of appended message (if UIDPLUS extension)uidValidity(BigInt) - Mailbox UIDVALIDITYseq(Number) - Sequence number
Example:
let message = `From: sender@example.com
To: recipient@example.com
Subject: Test Message
Date: ${new Date().toUTCString()}
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Hello, World!`;
let result = await client.append('INBOX', message, ['\\Seen']);
console.log('Appended as UID:', result.uid);
Events
Event: 'error'
Emitted when an error occurs.
client.on('error', (err) => {
console.error('IMAP error:', err.message);
console.error('Code:', err.code);
});
Event: 'close'
Emitted when connection is closed. ImapFlow does not auto-reconnect.
client.on('close', () => {
console.log('Connection closed');
// Implement your own reconnection logic here
});
Event: 'mailboxOpen'
Emitted when a mailbox is opened.
client.on('mailboxOpen', (mailbox) => {
console.log('Opened:', mailbox.path);
console.log('Messages:', mailbox.exists);
console.log('UIDVALIDITY:', mailbox.uidValidity);
});
Event: 'mailboxClose'
Emitted when a mailbox is closed.
client.on('mailboxClose', (mailbox) => {
console.log('Closed:', mailbox.path);
});
Event: 'exists'
Emitted when message count changes in the currently open mailbox.
client.on('exists', (data) => {
console.log('Path:', data.path);
console.log('New count:', data.count);
console.log('Previous count:', data.prevCount);
});
Event: 'expunge'
Emitted when a message is deleted from the currently open mailbox.
client.on('expunge', (data) => {
console.log('Path:', data.path);
console.log('Sequence:', data.seq);
// If QRESYNC enabled:
console.log('UID:', data.uid);
});
Event: 'flags'
Emitted when message flags change in the currently open mailbox.
client.on('flags', (data) => {
console.log('Path:', data.path);
console.log('Sequence:', data.seq);
console.log('UID:', data.uid);
console.log('Flags:', data.flags);
console.log('Modseq:', data.modseq);
});
Event: 'response'
Emitted when a tagged response is received from the server.
client.on('response', (response) => {
console.log('Response:', response.response);
if (response.code) {
console.log('Code:', response.code);
}
});
Event: 'log'
Emitted when emitLogs: true. Contains log entries.
client.on('log', (entry) => {
console.log(`[${entry.level}] ${entry.msg}`);
});
Properties
mailbox
Currently selected mailbox information.
Type: MailboxObject | null
let lock = await client.getMailboxLock('INBOX');
try {
console.log('Path:', client.mailbox.path);
console.log('Messages:', client.mailbox.exists);
console.log('UIDVALIDITY:', client.mailbox.uidValidity);
console.log('Next UID:', client.mailbox.uidNext);
console.log('Flags:', client.mailbox.flags);
console.log('Permanent Flags:', client.mailbox.permanentFlags);
console.log('Highest Modseq:', client.mailbox.highestModseq);
console.log('Read-only:', client.mailbox.readOnly);
} finally {
lock.release();
}
authenticated
The authenticated username, or false if not authenticated.
Type: string | boolean
secureConnection
Whether the connection is currently encrypted.
Type: Boolean
usable
Whether the connection is usable (connected and authenticated).
Type: Boolean
capabilities
Map of server capabilities reported by the server. Keys are capability names, values are typically true or, for capabilities like APPENDLIMIT, a numeric value.
Type: Map<string, boolean | number>
enabled
Set of IMAP extensions that have been activated for this connection (via the ENABLE command).
Type: Set<string>
host
Hostname the client is connecting to.
Type: String
port
Port number the client is connecting to.
Type: Number
serverInfo
Server identification (from ID extension).
Type: Object | null
id
Connection instance ID.
Type: String
idling
Whether currently in IDLE mode.
Type: Boolean
Type Definitions
For detailed TypeScript type definitions, see the included lib/imap-flow.d.ts file in the package.
FetchMessageObject
| Property | Type | Description |
|---|---|---|
| seq | Number | Sequence number |
| uid | Number | Unique identifier |
| modseq | BigInt | Modification sequence |
| emailId | String | Email ID (OBJECTID) |
| threadId | String | Thread ID |
| labels | Set | Gmail labels |
| size | Number | Message size |
| flags | Set | Message flags |
| flagColor | String | Flag color |
| envelope | Object | Envelope data |
| bodyStructure | Object | MIME structure |
| internalDate | Date | Internal date |
| source | Buffer | Raw message |
| headers | Buffer | Raw headers |
| bodyParts | Map | Body parts |
MailboxObject
| Property | Type | Description |
|---|---|---|
| path | String | Mailbox path |
| delimiter | String | Path delimiter |
| flags | Set | Mailbox flags |
| specialUse | String | Special-use flag |
| permanentFlags | Set | Allowed flags |
| mailboxId | String | Mailbox ID (OBJECTID) |
| highestModseq | BigInt | Highest modseq |
| uidValidity | BigInt | UIDVALIDITY |
| uidNext | Number | Next UID |
| exists | Number | Message count |
| readOnly | Boolean | Read-only mode |