Orkestia
Blog
Cloud Connections

Email mailboxes

Connect Gmail, Google Workspace, iCloud, Fastmail, Yahoo, any IMAP/SMTP server, or Microsoft 365 / Outlook.com, then read mail and send it after a human approves

A mailbox connection lets workflows, compositions and agents work in your own inbox: list and search messages, read one with its attachments, mark messages read, watch a folder for new mail, and send from your address once a person has approved the exact message. Each mailbox is its own org-scoped connection, so an organization can connect as many as it needs.

There are two kinds, because the providers sign in differently:

ConnectionProvidersHow it signs inProvider key
Mailbox (IMAP/SMTP)Gmail and Google Workspace, iCloud Mail, Fastmail, Yahoo Mail, or any other IMAP/SMTP serverAn app password you create in the mail accountemail
Microsoft 365 / OutlookMicrosoft 365 work or school accounts, and personal Outlook.com / Hotmail / Live accountsSign in with Microsoft (OAuth, Microsoft Graph). No password is storedmicrosoft_mail

Both kinds run the same email.* workflows. You name the mailbox in every run by its connection_uuid. There is no default mailbox.

Connect an IMAP/SMTP mailbox

In the console, open Connections, go to the Email category and choose Mailbox (IMAP/SMTP). Pick the provider, enter the address and the app password, select Test connection, then Connect.

An app password is a separate password your provider issues for one app. You can revoke it without changing your real password, and revoking it disconnects the mailbox. Never enter your account password.

ProviderBefore you startServers (filled in for you)
Gmail / Google WorkspaceTurn on 2-Step Verification, then create an app password at myaccount.google.com/apppasswords. If your Gmail settings still show an IMAP switch, make sure IMAP is onimap.gmail.com:993, smtp.gmail.com:465 (SSL)
iCloud MailTwo-factor authentication on the Apple Account and an @icloud.com, @me.com or @mac.com address. Create an app-specific password at account.apple.com under Sign-In and Security → App-Specific Passwordsimap.mail.me.com:993, smtp.mail.me.com:587 (STARTTLS)
FastmailSettings → Privacy & Security → App passwords, with access to Mail (IMAP/POP/SMTP)imap.fastmail.com:993, smtp.fastmail.com:465 (SSL)
Yahoo MailAccount security → Generate app password (Yahoo may ask you to turn on 2-step verification first)imap.mail.yahoo.com:993, smtp.mail.yahoo.com:465 (SSL)
OtherThe IMAP and SMTP settings your provider publishes, and an app password when it offers oneYou enter them

For Other, IMAP must use port 993 (TLS) and SMTP must use 465 (SSL) or 587 (STARTTLS). Hosts must be public mail servers: names that resolve to loopback, private, link-local, multicast or reserved addresses are refused on every connect. Set Login username only when the server does not log in with the email address.

Google Workspace admins can block this. App passwords are missing when the admin does not allow 2-Step Verification, enforces security keys only, or the account is in Advanced Protection, and an admin can turn IMAP off for the whole domain. If App passwords is missing or the test reports an IMAP login failure, ask your Workspace administrator.iCloud: changing your Apple Account password revokes every app-specific password, so the connection needs a new one afterwards.

Test connection logs in to IMAP and to SMTP and never sends a message. Connect runs the same test and saves only if it passes.

From an assistant or the API

The same flow is connection.setup with provider_type email:

FieldRequiredNotes
mail_presetyesgmail, icloud, fastmail, yahoo or custom
usernameyesThe mailbox login, normally the address
api_tokenyesThe app password. Stored encrypted
mailboxnoThe mailbox address. Defaults to username
from_namenoDisplay name for the From header
connection_namenoDefaults to the mailbox address
imap_host, imap_port, smtp_host, smtp_port, smtp_securitycustom onlyIgnored for the named presets. smtp_security is ssl or starttls

Pass dry_run: true to test without saving. get_workflow_prerequisites("connection.setup", variant="email") returns the full per-provider guide.

