IMAP & POP3

NEW EMAIL IMAP and NEW EMAIL POP3 connect and authenticate to a mailbox, captured with SET. Every subsequent operation is subject-first — EMAIL ?conn VERB .... This is a separate, dedicated verb family from MAIL, which only sends outbound email — see Mail & Redirection.

Protocol scope. IMAP is a mail-retrieval and folder-management protocol. It supports folders, flags, search, and Gmail-style labels. It does not expose product-only features like Smart Compose, Priority Inbox sorting, Gmail's Category tabs, snoozing, scheduled send, or confidential mode — these are Gmail-the-product features with no IMAP equivalent, regardless of client.

Where the Mail Arrives

A mailbox needs the domain’s mail to be delivered here, and that is a DNS question rather than an OcaltQL one. There are three ways to arrange it, and which you pick decides how much of the domain Ocalt is responsible for.

Route 1 - Delegation: nothing to configure

Set the domain’s nameservers at your registrar to dns1.ocalt.com and dns2.ocalt.com. Ocalt serves the whole zone, and the moment a mailbox exists it writes the mail records itself - MX, SPF and DMARC included. There is nothing for you to add and nothing to keep in step.

This is the route to take unless you have a reason not to. See Custom Domains.

Route 2 - An A record: web and mail both here

Point the domain at 41.61.20.37 with an A record on @, then add the three mail records below yourself. You keep the zone, so anything else you run on the domain is untouched, but every record is yours to maintain.

Route 3 - Mail records only: the site stays where it is

If the website lives with another host and you only want the mailboxes here, leave the A record pointing wherever it already points and add only the three mail records. Ocalt never sees the web traffic. Register it with DOMAIN "tld.com" FOR MAIL, which checks the MX rather than the address, because there is no site here to check.

Point Only the Mailboxes
DOMAIN "tld.com" FOR MAIL SET ?r
AFTER EMIT ?r("mail_only")
(* The web for tld.com stays with your existing host *)

AFTER NEW EMAIL ACCOUNT "hello" AT "tld.com" WITH PASSWORD "Password" SET ?acc
AFTER EMIT ?acc("address")

The three records

Routes 2 and 3 need the same three. Add them at whoever provides your DNS, exactly as written.

Type Name Value
MX @ mail.ocalt.com   priority 10
TXT @ v=spf1 include:mail.ocalt.com ~all
TXT _dmarc v=DMARC1; p=none; rua=mailto:you@tld.com
TXT ocalt._domainkey Given to you by DOMAIN STATUS - a long v=DKIM1 value unique to your domain

What each record does

MX is the only one that carries mail. It tells every sending server where to deliver anything addressed to your domain; mail.ocalt.com is the host that accepts it. The priority number only matters when there are several - lower is tried first - and with one record the value is arbitrary. Without an MX, mail to your domain bounces before it ever reaches us.

SPF is a public list of who may send as you. include:mail.ocalt.com means “the machine Ocalt sends your mail from is allowed to”. It points at one host rather than at everything under ocalt.com, so authorising Ocalt to send as you does not quietly authorise anything else that Ocalt itself uses. ~all ends it with “treat anything else as suspicious” rather than “reject it outright”, which is the safer setting while you are still moving things around. If you send from somewhere else too - a newsletter service, your own server - add their include to the same record. There must be exactly one SPF record on a domain; a second one invalidates both.

DMARC tells a receiver what to do when SPF disagrees. p=none asks them to do nothing and simply report, which is where to start: you find out what is being sent in your name before you begin blocking it. The rua address receives those reports. Once the reports look right, tighten to p=quarantine and later p=reject.

DKIM proves a message really came from you. Ocalt generates a signing key for your domain the moment you point it, and signs everything sent from an address on it. The public half is the record above, and until it is published a receiver has nothing to check the signature against.

The value is long and unique to your domain, so it is not printed here. Ask for it:

Read Your DKIM Record
DOMAIN STATUS "tld.com" SET ?d
AFTER EMIT ?d("dkim_name") & "  ->  " & ?d("dkim_value")
AFTER EMIT "published: " & ?d("dkim_published")

Publish it as a TXT record at the name it gives you, then run the same script again - dkim_published turns true once it resolves. On a delegated domain there is nothing to do: Ocalt writes the record itself.

Give DNS time. A new MX is usually live within minutes and can take up to a few hours. DOMAIN ... FOR MAIL refuses until it can actually see the record, and the refusal says so - it is not a failure, only an answer that arrived early.
Publish the DKIM record before you send. Until it resolves, mail from your domain is signed with a key no receiver can look up, and an unverifiable signature is treated much like a missing one. Receiving is unaffected either way.

Creating a Mailbox

A mailbox does not have to come from somewhere else. NEW EMAIL ACCOUNT creates one on a subdomain you own, or on a domain already pointed at Ocalt with DOMAIN. Once created, every verb on this page manages it — the account is an ordinary IMAP/POP3 mailbox, reached with the same NEW EMAIL IMAP connection as any other host.

