Skip to main content

Email

Connect your inbox, let AI triage it, and act on what matters.

The Email Intelligence Plugin connects Hrida AI Studio to your IMAP/SMTP inbox. Once configured, AI reads your incoming mail, scores each message for urgency, tags it by topic, flags spam, suggests a draft reply, and links meeting invites to your CalDAV calendar — all without leaving Hrida AI Studio.

Plugin required

The Email workspace is only visible when the admin has enabled the Email Intelligence Plugin under Admin > Settings > Email > Install for All Users. See Admin Setup below.


What the plugin does​

CapabilityDescription
Urgency scoringEach email is rated 1–5 for how urgently it needs attention
Auto-taggingTopics like billing, legal, internal, urgent are detected and attached as tags
Spam detectionA spam_score (0.0–1.0) is assigned; emails above the admin-configured threshold are automatically moved to Spam
Draft repliesAI generates a ready-to-send reply draft for each triaged message
CalDAV awarenessMeeting invites found in email are cross-referenced with your calendar to surface scheduling conflicts
Chat assistantThe Email Triage Assistant pipe lets you converse with your inbox in natural language

Admin Setup​

1. Install the plugins​

Go to Admin > Settings > Email and click Install for All Users.

This single action registers two plugins server-side:

PluginTypeID
Email ManagerToolemail_manager
Email Triage AssistantPipe (function)email_triage_assistant

The install is idempotent — clicking again after a server update reinstalls both plugins with the latest source.

2. Tool and pipe valves are set automatically​

The Hrida API URL and API Key fields you fill in on the same Admin > Settings > Email screen before clicking Install for All Users are written straight into both plugins' HRIDA_API_URL / HRIDA_API_KEY valves server-side — there's no separate manual valve-configuration step. HRIDA_API_URL defaults to the container's own internal address (override via the EMAIL_PLUGIN_SELF_URL env var if yours differs; do not point it at the browser-facing port, e.g. not 3000). HRIDA_API_KEY is optional for the pipe — it falls back to the signed-in user's own session token, so leave it blank unless you need headless/API access.

If you want to double-check or hand-edit them afterward, they're visible under Admin > Workspace > Tools > Email Manager and Admin > Workspace > Functions > Email Triage Assistant (gear icon on each).

3. Email Triage Assistant pipe settings (optional)​

The pipe also exposes a few tunables (gear icon on Email Triage Assistant under Admin > Workspace > Functions) — all have sane defaults, so this step is optional:

ValveDefaultNotes
MODEL_ID(empty)Model that writes the replies. Empty uses the Task Model, then the first default model, then the first available model
TRIAGE_SYSTEM_PROMPTBuilt-in email-assistant system promptCustomize the assistant's persona/instructions
AUTO_TRIAGE_ON_LOADtrueInclude the email digest in the context of every reply
AUTO_TRIAGE_LIMIT50Max cached triage entries pulled into the digest

Per-user, the pipe only has one setting — User Valves > account_id — covered in Linking your account below.

4. Set admin-level email settings​

Go to Admin > Settings > Email:

SettingDefaultDescription
Max Emails per Triage Run50Prevents runaway IMAP polling. Max: 500
Spam Auto-flag Threshold0.75Emails with spam_score ≥ this are moved to Spam
Triage Model Override(blank)Model ID for the background sync triage. Leave blank to use the instance default.

Docker Compose environment variables​

# docker-compose.yaml → hrida-ai-studio service

# Background inbox auto-sync
- EMAIL_SYNC_INTERVAL=900        # seconds between automatic syncs (default: 15 min)
- EMAIL_RETENTION_DAYS=90        # how long triage results are kept

# Internal URL for the email pipe (only needed if your internal port differs from 8080)
# - EMAIL_PLUGIN_SELF_URL=http://localhost:8080
Not the same as system SMTP

SMTP_HOST / SMTP_USER / SMTP_PASSWORD (if set on your instance) configure the app's own outgoing system email — password resets, demo request notifications, etc. They have nothing to do with this feature. Each user's own inbox IMAP/SMTP credentials are entered per-account in Dashboard > Email (next section) and stored encrypted in the database, not as environment variables.


Setting up your email account​

Navigate to Dashboard > Email and click + Add Account.