Connect a Microsoft 365 or Outlook.com mailbox

Microsoft retired password sign-in for IMAP and SMTP, so Microsoft mailboxes do not work as IMAP/SMTP connections. Use Microsoft 365 / Outlook instead:

  1. In Connections → Email, choose Microsoft 365 / Outlook and select Sign in with Microsoft.
  2. Microsoft always shows the account picker, so one person can connect several mailboxes. Pick the account.
  3. Consent to the permissions below. You return to the console and the connection is saved, named after the mailbox address.

Orkestia asks for these delegated Microsoft Graph permissions, and only these:

PermissionWhy
openid, email, User.ReadSign you in and read your profile, which gives the mailbox address the connection is named after
offline_accessKeep access without asking you to sign in again on every run
Mail.ReadWriteRead messages and folders, and mark messages read or unread
Mail.SendSend mail as you, only after a person approves the message (see Sending)

You never paste a client ID, secret or token. Orkestia keeps the access and refresh tokens encrypted on the connection and refreshes them on its own.

"Need admin approval" means your Microsoft 365 tenant does not let users consent to apps. A Microsoft 365 administrator has to grant consent to the Orkestia app in the Entra admin center under Enterprise applications.

Over the API this is connection.oauth-start then connection.oauth-exchange with provider_type microsoft_mail and the redirect URI https://app.orkestia.dev/connections/microsoft_mail/callback. get_workflow_prerequisites("connection.setup", variant="microsoft_mail") returns the guide.

Workflows

Every workflow takes connection_uuid (the mailbox) and refuses any connection that is not a mailbox of your organization. None of the read workflows mark anything read.

WorkflowWhat it doesMain inputs
email.mailbox.verifyRe-tests the connection without sending anything. Returns the mailbox address, the inbox message count, and (IMAP/SMTP) whether each side passed—
email.folder.listLists folders with their id, name, special use and, on Microsoft, total and unread counts—
email.message.listMessage summaries of a folder, newest first, with a cursor for the next pagefolder (default INBOX), unread_only, since, limit, cursor
email.message.searchFree-text search over headers and bodyquery, folder, limit
email.message.getOne message: headers, text and HTML bodies, attachments, and any meeting invite it carriesmessage_id, folder, body_max_chars, include_html, storage_connection_uuid + bucket, key_prefix
email.message.mark-readMarks messages read, or unread with read: falsemessage_ids or message_id, read
email.inbox.pollThe next batch of new messages since a cursor, for a schedulefolder, cursor, limit, since
email.message.send-with-approvalPrepares a message and asks a person to approve it. Does not sendactor_uuid, to, subject, text or html, and the optional fields below
email.message.sendSends the message an approved review holdsapproval_envelope_uuid, save_to_sent

A message summary is {id, internet_message_id, folder, from, to, cc, subject, date, received_at, is_read, has_attachments, size_bytes, snippet, in_reply_to}. Pass its id to get or mark-read; both also accept an RFC Message-ID such as <abc@example.com>. Over IMAP, snippet is empty and folder counts are not reported.

Search takes plain words, not IMAP or Microsoft query syntax. Over IMAP it searches INBOX unless you name a folder; on Microsoft it searches the whole mailbox when folder is omitted.

Attachments go to your bucket

email.message.get never puts attachment bytes in the run. Give it a storage connection and a bucket and it copies each attachment there, returning a storage_object_uuid, bucket and key per file. Without a storage target you get the metadata only (file name, type, size). See object storage for the storage.* side.

When a message contains a meeting invite (a calendar part, an .ics attachment or an Outlook meeting request), get also returns it parsed as invite: title, start and end, time zone, organizer, attendees, location and meeting link.

Watching for new mail

