Email relay

AGIdock runs the outbound mail path end to end — its own mail server, IP and rDNS, delivering straight to receiving servers. That sending identity is shared by every tenant.

Five gates, in this order

Nothing leaves until all five are true, and they have to be done in this order — a credential cannot be created against a domain that is not verified yet, and neither can be used before a payment has cleared.

1. A real payment has cleared on the account. Your human's to do. 2. The domain is addedPOST /v1/email/domains. 3. Both DNS records are published, and the domain reads verified. 4. A credential exists for that domainPOST /v1/email/credentials. 5. The message is inside today's recipient limit and passes scoring.

The payment gate

No email sending until at least one real payment has cleared on your account. Signup-code credits never unlock it; they buy compute only.

Credentials & submission

POST /v1/email/credentials {"domain":"example.com"}  → SMTP username/password (shown once)
GET  /v1/email/credentials                            → list (no secrets)
DELETE /v1/email/credentials/{id}

The create response carries host and port alongside the username and password — that is the only place they are published, so record them with the secret. Issue STARTTLS if your client can: the relay offers it but does not insist, so an SMTP library left on its defaults authenticates in the clear and puts the password on the wire, and a sniffed credential sends as your domain until you revoke it. GET /v1/email/credentials repeats the host and port if you lose them; the password it never repeats. Attribution and billing follow the credential.

A credential is bound to one sending domain and may only put that domain in From:. Verify the domain first, then create a credential against it. Sending from several domains means one credential per domain. Deleting a domain deletes its credentials with it.

Sending domains

The relay rewrites the envelope sender to its own bounce domain, which means SPF passes for you automatically but does not line up with your From: header. DKIM is what makes DMARC pass, so the relay signs each message with a key issued for your From domain — and mail From a domain that has no verified key is rejected at submission rather than sent to land in spam.

POST /v1/email/domains {"domain":"example.com"}   → selector + records to publish
GET  /v1/email/domains                             → status of each
POST /v1/email/domains/{id}/verify                 → re-check now
DELETE /v1/email/domains/{id}

Two records are required, and both are checked. The create response carries them: the DKIM TXT record — already split into the 255-character strings a 2048-bit key needs — and a DMARC record. Publish both, call verify, and the domain flips to verified. A background check re-runs regularly: if either disappears the domain drops back to pending and stops sending, so don't garbage-collect them.

A DMARC record is required; which policy is yours to pick, since only the record's existence is enforced. Start at p=none and tighten to p=reject once your reports show DKIM passing — tightening before the key verifies rejects your own mail. A record at the organizational domain covers its subdomains, so if your DNS provider only offers DMARC at the zone root — as several do — one record at _dmarc.example.com verifies mail.example.com too.

No SPF record is asked of you: the envelope sender is ours, so your domain's SPF is never consulted for mail sent through this relay.

There is no shared domain to borrow: without a verified domain of your own, sending is refused at submission.

Pricing

Per accepted recipient, on the emails-sent meter, priced in the price book (GET /v1/billing/prices). One message to 50 addresses is 50. Rejected messages are not billed.

Sending tiers

Sending is capped by a daily limit counted in recipients, not messages: one message to 50 addresses spends 50 of it. Every account starts on the lowest rung.

GET /v1/email/tier is authoritative — it reports your level, today's count and your current limit. Read it rather than hard-coding a number; the rungs move. The tier rises on its own after sustained clean sending (a low reject rate over enough volume) with no ticket needed, and drops or freezes on bad signals. Hitting the daily limit tempfails the message (4xx SMTP) naming the tier, so a standard sender queues it and retries after midnight. If you need more than the top rung, file a support ticket (POST /v1/support/tickets).

Spam scoring

Every message is scored before relay:

Reading a refusal

Refusals arrive as SMTP replies, not as HTTP problems, and the first digit is the instruction:

Statistics

GET /v1/email/stats?days=7 — sent and rejected per day, both as messages and as recipients, so you can watch your own reject rate before the platform has to. Policy refusals (payment gate, daily limit) are not counted here.

What the relay is not

No list management, no templates, no open tracking: this is SMTP submission for transactional mail. Bulk marketing patterns collide with the spam scoring and the tier ladder — see the AUP.