Create an Account on Your Subdomain
NEW EMAIL ACCOUNT "hello" AT "mysite.ocalt.site" WITH PASSWORD "Password" SET ?emailaccountobject
AFTER EMIT ?emailaccountobject("address")
Create an Account on a Pointed Domain
NEW EMAIL ACCOUNT "sales" AT "tld.com" WITH PASSWORD "Password" SET ?acc
AFTER EMIT ?acc("address")
(* tld.com must already be pointed at Ocalt — see DOMAIN on the Site Mode page *)
Two ways it fails. Creation errors if the subdomain does not belong to your namespace, and it errors if the domain is not pointing at Ocalt’s server address. Both are catchable, and ?err("message") says which of the two it was.
Create It, Then Log Into It
NEW EMAIL ACCOUNT "hello" AT "mysite.ocalt.site" WITH PASSWORD "Password" SET ?acc
AFTER NEW EMAIL IMAP ?acc("imap_host") WITH "Password" AS ?acc("address") SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER COUNT ?inbox SET ?n
AFTER EMIT ?n & " messages"
Field Description
addressThe full address — hello@mysite.ocalt.site
imap_hostHost to pass to NEW EMAIL IMAP
pop3_hostHost to pass to NEW EMAIL POP3

IMAP - Connect

NEW EMAIL IMAP speaks the standard protocol, so it connects to any server that does - a company Exchange box, a mailbox at your web host, Fastmail, Zoho, a self-hosted Dovecot, or one you created here. Three things are needed: the host, the address, and that mailbox’s password.

A Mailbox Anywhere
NEW EMAIL IMAP "mail.yourcompany.com" WITH "your_password" AS "you@yourcompany.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER COUNT ?inbox SET ?n
AFTER EMIT ?n & " messages"

Nothing there is Ocalt-specific. A mailbox you create here is the same shape - NEW EMAIL ACCOUNT hands you the host to use, so you never have to look one up.

A Mailbox You Created Here
NEW EMAIL ACCOUNT "hello" AT "mysite.ocalt.site" WITH PASSWORD "Password" SET ?acc
AFTER NEW EMAIL IMAP ?acc("imap_host") WITH "Password" AS ?acc("address") SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER COUNT ?inbox SET ?n
AFTER EMIT ?n
Everything below works identically against an Ocalt mailbox and against a third-party one. The examples use Gmail because it is the strictest case - App Passwords, OAuth2, label extensions - and anything that works there works on a mailbox you created here with less setup.
Connect to a Third-Party Mailbox (Gmail requires an App Password)
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
OAuth2 — PWTYPE selects the authentication mechanism
NEW EMAIL IMAP "imap.gmail.com" WITH "ya29.access_token" AS "user@gmail.com" PWTYPE "oauth2" SET ?conn
PWTYPE defaults to "plain" — the WITH value is sent as the account password (for Gmail this must be an App Password; Google no longer accepts regular account passwords over IMAP, POP3, or SMTP). With PWTYPE "oauth2" the WITH value is an OAuth2 access token, delivered via SASL XOAUTH2 on IMAP, POP3, and the derived SMTP transport alike. PWTYPE is accepted by both NEW EMAIL IMAP and NEW EMAIL POP3. A failed connection — wrong credentials, unreachable host, unknown PWTYPE — is a catchable E4001, as is every subsequent protocol failure on an EMAIL operation, so OR CATCH ERROR SET ?err receives ?err("code"), ?err("message"), and ?err("verb") — see Error Codes.

IMAP — Folders

List All Folders
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn LIST FOLDERS SET ?folders
Inbox, Sent, Drafts, Spam, Trash
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER EMAIL ?conn SENT SET ?sent
AFTER EMAIL ?conn DRAFTS SET ?drafts
AFTER EMAIL ?conn SPAM SET ?spam
AFTER EMAIL ?conn TRASH SET ?trash
A Custom Folder
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn FOLDER "Custom Folder Name" SET ?custom

IMAP — Unread and Search

Unread Only
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn UNREAD SET ?new
AFTER COUNT ?new SET ?n
AFTER EMIT ?n & " unread"
Search the Inbox
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEARCH "FROM boss@company.com" SET ?msgs
Search a Specific Folder
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn FOLDER "Sent" SEARCH "client@site.com" SET ?results

IMAP — Fetching a Message

Fetch by UID, Retrieved from a Real List
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER EMIT ?inbox(0)("uid")
AFTER EMAIL ?conn UID ?inbox(0)("uid") SET ?msg
AFTER EMIT ?msg("subject")

IMAP — Flags

Mark Read, Unread, Flagged, Unflagged, Deleted
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER EMAIL ?conn MARK ?inbox(0)("uid") AS READ
AFTER EMAIL ?conn MARK ?inbox(0)("uid") AS UNREAD
AFTER EMAIL ?conn MARK ?inbox(0)("uid") AS FLAGGED
AFTER EMAIL ?conn MARK ?inbox(0)("uid") AS UNFLAGGED
AFTER EMAIL ?conn MARK ?inbox(0)("uid") AS DELETED