FieldDescription
LabelFriendly name for this account (e.g. "Work Gmail")
IMAP hostIMAP server address (e.g. imap.gmail.com)
IMAP portDefault: 993 (SSL)
SMTP hostSMTP server address (e.g. smtp.gmail.com)
SMTP portDefault: 587 (STARTTLS). Use 465 for SMTP over SSL
UsernameYour email address
PasswordApp password or account password
Use SSLEnable for IMAP port 993; leave off for STARTTLS configurations
CalDAV URL(Optional) CalDAV server URL for calendar-aware scheduling
CalDAV username / password(Optional) CalDAV credentials (stored separately from email credentials)

Credentials are encrypted at rest using Fernet symmetric encryption keyed to the instance HRIDAAI_SECRET_KEY. Passwords are never returned in API responses or logs.

After saving, click Test Connection to verify IMAP and SMTP connectivity before running a triage.

Gmail: use an App Password

Gmail requires an App Password (not your account password) when IMAP access is enabled. Generate one at Google Account > Security > 2-Step Verification > App passwords.


Linking your account to the Email Triage Assistant​

The pipe needs to know which email account belongs to you. After adding your account:

  1. Go to Dashboard > Email, click your account, and copy the Account ID.
  2. Open a new chat and select Email Triage Assistant as the model.
  3. Open its Chat Controls panel (the sliders/adjustments icon) → Valves, and paste your Account ID into the account_id field under User Valves.

Using the Email Triage Assistant​

With your account ID set, a digest of recently triaged emails (from the local triage cache) is injected into the assistant's context on every reply (controlled by the AUTO_TRIAGE_ON_LOAD / AUTO_TRIAGE_LIMIT valves above). From there you can ask things like:

  • "Which emails are most urgent today?"
  • "Is there anything from the finance team I should respond to?"
  • "Triage my inbox" — explicitly re-runs triage mid-conversation

The injected digest looks like:

📬 **Email Digest** — 2026-08-14 09:30 UTC
Account: Work <you@example.com>

🔴 **CRITICAL** (1 email)
• **Budget approval needed** — finance@company.com [billing, urgent]
🟠 **URGENT** (2 emails)
• **Server outage — action required** — ops@company.com [infra]
• **Contract expires Friday** — legal@company.com [legal]
🚫 **Auto-filtered spam**: 3 emails

The model then answers based on this real-time inbox snapshot.


How triage works​

Triage is triggered manually from the Email workspace, or automatically via the background scheduler:

  1. Fetch — the plugin connects via IMAP and fetches up to N recent messages (admin-configurable; default: 50).
  2. Analyse — each message is sent to the configured triage model. The model returns a structured triage result:
    • urgency (1–5)
    • tags (list of topic strings)
    • spam_score (0.0–1.0)
    • summary (one-paragraph summary)
    • draft_reply (ready-to-send response)
  3. Cache — results are stored in the triage cache (email_triage_cache table). Re-triaging the same message UID updates the cached result.
  4. Spam filter — messages with spam_score ≥ threshold (admin default: 0.75) are moved to the Spam folder via IMAP.

Browsing the triage results​

The Email workspace shows your triaged messages. Use the filter controls to narrow by:

FilterValues
UrgencyMinimum urgency level (1–5)
TagFilter to messages with a specific tag

Each triaged message card shows:

  • Subject, sender, received timestamp
  • Urgency badge (color-coded: 1=grey, 3=yellow, 5=red)
  • Tags
  • AI summary
  • Draft reply (expandable)
  • Spam score

Click a message to open the full detail view where you can copy or edit the draft reply before sending.


Scheduled triage (background sync)​

You don't need to set anything up for this — every active email account is synced and re-triaged automatically in the background on a fixed interval, no Automation needed:

Env varDefaultDescription
EMAIL_SYNC_INTERVAL900 (15 min)Seconds between automatic background syncs
EMAIL_RETENTION_DAYS90How long triage results are kept before being pruned

These are plain environment variables (not admin-UI editable) — changing them requires a container restart. Use the manual ↻ Sync button in Dashboard > Email, or POST /api/v1/email/accounts/{id}/sync, to trigger a triage run immediately instead of waiting for the next scheduled interval.


