Email

Email

Connect any mailbox, then read, search, send, draft, template, schedule, and process mail with AI.

One normalized email surface spans Gmail, Microsoft 365, and custom IMAP/SMTP. Actions are gated by connection capabilities, so an SMTP-only mailbox can send but not read.

Connect a mailbox

Gmail and Microsoft 365 connect over OAuth. Custom mailboxes connect with direct IMAP/SMTP credentials, stored encrypted at rest — no OAuth app required. Check capabilities before acting: an IMAP+SMTP mailbox reads and sends, an SMTP-only mailbox sends only.

Create a mailbox connection by posting credentials. The connection activates immediately and returns its id.

Connect a custom IMAP/SMTP mailboxbash
curl -X POST https://api.hora.to/v1/connections \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "imap",
    "credentials": {
      "user": "agent@acme.com",
      "password": "app-specific-password",
      "imap": { "host": "imap.acme.com", "port": 993, "secure": true },
      "smtp": { "host": "smtp.acme.com", "port": 465, "secure": true }
    }
  }'
Check capabilitiesbash
curl https://api.hora.to/v1/email/capabilities/conn_123 \
  -H "Authorization: Bearer $HORATO_API_KEY"

Read, search, and organize

List and read messages and threads from the canonical store, or pull live from the provider. Search with `q`, list folders and labels, mark read/unread, move labels, and download attachments.

Set `live=true` to bypass the cache and fetch straight from the provider (it also refreshes the local copy).

Search messagesbash
curl "https://api.hora.to/v1/email/messages?connection_id=conn_123&q=invoice&limit=25" \
  -H "Authorization: Bearer $HORATO_API_KEY"
Mark read / change labelsbash
curl -X PATCH https://api.hora.to/v1/email/messages/msg_123 \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"connection_id":"conn_123","is_read":true,"add_labels":["Processed"]}'

Send, reply, and schedule

Send immediately, reply on a thread, or defer delivery. Add a `send_at` timestamp to schedule a send; scheduled messages run through a retrying dispatcher and can be listed or cancelled before they go out.

Reference a template by id or slug to send templated mail with merge variables.

Send nowbash
curl -X POST https://api.hora.to/v1/email/send \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"connection_id":"conn_123","to":[{"email":"client@example.com"}],"subject":"Hello","body_text":"Hi there"}'
Schedule for laterbash
curl -X POST https://api.hora.to/v1/email/send \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"connection_id":"conn_123","to":[{"email":"client@example.com"}],"subject":"Reminder","body_text":"See you tomorrow","send_at":"2026-06-11T09:00:00Z"}'

Provider-native drafts

Drafts are real provider drafts. On Gmail and Microsoft 365 a draft is created in the account's own Drafts folder, so it is visible in the native client and is sent as the provider's stored copy. Custom IMAP/SMTP mailboxes fall back to a Horato-managed draft.

Create, update, send, and delete follow the same lifecycle. Updating replaces the draft's content; sending delivers it and marks it sent.

Create then send a draftbash
curl -X POST https://api.hora.to/v1/email/drafts \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"connection_id":"conn_123","to":[{"email":"client@example.com"}],"subject":"Proposal","body_text":"Draft body"}'

curl -X POST https://api.hora.to/v1/email/drafts/draft_123/send \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"connection_id":"conn_123"}'

Dynamic templates

Store reusable subject/body templates with `{{ variable }}` merge fields (dot-paths like `{{ invitee.name }}` are supported). Rendering is substitution-only — no logic or code execution — so a stored template can never run arbitrary code. Preview a render with sample variables before sending.

Create and preview a templatebash
curl -X POST https://api.hora.to/v1/email/templates \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slug":"welcome","name":"Welcome","subject":"Welcome, {{ name }}","body_text":"Thanks for joining, {{ name }}."}'

curl -X POST https://api.hora.to/v1/email/templates/tmpl_123/preview \
  -H "Authorization: Bearer $HORATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"variables":{"name":"Dana"}}'

AI message processing

Turn raw mail into structured signal. Summarize a thread, classify intent, extract fields, or clean quoted replies and signatures into plain text. These run on Horato-managed models and return structured JSON.

AI endpoints require an AI key to be configured for the deployment; when it is not, they return a clear error rather than failing silently.

  • `POST /v1/email/ai/summarize`: concise thread or message summary.
  • `POST /v1/email/ai/classify`: label intent/category.
  • `POST /v1/email/ai/extract`: pull structured fields from a message.
  • `POST /v1/email/ai/clean`: strip quotes and signatures to core text.