Protocols and limits

Every SMTP, IMAP, POP3, JMAP, ManageSieve and HTTPS extension Nixt Server offers, and every built-in ceiling, timeout and connection limit.

SMTP

Extensions

ExtensionPort 25 (mx)Ports 587 and 465 (submission)
PIPELININGYesYes
SIZEYesYes
8BITMIMEYesYes
SMTPUTF8YesYes
ENHANCEDSTATUSCODESYesYes
DSNYesYes
CHUNKING and BINARYMIMEYesYes
LIMITS RCPTMAX=… MAILMAX=…YesYes
STARTTLSBefore TLSPort 587, before TLS
REQUIRETLSAfter TLSAfter TLS
AUTH PLAIN LOGIN SCRAM-SHA-256 OAUTHBEARER XOAUTH2NeverAfter TLS, until signed in
BURL imapNeverYes
FUTURERELEASE 2592000 <date>NeverYes: HOLDFOR and HOLDUNTIL on MAIL, up to 30 days; see Sending later
HELPYesYes

Commands: EHLO, HELO, STARTTLS, AUTH, MAIL, RCPT, DATA, BDAT, BURL, RSET, NOOP, VRFY (always 252), HELP, QUIT. EXPN, ETRN and ATRN answer 502.

Ceilings

CeilingValueChangeable
Message size25 MiB (26,214,400 bytes)Lower only: [limits] message_size, limits.message_size
Recipients per message100Lower only: [limits] recipients, limits.recipients
Messages per connection100No
Command line4,096 bytesNo
Line of message data8,192 bytesNo
Reply line sent512 bytesNo
One BDAT chunk1 MiBNo
Commands per session1,000No
Bad commands before closing10No
Failed AUTH before closing3No
Header fields per message1,000No
Header section64 KiBNo
One header field8 KiBNo
MIME nesting depth32No
MIME parts per message1,000No
Addresses in one header1,000No
Local part of an address64 bytesNo
Domain255 bytesNo
Whole address path512 bytesNo

Connections

Port 25Submission
Connections at once1,0001,000
From one address2050
From one network200200
Pause before the greeting2 secondsNone
Idle time between commands5 minutes10 minutes
Whole session1 hour1 hour

A network is an IPv4 /24 or an IPv6 /48. Every mail listener’s ceilings can be changed, and rates added, in its [listeners.<name>] table.

IMAP

The server speaks IMAP4rev2 (RFC 9051) and IMAP4rev1, and advertises both. Its capabilities:

CapabilityWhat it lets an app do
STARTTLS, LOGINDISABLEDBefore TLS on port 143 only.
AUTH=SCRAM-SHA-256, AUTH=PLAIN, AUTH=LOGIN, AUTH=OAUTHBEARER, AUTH=XOAUTH2Sign in. Only SCRAM-SHA-256 is offered before TLS.
SASL-IRSend the first sign-in step with AUTHENTICATE.
ENABLETurn on extensions such as CONDSTORE, QRESYNC and UTF8=ACCEPT.
IDLEBe told of changes as they happen.
NOTIFYBe told of changes in other folders as well as the open one, without opening each.
LITERAL+Send literals without waiting.
UIDONLYOnce enabled, work with UIDs only (RFC 9586): message numbers are refused with UIDREQUIRED, fetches answer as UIDFETCH and removals as VANISHED, which saves memory in large mailboxes.
UIDBATCHESThe UID ranges that divide the open mailbox into batches of a chosen size, newest first (RFC 10022), at least 500 messages a batch and at most 100,000 messages in one request for a range of batches.
PARTIALA page of a search or a UID FETCH by position, counted from the oldest (1:50) or the newest (-1:-50) (RFC 9394).
BINARYFetch and append parts without transfer encoding.
MOVEMove messages in one command.
UIDPLUSLearn the UIDs of appended, copied and moved messages.
UNSELECTClose a mailbox without expunging.
NAMESPACEDiscover the folder namespaces: your own, and Other Users/ for mail you are a delegate for.
IDExchange client and server identification.
QUOTAAsk about storage limits: the mailbox’s size and number of messages against its ceilings (STORAGE and MESSAGE).
UTF8=ACCEPTUse UTF-8 in folder names and messages.
SORT, SORT=DISPLAYSort on the server, including by display name.
THREAD=REFERENCES, THREAD=ORDEREDSUBJECTThread on the server.
ESEARCH, ESORT, CONTEXT=SEARCH, CONTEXT=SORTCompact search results, partial results and updating searches.
SEARCHRESSave a search result and use it as $.
MULTIAPPENDAppend several messages at once.
CATENATEBuild a message from parts already on the server.
REPLACEReplace a message, such as a draft, in one step.
STATUS=SIZEAsk a folder’s size.
CONDSTORE, QRESYNCResynchronise quickly: only what changed, and what vanished.
SPECIAL-USEFind Drafts, Sent, Junk, Trash and Archive by use, and Scheduled and Snoozed (\Scheduled and \Snoozed, RFC 9979) once they are made.
LIST-EXTENDED, LIST-STATUSRicher folder listings, with counts in one command.
OBJECTIDStable ids for folders, messages and threads, the same as JMAP’s.
PREVIEWA message’s first words.
SAVEDATEWhen a message arrived in its current folder.
ACL, RIGHTS=texkAsk what you may do in a folder, and see who else may read your mail.
URLAUTH, URLAUTH=BINARYMake signed URLs to messages, for BURL.
UNAUTHENTICATESign out without disconnecting. Offered after signing in.
METADATAFolder and server annotations.
COMPRESS=DEFLATECompress the connection.
LimitValue
Connections at once2,000
From one address30
From one network200
Idle time31 minutes
One command, including an appended message32 MiB
Commands per connection100,000
Failed sign-ins before closing3
Unparseable commands before closing10