Security​

  • Fernet encryption: All email and CalDAV credentials are encrypted using a key derived from HRIDAAI_SECRET_KEY. If the secret key changes, existing credentials cannot be decrypted.
  • Owner-scoped access: Each user can only see and manage their own email accounts. Admins can access any account.
  • Passwords never returned: The account API never includes plaintext passwords in responses. A separate internal endpoint decrypts on the fly for plugin use only and is only called server-side.
  • Session token precedence: The Email Triage Pipe uses your signed-in session token by default. The HRIDA_API_KEY valve is only a fallback for headless API usage.
  • Spam scores are advisory: The plugin moves messages to the Spam IMAP folder but does not delete them. You can always recover messages from Spam manually.

Troubleshooting​

"Pipe load failed: unterminated string literal"​

The pipe source was stored with a corrupt escape sequence. Re-run the install endpoint:

Admin > Settings > Email > Install for All Users

This re-installs the latest pipe source and clears the cached module.


"Configuration error: Could not auto-detect model"​

The pipe's HRIDA_API_URL is pointing to the wrong address. Common causes:

SymptomCauseFix
Max retries exceeded ... port=3000Valve set to browser-facing URLSet HRIDA_API_URL to http://localhost:8080
Read timed outSync HTTP call deadlocking event loopUpgrade to the latest server image — the fix is in functions.py (asyncio.to_thread)
Connection refusedContainer port mismatchCheck the PORT env var; default is 8080. Set EMAIL_PLUGIN_SELF_URL if needed

The HRIDA_API_URL must be the container's own internal port, not the port your browser uses. If you publish port 3000:8080 in Docker, the internal URL is still http://localhost:8080.


Empty response (blank chat bubble)​

This happens when the pipe returns raw JSON instead of text. Cause: the pipe was returning a dict (pass-through body). The fix is in the server — make sure you are running version 1.5.0+ of the pipe (visible in Admin > Workspace > Functions > Email Triage Assistant). Re-install if needed.


"LLM error 400: Bad Request"​

The pipe was sending framework-internal fields (metadata, tool_ids, session_id) that your backend rejected. Fixed in pipe version 1.5.0 — the pipe now builds a clean OpenAI-compatible body before forwarding. Re-install the plugin.


No emails appearing after sync​

  1. Confirm the email account credentials are correct (Dashboard > Email > Test Connection).
  2. Run a manual sync: click Sync on your account, or call POST /api/v1/email/accounts/{id}/sync.
  3. Check that the Email Triage Assistant has your account_id set in User Valves.
  4. Ensure the triage model is available: go to Workspace > Models and confirm at least one model is loaded.

Email account returns "Failed to decrypt credentials"​

The HRIDAAI_SECRET_KEY environment variable changed between the time the account was saved and now. Credentials are encrypted with this key — changing it makes existing accounts unreadable. Re-add the account after restoring the original key, or keep the key stable across restarts (set it explicitly rather than letting it auto-generate).


API reference​

All email endpoints are under /api/v1/email.

# Account management
GET    /api/v1/email/accounts
POST   /api/v1/email/accounts
GET    /api/v1/email/accounts/{id}
PATCH  /api/v1/email/accounts/{id}
DELETE /api/v1/email/accounts/{id}

# Connection test
POST   /api/v1/email/accounts/{id}/test
# Returns: {"imap": true, "smtp": true, "errors": {}}

# Manual IMAP sync + triage
POST   /api/v1/email/accounts/{id}/sync
# Body: {"limit": 50, "folder": "INBOX", "only_unseen": true, "mark_as_read": true}
# Returns: {"synced": N, "fetched": N}

# Triage cache
GET    /api/v1/email/accounts/{id}/triage    ?urgency_min=1&tag=&skip=0&limit=50
POST   /api/v1/email/accounts/{id}/triage    # upsert a triage result (plugin use)
DELETE /api/v1/email/accounts/{id}/triage/{message_uid}
DELETE /api/v1/email/accounts/{id}/triage    # clear all cached results for account

# Thread grouping
GET    /api/v1/email/accounts/{id}/threads   ?limit=200

# Draft management
GET    /api/v1/email/drafts
POST   /api/v1/email/drafts
PATCH  /api/v1/email/drafts/{draft_id}
DELETE /api/v1/email/drafts/{draft_id}

# Plugin install (admin only)
POST   /api/v1/email/plugin/install
# Body: {"hrida_api_key": "<service-account-key>"}
# Returns: {"tool": "created|updated", "function": "created|updated"}
Hrida.ai is proprietary software of Zlabs Innovation. See the license for terms. © 2026 Zlabs Innovation.