Security

How Mailgi keeps mail safe

Where data lives, how credentials are stored, how mail is signed, and what we don't have yet.

Mailgi stores mailbox content in Germany, keeps API keys and session tokens only as one-way hashes, signs every domain's mail with DKIM, SPF and DMARC, and sends webhooks that carry no message content. It has no SOC 2 report yet. Everything below describes the service as it runs today.

Where data lives

The full processor list is on the privacy page. The one exception to EU hosting is the encrypted nightly backup.

DataWhereNotes
Mailbox contentGermany (Hetzner)Separate from the account database
Accounts, organisations, usageEU, Frankfurt (Supabase)Postgres
Outbound relayEU, Ireland (AWS SES)Per-organisation sending reputation
Nightly backupUS (AWS S3, us-east-1)Encrypted on our server before upload, key never sent to AWS
Logs and errorsEU (CloudWatch, Sentry)Application logs and error tracking

Credentials

01

API keys are hashed

Stored only as one-way hashes. We can't recover a key, so we can't email you one; lost keys are revoked and replaced. Agents can mint extra keys per task, with expiry, and revoke them individually.

02

Dashboard sign-in by one-time code

Login codes sent by email expire after ten minutes; session tokens are also stored as hashes.

03

Registration tokens for custom domains

An agent can only claim an address on your domain with a token a human created in the dashboard. Invalid, revoked and unverified tokens all return the same error, so the response leaks nothing.

Mail

01

DKIM, SPF and DMARC on every domain

Mailgi generates and holds each domain's DKIM key and publishes it under its own selector, aligns SPF with a dedicated MAIL FROM subdomain, and recommends DMARC. A custom domain cannot send until the records verify.

02

Content-free webhooks

A webhook says that mail arrived, from whom and when, and gives a fetch URL. Subjects and bodies never pass through your endpoint, and reading the message needs the agent's API key.

03

Signed webhooks

HMAC-SHA256 over the timestamp and raw body, in x-mailgi-signature, with a per-endpoint secret shown once. Reject old timestamps to stop replays.

04

Contacts kept as keyed hashes

To tell new recipients from known ones we keep per-agent keyed hashes, not addresses, so the table can't be read as a list of who talks to whom.

Abuse controls

Unattended registration only works if sending is hard to abuse.

01

Layered sending limits

Per API key, per agent, per organisation by domain age, and one shared bucket for the @mailgi.xyz domain. The lowest limit wins. Full numbers on the pricing page.

02

Automatic suspension

Bounces and complaints are tracked per organisation, and sending is suspended when they cross a threshold.

03

No bulk features

No lists, imports or campaigns. Every send is one API call naming its own recipients, at most 50 per field.

04

Paid outbound

Mail to the outside world is paid from a prepaid balance, and whoever pays is accountable for that wallet's mail.

What we don't have yet

01

No SOC 2 or ISO 27001 report

If your procurement needs one, we're not the right choice today.

02

No dedicated IPs

Outbound shares relay infrastructure; reputation is isolated per organisation, not per IP.

03

Deleting an agent

Revokes its keys immediately and burns the address for good. The privacy page describes retention.

Reporting a vulnerability

01

hello@mailgi.xyz

Subject starting security:. A person reads it. Please give us a reasonable chance to fix an issue before publishing it.

One POST to start.

No signup form, no OAuth, no card to start. Receiving is free.

Open the dashboard →