Skip to main content
Curia’s email channel is powered by Nylas — a unified API that handles the OAuth and IMAP/SMTP complexity across Gmail, Outlook, and other providers. Once connected, Curia can send emails on your behalf, draft replies for your review, and read your inbox.

Single account setup

The quickest way to get email working is to connect one account using three vault secrets.
1

Create a Nylas account

Sign up at app.nylas.com. The free tier is sufficient for development and small deployments.
2

Create an application

In the Nylas dashboard, create a new application and choose Email as the product. Once created, copy your API key — this becomes nylas_api_key.
3

Connect an email account

Inside your application, go to Grants and add a new grant. This walks you through an OAuth flow to connect a Gmail, Outlook, or other email account to Nylas. After completing the flow, copy the Grant ID — this becomes nylas_grant_id.
Use a dedicated email address for Curia (e.g., [email protected]) rather than your primary inbox. Curia will read and process all incoming messages on this account.
4

Seed the credentials into the vault

Set all three values transiently and run the seed script — they are encrypted and stored in the vault, not in .env:
NYLAS_API_KEY=nyk_v0_... \
NYLAS_GRANT_ID=<grant-id-from-dashboard> \
[email protected] \
pnpm run seed-vault
They are stored under the vault keys nylas_api_key, nylas_grant_id, and nylas_self_email. nylas_self_email is the address of the connected account — Curia uses it to filter self-sent messages and sign outbound emails.
5

Apply the change

Recreate the Curia container so it picks up the new secrets:
docker compose up -d --force-recreate curia
The email channel activates automatically when all three Nylas secrets are in the vault. docker compose logs curia will show the email adapter initializing.

Multiple email accounts

For more advanced deployments — for example, connecting multiple inboxes — configure named accounts in config/local.yaml using the channel_accounts.email block.
# config/local.yaml
channel_accounts:
  email:
    curia:
      nylas_grant_id: "env:NYLAS_GRANT_ID_CURIA"
      self_email:     "env:NYLAS_SELF_EMAIL_CURIA"

    personal:
      nylas_grant_id: "env:NYLAS_GRANT_ID_PERSONAL"
      self_email:     "env:NYLAS_SELF_EMAIL_PERSONAL"
Each key (curia, personal) becomes an account name that you pass to email skills via the account parameter. Outbound email sending is governed by the autonomy engine — when the score is below the skill’s action_risk floor, sends are blocked and saved as drafts instead.
When using channel_accounts.email, the single-account vault keys (nylas_grant_id, nylas_self_email) are no longer used for routing — all accounts must be defined in the YAML block. You still need nylas_api_key in the vault: it’s the application-level key shared by all accounts.

Email skills

Once the email channel is active, the following skills become available to Curia and any agents you configure:
SkillWhat it does
email-listList recent messages in any connected account
email-getFetch the full body of a specific message by ID
email-sendCompose and send a new email
email-replyReply to an existing thread by message ID
email-draft-saveSave a draft to a specified account for human review
send-draftSend a previously saved draft (CEO-authorized)
email-archiveArchive a message by ID
All email skills accept an account parameter to target a specific named account. Omit it to use Curia’s own account.

File attachments

Outbound email skills (email-send, email-reply, and their CEO-inbox counterparts) accept an optional list of attachments. Files are referenced by file:// URLs backed by Curia’s temp-file store rather than passed inline, with a cap of 20 MB total across at most 10 attachments per message. Anything an agent has written to the temp-file store can be attached; the drive-download-file skill bridges Google Drive by downloading a file (including Google-native exports) into that store and returning a file:// URL ready to attach. No extra configuration is needed beyond a working Nylas grant — attachments ride the same Send API as the message body.

Troubleshooting

All three Nylas secrets (nylas_api_key, nylas_grant_id, nylas_self_email) must be in the vault. If any is missing, the channel disables itself at startup with one of these log messages:
NYLAS_API_KEY/NYLAS_GRANT_ID not set — email channel disabled
NYLAS_SELF_EMAIL not set — email adapter disabled
Confirm what is seeded with pnpm run seed-vault (it verifies and lists keys), re-seed any missing value, and recreate the container.
Curia polls the Nylas Messages API every 30 seconds by default. If messages are slow to appear, confirm the email account’s OAuth grant is active in the Nylas dashboard and that the grant ID matches the vault’s nylas_grant_id.You can also adjust the polling interval (non-secret config in .env):
NYLAS_POLL_INTERVAL_MS=15000
Outbound sends are governed by the autonomy engine. If your autonomy score is below 70, email-send and email-reply are blocked and drafts are saved instead. Ask Curia its current score (“What is your autonomy score?”) and raise it if needed.