IMAP — Move and Copy

Move a Message
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER EMAIL ?conn MOVE ?inbox(0)("uid") TO "Trash"
Copy a Message
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER EMAIL ?conn COPY ?inbox(0)("uid") TO "Custom Folder Name"

IMAP — Labels (Gmail Extension)

Read, Add, Remove Labels
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn INBOX SET ?inbox
AFTER EMAIL ?conn LABELS ?inbox(0)("uid") SET ?labels
AFTER EMAIL ?conn ADD LABEL ?inbox(0)("uid") AS "Important"
AFTER EMAIL ?conn REMOVE LABEL ?inbox(0)("uid") AS "Important"

IMAP — Drafts

Save a Draft
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SAVE DRAFT TO "recipient@example.ocalt.com" SUBJECT "Hello" BODY "message text"

IMAP — Close

Close the Connection
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn CLOSE

POP3

POP3 has no folders and no server-side search — it operates on a flat, download-and-delete model. NEW EMAIL POP3 connects the same way as IMAP, but the available operations are LIST, UID, DELETE, and CLOSE.

Connect
NEW EMAIL POP3 "pop.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
List Messages
NEW EMAIL POP3 "pop.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn LIST SET ?messages
Fetch by UID, Retrieved from a Real List

POP3’s LIST only ever returns uid and size per message — the protocol does not expose subject, sender, date, or body until the full message is fetched by UID.

NEW EMAIL POP3 "pop.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn LIST SET ?messages
AFTER EMIT ?messages(0)("uid")
AFTER EMIT ?messages(0)("size")
AFTER EMAIL ?conn UID ?messages(0)("uid") SET ?msg
AFTER EMIT ?msg("subject")
AFTER EMIT ?msg("from")
AFTER EMIT ?msg("date")
AFTER EMIT ?msg("body")
Delete and Close
NEW EMAIL POP3 "pop.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn LIST SET ?messages
AFTER EMAIL ?conn DELETE ?messages(0)("uid")
AFTER EMAIL ?conn CLOSE

Sending Email

EMAIL ?conn SEND shares the exact same modifier set as MAIL: TO, SUBJECT, BODY, CC, BCC, REPLY TO, HEADER, and ATTACH. All modifiers are optional and can appear in any order.

Basic Send
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "recipient@example.ocalt.com" SUBJECT "Hello!" BODY "This is the body"
AFTER EMAIL ?conn CLOSE
CC and BCC
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "boss@site.com" CC "team@site.com" SUBJECT "report" BODY "message"
AFTER EMAIL ?conn SEND TO "boss@site.com" BCC "secret@site.com" SUBJECT "hidden copy" BODY "message"
Reply-To
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "support@site.com" SUBJECT "support" BODY "help needed" REPLY TO "user@site.com"
Custom Header
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "email@email.com" HEADER "From: blah@blah.com" SUBJECT "with header" BODY "hello"

Sending Attachments

An attachment is shared to a URL first with FILE SHARE, then passed to SEND via ATTACH. This works identically for a local file or anything already reachable at a web URL. ATTACH accepts a single value or an array of values for multiple attachments.

Attach a Local File
FILE SHARE "/root/invoice.pdf" SET ?url
AFTER NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "client@site.com" SUBJECT "Invoice" BODY "See attached" ATTACH ?url
AFTER EMAIL ?conn CLOSE
Attach an Existing Web URL
NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "client@site.com" SUBJECT "Report" BODY "See attached" ATTACH "https://example.ocalt.com/files/report.pdf"
AFTER EMAIL ?conn CLOSE
Multiple Attachments
FILE SHARE "/root/invoice.pdf" SET ?url1
AFTER FILE SHARE "/root/receipt.pdf" SET ?url2
AFTER NEW ARRAY SET ?attachments
AFTER APPEND ?url1 TO ?attachments
AFTER APPEND ?url2 TO ?attachments
AFTER NEW EMAIL IMAP "imap.gmail.com" WITH "app_password" AS "user@gmail.com" SET ?conn
AFTER EMAIL ?conn SEND TO "client@site.com" SUBJECT "Invoice + Receipt" BODY "See attached" ATTACH ?attachments
AFTER EMAIL ?conn CLOSE
EMAIL is a distinct verb family from MAIL — MAIL only sends outbound email, EMAIL connects to and manages a mailbox via IMAP or POP3. NEW EMAIL IMAP and NEW EMAIL POP3 both produce a ?conn subject passed to every subsequent operation. UIDs are always retrieved from a real prior fetch, never hardcoded. SENT, DRAFTS, SPAM, and TRASH are bare keywords; any other folder uses FOLDER "name". EMAIL ... SEND shares the complete MAIL modifier set. POP3 is intentionally more limited than IMAP — no folders, no server-side search, no flags, no labels.