Protocols and file formats
By the end of this page you will know what each built-in connector moves, which credentials it needs, and what it does not carry. For how a route is put together, see Connectors.
| Kind | Source | Target | Moves |
|---|---|---|---|
jmap | yes | yes | mail, contacts |
google | yes | mail, calendars, contacts | |
files | yes | mail, calendars, contacts, from an uploaded file |
CalDAV and CardDAV, as sources and targets, are described in Connectors and DAV discovery. Every source here is read-only. Nothing is deleted, flagged or moved there.
Mail follows RFC 8620 (core) and RFC 8621 (mail). Contacts follow RFC 9610, where a card is a JSContact object (RFC 9553).
Calendars are not carried by this connector. JMAP Calendars is still an Internet-Draft, so it is not implemented. Use the caldav connector with the same provider (CalDAV is the standard way to reach its calendars).
- Credentials. The session URL (
https://host/.well-known/jmap, or the provider’s session URL) and either a login with a password (auth: basic) or an access token (auth: bearer).account_idis optional; empty means the primary account. - As a source. The session resource is read first, then the account’s mailboxes and address books. Each mailbox is a folder. A mail kept in several mailboxes (JMAP mailboxes work like labels) is copied once, in one mailbox chosen the same way on every run: trash, junk, drafts, sent, inbox, then the first by name. Mailboxes with the roles
all,flagged,importantandsubscribedare views and are skipped. Mail is listed withEmail/queryandEmail/getin one request, newest first, and downloaded from the blob URL.$seen,$flagged,$answered,$draftand$forwardedbecome flags; the received date is kept. Cards are converted to vCard 3.0. - As a target. Mail is uploaded as a blob and added with
Email/import, with its keywords and received date. Mailboxes are created as needed, with the special roles when the server has none of them.root_folderputs everything under one mailbox. Contacts are written withContactCard/setin an address book of the same name as the source folder, created if absent. - Resume. A mail already imported is found by its
X-PST-Import-Idheader withEmail/queryand checked for an exact match. A contact is found by itsuid, which is derived from the item, so a second attempt never makes a second card. - State.
changed_sinceusesEmail/changesandContactCard/changes, and falls back to a full listing oncannotCalculateChanges. Jobs do not use it yet (see Known limitations). - Limits.
- Credentials are only sent to the host of the session URL. A server whose
apiUrl,uploadUrlordownloadUrlis on another host is refused. Give the final session URL, not a redirecting one. - Photos and other binary properties of a contact are not carried. A card of kind
groupis skipped. Vendor properties that vCard has no equivalent for are dropped. - A contact in several address books is copied once.
- An
Email/importrefused by the server as invalid is reported for that mail and the job goes on.
- Credentials are only sent to the host of the session URL. A server whose
Gmail through IMAP, Google Calendar and Google People (contacts) through their REST APIs. This connector was written from Google’s documentation and tested against simulated servers only, never against Google itself. Try a single test mailbox first.
- Access, option 1: Google Workspace service account with domain-wide delegation. Create a service account, enable domain-wide delegation, authorize its client id in the Workspace admin console for the scopes below, and paste the JSON key file whole in
service_account_key. The connector signs a JWT (RS256) as the service account for the user inuserand exchanges it for an access token (urn:ietf:params:oauth:grant-type:jwt-bearer). - Access, option 2: per-user OAuth. Give
client_id,client_secretand arefresh_tokenof the user. mccb does not run the consent screen: obtain the refresh token yourself (for example with the OAuth 2.0 Playground and your own client) with the scopes below, once, with offline access. - Scopes. Mail
https://mail.google.com/(the only scope Gmail IMAP accepts; for delegation,gmail.imap_adminalso shows labels hidden from IMAP in the user’s settings, but this connector asks forhttps://mail.google.com/). Calendarhttps://www.googleapis.com/auth/calendar.readonly. Contactshttps://www.googleapis.com/auth/contacts.readonly. Enable the Gmail, Calendar and People APIs in the Cloud project, and turn on IMAP for the mailbox. Untick a service (sync_mail,sync_calendar,sync_contacts) to leave its scope out. - Mail. Gmail labels are not folders: a mail with three labels appears in three IMAP folders, and a plain IMAP copy would make three copies. This connector reads
[Gmail]/All Mailonce and uses each message’sX-GM-MSGIDas its identity, and itsX-GM-LABELSto pick one folder: Drafts, then INBOX, then Sent, then the first user label by name (a labelA/Bbecomes the folderA/B), thenArchivefor a mail with no label. The other labels are not carried. Starred is the\Flaggedflag. Spam and Trash are skipped unlessinclude_trash_spamis ticked. Messages are read withBODY.PEEK, read-only. - Calendars. Every calendar the user can read, as a folder. A series and its changed or cancelled occurrences are one iCalendar resource: a cancelled occurrence becomes an
EXDATE. A single event is written in UTC; a series keeps the time zone name (TZID) so that it follows daylight saving time, without an embeddedVTIMEZONEblock. Attendees, organizer, reminders, location, description and the conference link (X-GOOGLE-CONFERENCE) are carried; attachments and the Google-specific event types birthday and working location are not. - Contacts. The user’s saved contacts (
people/me/connections) as one folder, converted to vCard 3.0: names, emails, phones, addresses, organization, title, nicknames, URLs, birthday and notes. “Other contacts”, the directory, groups and photos are not carried. A birthday without a year is written with the Apple Contacts convention. - State. Contacts and calendars use the API sync tokens, mail the UID of All Mail, in
changed_since. Jobs do not use it yet. People sync tokens expire after 7 days; an expired one gives a full listing. - Limits. The Gmail IMAP bandwidth and API quotas of Google apply, and the first full People sync has its own quota (HTTP 429, retried). Google throttles large mailboxes: expect hours per gigabytes.
Files: mbox, Maildir, .eml, .msg, .ics, .vcf, .zip
Section titled “Files: mbox, Maildir, .eml, .msg, .ics, .vcf, .zip”These arrive like a PST: through the Files page, POST /api/uploads, a URL fetch, or the drop folder (see Server-side intake). The analysis recognizes them, the row appears in the PST list with scan.format: "files", and a mailbox that links it reads it with the files connector. A PST or OST is analysed as before and is never read by this connector.
| What you have | How to send it |
|---|---|
An mbox file (Thunderbird, Apple Mail export, mutt, Gmail Takeout) | The file itself, .mbox or .mbx, or with no extension if it starts with a From line |
| Maildir | A .zip of the directory (cur, new, tmp, and .Sub.Folder directories) |
| Loose messages | One .eml or .msg, or a .zip of many |
| Calendar | .ics, one or many events |
| Contacts | .vcf, one or many cards |
| A mix | A .zip with any of these, in any folders |
- Folders. A single mbox,
.emlor.msggoes toINBOX. In a zip, a folder of messages becomes the folder of that name, a message at the root goes toINBOX, an mbox becomes a folder named after the file, a Maildir keeps its layout (a root Maildir isINBOX,.Archive.2020isArchive/2020). A calendar or address book file becomes a folder named after itsX-WR-CALNAMEor its file name. Folders namedInbox,Sent,Drafts,TrashorJunkget that role. - Flags. Maildir flags in the file name (
:2,FLAGS), mboxStatusandX-Status, and Thunderbird’sX-Mozilla-Statusbecome the usual flags. A message flagged deleted or trashed is not copied. The date of the message is itsDateheader. - Stable keys. The key of a message is the path inside the file plus its position, so uploading the same file again, or resuming, never copies a message twice. A different file is a different source, even if its messages are the same: messages found again by their
Message-IDare recognized only after a key change of the same source. - mboxrd.
>Fromlines are unquoted. - .msg. Converted to a standard message from the headers (the transport headers when the file has them), the text and HTML body, and the file attachments. Not converted: a body that exists only as RTF, embedded messages, OLE objects. Each is reported as a warning on that message.
- .ics and .vcf. A file with several events or cards is split: one resource per event (a series and its exceptions together, with the file’s time zone definitions) or per card. Tasks and journals are left out.
- Zip. It is read in place, never unpacked, except an mbox inside it, which is copied to the data folder while a job runs. Encrypted entries, nested zips, entries larger than 512 MB and entries with a compression ratio above 250 are skipped and listed under
scan.skipped. - Limits. Contacts and calendars need a target for them (the server’s DAV, or a target that serves them), as for a PST. A
.zipdropped in the inbox folder is taken as a mail export, so keep unrelated archives out of it.