POP3

CapabilityMeaning
STLSBefore TLS on port 110.
UIDLStable message identifiers.
TOPFetch headers and the first lines.
PIPELININGSend commands together.
RESP-CODESMachine-readable response codes.
EXPIRE NEVERThe server never deletes mail on its own.
UTF8 USERUTF-8 user names and passwords.
LANGLanguage negotiation for response texts.
IMPLEMENTATION Nixt Server <version>The server’s name and version.
USERAfter TLS.
SASL <mechanisms>Mechanisms that send no password before TLS, all of them after.

POP3 serves the Inbox only.

LimitValue
Connections at once500
From one address20
From one network200
Idle time15 minutes
Whole session1 hour

ManageSieve

Port 4190 with STARTTLS: 500 connections at once, 20 from one address and 200 from one network. Capabilities: IMPLEMENTATION, VERSION 1.0, SIEVE with every supported extension, SASL after TLS, STARTTLS before it, NOTIFY mailto, MAXREDIRECTS 4, UNAUTHENTICATE. Limits are on Sieve filters and vacation replies.

JMAP

Capabilities

CapabilityServer-level values
urn:ietf:params:jmap:coremaxSizeUpload 26,214,400 (as large as a message); maxConcurrentUpload 4; maxSizeRequest 10,485,760; maxConcurrentRequests 8, each per person, and a request past them is answered with the limit error; maxCallsInRequest 64; maxObjectsInGet 500; maxObjectsInSet 500; collationAlgorithms i;octet and i;ascii-casemap
urn:ietf:params:jmap:mailPer account: maxMailboxesPerEmail null, maxMailboxDepth null, maxSizeMailboxName 200, maxSizeAttachmentsPerEmail 50,000,000, emailQuerySortOptions receivedAt, size, from, to, subject, sentAt, hasKeyword, allInThreadHaveKeyword and someInThreadHaveKeyword, mayCreateTopLevelMailbox true
urn:ietf:params:jmap:submissionSending. Per account: maxDelayedSend 2,592,000 (30 days), and submissionExtensions with FUTURERELEASE, so HOLDFOR and HOLDUNTIL may be given; see Sending later.
urn:ietf:params:jmap:vacationresponseOut-of-office replies.
urn:ietf:params:jmap:quotaHow full the person’s own mailbox is (RFC 9425): Quota/get, /changes, /query and /queryChanges, the same numbers IMAP GETQUOTA gives.
https://nixtoffice.com/docs/server/jmap-sender-listThe senders a person allows and blocks for themselves; see JMAP sender lists.
https://nixtoffice.com/docs/server/jmap-snoozeSnoozing a message until a time; see JMAP snooze.
urn:ietf:params:jmap:sieveThe person’s Sieve scripts, the ones ManageSieve keeps (RFC 9661). Server-level implementation “Nixt Server Sieve”; per account, the script and name size limits, the quota, the redirect limit and every extension.
urn:ietf:params:jmap:blobBlob management (RFC 9404). Per account: maxSizeBlobSet (the upload limit), maxDataSources 64, supportedTypeNames Mailbox, Thread and Email, supportedDigestAlgorithms sha and sha-256.
urn:ietf:params:jmap:mdnRead receipts (RFC 9007): MDN/send answers a message that asked for a receipt, and MDN/parse reads one. A receipt goes from the person’s own identity, to the address the message named, and the client must mark the message $mdnsent in the same request. The organisation’s mdn.send setting says how far receipts may go.
urn:ietf:params:jmap:websocketurl wss://<host>/jmap/ws/, supportsPush true
urn:ietf:params:jmap:webpush-vapidapplicationServerKey, the server’s VAPID public key (RFC 9749), which an app gives its platform when it asks for a push address; see Push to phones.

Methods