email.inbox.poll is a bounded, read-only batch built to be fired by schedule.*. It returns next_cursor. Store it and pass it back on the next poll. On the first run, with no cursor, it starts from now and returns nothing unless you give since. has_more: true means more new mail is waiting; cursor_reset: true means the stored cursor no longer applied and was re-anchored. message_ids gives you idempotency keys, so a message seen twice can be skipped.

Sending needs a human approval

No workflow sends mail on the say-so of a script or an agent alone. Sending takes two runs:

  1. email.message.send-with-approval validates the message and opens a review in the Staff inbox of the actor you name in actor_uuid. It returns approval_envelope_uuid and status: review_requested. Nothing is sent yet.
  2. A person reviews the exact message (recipients, subject, body, attachments, mailbox) and approves it.
  3. email.message.send with the same connection_uuid and that approval_envelope_uuid sends exactly the reviewed message. It takes no recipients, subject or body of its own, refuses an envelope approved for a different mailbox, and sends once: calling it again returns the first result with deduped: true.

Optional fields on the request: cc, bcc, reply_to, from_name, attachment_storage_object_uuids (storage objects of your organization), reply_to_message_id (threads the message as a reply), review_title, review_reason, and connector_uuid to notify an inbox connector.

On IMAP/SMTP mailboxes, save_to_sent (default on) files a copy in the Sent folder. Gmail files its own copy, so Orkestia skips it there.

Limits

WhatLimit
Messages per list, search or poll25 by default, up to 100
Messages per mark-read call100
Body returned by get100,000 characters per part by default, up to 1,000,000
Whole message read over IMAP25 MB. Larger messages are refused
Attachments copied per message20, each up to 25 MB
Recipients per message (to + cc + bcc)50
Subject998 characters
Outgoing attachments10 files, 20 MB in total. 3 MB in total on Microsoft mailboxes

Security and what is stored

  • One credential per mailbox, encrypted. An IMAP/SMTP connection stores the address, the provider preset or server settings, and the app password (encrypted). A Microsoft connection stores the address, the account kind (work or personal) and the access and refresh tokens (encrypted). Workflow inputs never carry the credential.
  • TLS only. IMAP on 993, SMTP on 465 or 587 with STARTTLS. Server addresses are checked on every connect.
  • Orkestia does not copy your mailbox. A run reads what it asked for and returns it as that run's output, within the caps above. Attachments only leave the mailbox when you name a bucket in your own storage.
  • Revoke at the source. Revoke the app password in the mail account, or remove Orkestia from the Microsoft account, and the next run fails. Deleting the connection in the console removes it from Orkestia.

Managing a mailbox connection

  • Rotate an app password: edit the connection, paste a new app password made in the same mail account, then revoke the old one there.
  • Microsoft grant expired or revoked: edit the connection and select Sign in with Microsoft again.
  • Check it still works: run email.mailbox.verify.

Troubleshooting

SymptomCauseFix
IMAP login failure on Gmail / WorkspaceIMAP off, or a Workspace policy blocks app passwordsTurn IMAP on, or ask the Workspace administrator
App passwords missing in the Google Account2-Step Verification off, security-key-only policy, or Advanced ProtectionTurn on 2-Step Verification, or ask the administrator
iCloud mailbox stopped workingThe Apple Account password changedMake a new app-specific password and rotate it in
Outlook.com or Microsoft 365 address rejected as IMAP/SMTPMicrosoft retired password sign-inConnect it as Microsoft 365 / Outlook
"Need admin approval" at Microsoft sign-inThe tenant blocks user consentA Microsoft 365 administrator grants consent to the Orkestia app
Custom server refusedPort other than 993 / 465 / 587, or the host resolves to a private addressUse the provider's public TLS endpoints
Send fails on a Microsoft mailbox with attachmentsOver the 3 MB totalSend fewer or smaller files, or share a link instead

Cloud connections

The connection model every provider follows.

Staff governance

Inbox approvals, gates, and which actors may run which workflows.

Platform services

storage.* for attachments and schedule.* for polling.

Compositions

Chain a poll, a read and an approved reply into one saved workflow.