Skip to main content
By default, a connected account syncs only the mail that arrives after it connects. Mail that was already in the mailbox isn’t imported. Turn on initial sync when you also need the recent mail that is already there. The engine then imports the last 30 days (or fewer, if you choose) right after the account connects.
At a glance
  • Off by default. Turn it on in the auth intent’s config with initial_sync_enable: true, or with the initial sync option in the dashboard.
  • Imports the last 1 to 30 days. Default and maximum: 30 days.
  • Works for IMAP accounts (Gmail included), for new accounts only (never on a reconnect).
  • Imported mail sends no email.new webhooks. You get account.initial_sync.running and account.initial_sync.completed, then read the mail with List emails.
  • Mail that arrives during the import is new mail and sends email.new as usual.

Turn it on

With the API

Add a config to the auth intent that connects the mailbox:
In this example, the mailbox imports the last 14 days.
boolean
default:"false"
Import the mail already in the mailbox.
integer
default:"30"
How many days back to import, from 1 to 30. More than 30 is refused with 400 errors/invalid_parameters. Ignored unless initial_sync_enable is true.
The response is the account (201) with an initial_sync object ("status": "pending"). The import runs in the background.

From the dashboard

In Accounts → Add account, turn on the initial sync option and choose how many days to import (1 to 30). See From the dashboard.

What happens

Once the user connects the mailbox, these steps run on their own:
  1. The account connects. You get account.add. The account’s initial_sync.status is pending.
  2. The import starts, within a few seconds. You get account.initial_sync.running.
  3. The engine imports the mail received in the chosen window, from every folder: Inbox, Sent, Archive, labels and so on. Each email is stored like any synced email, with its attachments. No email.new is sent for these.
  4. The import finishes. You get account.initial_sync.completed, with the number of emails imported. The account’s initial_sync.status is completed.
  5. Read the imported mail with List emails, for example GET /api/v1/emails?account_id=acc_….
From the moment the account connects, it also syncs new mail as usual. An email that arrives while the import is still running is new mail: it sends email.new, and it is never counted as imported. How long the import takes depends on the size of the mailbox: usually seconds to a few minutes for 30 days.
Why no email.new for imported mail? A mailbox can hold thousands of emails from the last 30 days. Sending a webhook for each would flood your endpoint and look like new mail. Use account.initial_sync.completed as your signal to fetch the imported mail in one go.

Follow the import

On the account

Every account connected with initial sync has an initial_sync object, in Retrieve an account and List accounts. Accounts connected without it don’t have this field.

With webhooks

Subscribe your webhook endpoint to these events: data.initial_sync is the account’s initial_sync object:
account.initial_sync.completed

If the import fails

If the provider can’t be read, for example because of a network error, the engine tries again on its next pass. Each try picks up where the last one stopped, so nothing is imported twice. After 5 failed tries, the import gives up:
  • initial_sync.status becomes failed;
  • imported shows what was imported until then (that mail stays);
  • you get account.initial_sync.failed.
A failed import doesn’t affect the account: new mail keeps syncing and sending email.new. If the account itself has a problem (for example, its password changed), its status shows it as usual.

Good to know

  • 30 days at most. Older mail can’t be imported.
  • Only when a new account connects. Reconnecting an account doesn’t import again. Connecting a mailbox that is already connected refreshes its credentials and doesn’t import either.
  • “Days” count from when the import starts. IMAP servers (Gmail included) search by day, so the whole first day of the window is included.
  • Every folder is imported, including Sent, Spam and Trash, as in a normal sync. Gmail’s “All Mail”, “Starred” and “Important” views are skipped; an email with several Gmail labels is imported once per label (see Gmail).
  • Unipile compatibility. The names are the same as in Unipile v2: initial_sync_enable, the account’s initial_sync, the account.initial_sync.* events. Unipile offers initial sync for IMAP; the same here. initial_sync_days is our addition.