Skip to content

First run

Create the super-admin, onboard a domain, make a mailbox, and send a test message.

Updated View as Markdown

Your Workers are deployed but no mail flows yet. This page brings the first domain online end to end.

1. Create the super-admin (genesis)

At genesis no domain is onboarded, so there’s no way to deliver a verification email. The trust root is deploy access — whoever holds the instance secrets. Two surfaces, both gated on “zero users exist”:

The guaranteed floor — works with no mail path:

pnpm --filter doota reset-admin you@external-example.com 'strong-password' --name "Your Name" --remote

In genesis mode it creates the super-admin, links the password, and enrolls TOTP — printing an otpauth:// URI and backup codes. Scan the URI into your authenticator and save the backup codes. Use --remote to target the production database.

If you set SETUP_TOKEN, open:

https://your-app/setup?token=<SETUP_TOKEN>

It renders only while zero users exist and re-checks the token server-side. It creates the super-admin and password; TOTP is added later via the onboarding “secure account” step. Once any user exists, the wizard locks out permanently.

Now sign in at /login. As super-admin your only onboarding step is secure account (TOTP or passkey), which genesis already handled.

2. Onboard your domain

Go to /admin/domains (super-admin only). This uses your scoped Cloudflare token to provision everything.

Pick a zone

Doota lists every zone on your Cloudflare account and flags which are already onboarded — pick one instead of typing it. A manual field remains for a domain not yet on Cloudflare. Optionally supply a sending subdomain (outbound DKIM host, e.g. send.acme.com) within the domain.

Zone creation (new domains only)

If the domain is already a zone on your account, Doota reuses it — no error. A brand-new domain triggers a zone create and returns the assigned nameservers; point your registrar at them. The request isn’t blocked on activation — status is tracked in D1.

Wait for active, then Refresh

Once the zone is active, hit Refresh (refreshDomain). Doota then wires mail idempotently: enables Email Routing, writes MX + SPF (inbound), onboards the sending domain (DKIM + DMARC + return-path), and points the catch-all rule at MAIL_IN_WORKER_NAME.

Add DNS records if your DNS is elsewhere

For a Cloudflare-hosted zone the records are created automatically. If your DNS lives elsewhere, the screen shows the exact DKIM / DMARC / return-path records to add — they’re fetched live per domain, never persisted.

The domain moves through pending_zone → pending_nameservers → wiring → active. Only domain, zone_id, the org mapping, and this status live in D1; all DNS/routing state is fetched live from Cloudflare for the settings screens.

3. Create the first mailbox and user

Once the domain is active, provision a user through the organization:

/admin/organizations → pick the org (one org = one domain) → manage members → create user. Because the org pins the domain, you supply only the local part — Doota builds <username>@<domain>. Set the role (member or admin) and an external recovery email.

Doota creates the user with a random temp password and emails an invite to the recovery address: the login email, the temp password, and a recovery-verification link. On first sign-in the onboarding gate forces set password + verify recovery (+ secure account for admins).

See Managing users for the full flow.

4. Send and receive a test message

Receive

From any external account (Gmail, Outlook), email the new mailbox (you@acme.com). It should appear as a new thread within seconds. If not, see Troubleshooting.

Send

Reply from Doota, or compose a new message to an external address. Watch the submission tick from queued → sent → delivered in the composer.

That’s a working instance. From here, explore Using Doota or read up on Operations.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close