GroupMethods
CoreCore/echo, Blob/copy
MailboxesMailbox/get, Mailbox/changes, Mailbox/query, Mailbox/queryChanges, Mailbox/set
ThreadsThread/get, Thread/changes
MessagesEmail/get, Email/changes, Email/query, Email/queryChanges, Email/set, Email/parse, Email/import, Email/copy, SearchSnippet/get
IdentitiesIdentity/get, Identity/changes, Identity/set (changing an identity’s details)
SendingEmailSubmission/get, EmailSubmission/changes, EmailSubmission/query, EmailSubmission/set
Out of officeVacationResponse/get, VacationResponse/set
RulesSieveScript/get, SieveScript/set, SieveScript/query, SieveScript/validate
BlobsBlob/upload, Blob/get, Blob/lookup
PushPushSubscription/get, PushSubscription/set

Push to phones

A phone app can hear about new mail while it is closed. It registers a push subscription (RFC 8620 §7.2) with PushSubscription/set, giving the https: push address its platform handed it and its encryption keys. The server then sends Web Push (RFC 8030) to that address.

  • A new subscription first gets a PushVerification with a code. Nothing else is sent until the app sets verificationCode to that code.
  • After that, each change to the account sends a StateChange naming the data types that changed and their new states. Message content never travels in a push; the app fetches what it needs over JMAP.
  • Every push is encrypted for the device (RFC 8291, aes128gcm) and signed with the server’s VAPID key (RFC 8292). Apps find the public key in the session, under urn:ietf:params:jmap:webpush-vapid.
  • Changes within a few seconds of each other become one push.
  • An account can have up to 20 subscriptions. Each lasts at most 7 days; apps renew one by updating its expires.
  • A push address that answers that it is gone (404 or 410) ends its subscription. A subscription also ends when the sign-in that made it ends.
  • Push addresses must be public https: hosts: the server does not send pushes into a private network.

Changes and resynchronising

Apps that keep mail on the device ask what changed since the state they last saw: JMAP’s /changes and /queryChanges methods, and IMAP’s NOTIFY. The server keeps each account’s record of changes for 30 days, and at least the last 100,000 changes, whichever is more. The operator can change both with the changes.keep_days and changes.keep_count settings.

An app that has been away for longer is told so. JMAP answers cannotCalculateChanges, and IMAP NOTIFY reports every folder as changed. The app then reads the folder list and the message list again, as it did when the account was first added. Nothing is lost: it only reads again what it already had.

Endpoints

PathPurpose
/.well-known/jmapThe session.
/jmap/api/Method calls.
/jmap/upload/{accountId}/Upload.
/jmap/download/{accountId}/{blobId}/{name}?accept={type}Download.
/jmap/eventsource/?types={types}&closeafter={closeafter}&ping={ping}Push over EventSource.
/jmap/ws/WebSocket, with the jmap subprotocol.

Every endpoint needs a bearer token for the versealx-jmap audience.

CalDAV and CardDAV

ItemValue
MethodsOPTIONS, HEAD, GET, PUT, DELETE, POST, PROPFIND, PROPPATCH, REPORT, MKCOL, MKCALENDAR, ACL
Discovery/.well-known/caldav and /.well-known/carddav redirect to /dav/
Access controlRFC 3744. Every resource names its owner and says what the asker may do (current-user-privilege-set), from the privileges it supports (supported-privilege-set). Its access list (acl) is read and set by its owner only. A calendar or address book is its owner’s, and reachable by whoever its owner shared it with and by a delegate who manages the owner’s calendars; everybody signed in may read the collections that lead to them. A request refused for want of a privilege names it in DAV:need-privileges.
SchedulingRFC 6638, done by the server: an event with attendees saved in a calendar is carried to each of them. RFC 5546 messages; by mail, RFC 6047.
SharingRFC 3744 ACL on a calendar or an address book, and CalendarServer’s CS:share with CS:invite-reply.
Busy timeThe scheduling outbox’s VFREEBUSY request (RFC 6638), with RFC 7953 availability.
Access reportsexpand-property, acl-principal-prop-set, principal-match, principal-property-search and principal-search-property-set
Finding peopleprincipal-property-search finds people in your own organisation who can sign in, by any part of their name or address, from two characters on, 50 at a time.
Calendars or address books per account200 of each
Items per collection100,000
Octets per collection64 MiB
One item10 MiB
Recurrence instances per request5,000
Widest time range10 years
Dates accepted1901 to 2100
Attendees per instance250
Results per report5,000

HTTPS

ItemValue
ProtocolHTTP/1.1 over TLS 1.2 or 1.3
Connections at once, per listener256
Time for one request60 seconds
Request body256 KiB for the admin API; about 10 MiB for JMAP and DAV
Headers on every answer over TLSStrict-Transport-Security: max-age=31536000, and a restrictive Content-Security-Policy

Metrics endpoint

Plain HTTP, no authentication, /metrics, /healthz and /readyz only, 5 seconds per request. See Monitoring.

Something unclear or out of date on this page? Tell us.