Groundmail

Features

Send email for your customers without sharing their mistakes

If your product sends email on behalf of your own customers, give each one a tenant: its own domains, suppression list, stats, sending ramp and pause switch, so one customer's bad list never hurts the rest.

What each tenant gets

Isolation per customer, in one account

You keep one account, one dashboard, and as many API keys and webhook endpoints as you like. Each of your customers gets its own lane.

Its own domains

A domain belongs to one tenant or to your whole account. Only that tenant can send from its domains, and every tenant can use your shared ones.

Its own suppression list

Bounces, complaints and unsubscribes land on the tenant's list. A complaint to one customer never stops another customer emailing the same person.

Its own stats

Delivered, bounced, complained and rates per tenant, over the API and on the Tenants page in the dashboard.

Its own sending ramp

Each new tenant starts at 1,000 product and 3,000 transactional recipients a day, doubling as it sends clean mail. Add your own daily limit on top.

Its own pause switch

Pause one tenant and its new sends are refused while every other tenant keeps sending. We pause a single tenant, not your account, when its rates get too high.

Its own keys and webhooks

Limit an API key to one tenant, and filter a webhook endpoint so a customer's delivery events go to their URL.

API

One call per customer, one field per send

Create a tenant with your own id for the customer, then name it on each send. Batch sends take a tenant per item.

  • external_id is your id for the customer, used everywhere you name the tenant
  • default_from_domain completes a bare from such as “billing”
  • stream_policy: "transactional_only" refuses product email for that tenant
  • daily_limit sets your own cap per UTC day
  • Every email and email webhook carries the tenant, and GET /emails filters by it

Create a tenant

curl -X POST https://api.groundmail.dev/tenants \
  -H "Authorization: Bearer $GROUNDMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "cust_8412",
    "name": "Acme Inc",
    "default_from_domain": "mail.acme.com"
  }'

Send as the tenant

curl -X POST https://api.groundmail.dev/emails \
  -H "Authorization: Bearer $GROUNDMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant": "cust_8412",
    "from": "Acme <billing@mail.acme.com>",
    "to": "jane@example.com",
    "subject": "Your receipt",
    "html": "<p>Thanks!</p>"
  }'

Webhooks

Each customer's events, at their own URL

By default an endpoint gets events for every tenant, with the tenant in each payload. Set tenants on an endpoint and it only gets those tenants' email events.

POST /webhooks

{
  "url": "https://acme.example.com/hooks/email",
  "events": ["email.delivered", "email.bounced", "email.complained"],
  "tenants": ["cust_8412"]
}

Node SDK

import { Groundmail } from 'groundmail'

const client = new Groundmail(process.env.GROUNDMAIL_API_KEY!)

await client.tenants.create({ external_id: 'cust_8412', name: 'Acme Inc' })
await client.tenants.domains.assign('cust_8412', 'mail.acme.com')
const { stats, ramp } = await client.tenants.stats('cust_8412', { days: 7 })
await client.tenants.pause('cust_8412', 'Customer asked us to stop')
await client.tenants.resume('cust_8412')

Plans

Included on Scale and Dedicated

Tenants are part of the plan, with no per-tenant fee. Billing stays on your sending volume. See pricing.

  • Scale: up to 1,000 tenants
  • Dedicated: up to 10,000 tenants
  • Give any tenant its own dedicated IP, or a pool of them, for $50 per IP per month
  • The CLI and SDKs cover tenants, keys and webhook filters
  • Walkthrough: the platforms guide

FAQ

Common questions

Do tenants cost extra?

No. Tenants are included on Scale (up to 1,000) and Dedicated (up to 10,000), with no per-tenant fee. You pay for sending volume as usual. Need more tenants, or tenants on another plan? Email support@groundmail.dev.

What happens when one customer sends to a bad list?

Their tenant takes the hit, not your other customers. Bounces and complaints go on that tenant's own suppression list, a new tenant ramps up its daily volume on its own schedule, and if a tenant's bounce or complaint rate gets too high, Groundmail pauses that one tenant instead of your whole account.

Do I have to change my sending code?

Add a tenant field to each send. If you leave it out and send from a domain that belongs to a tenant, the email is that tenant's anyway, so SMTP and existing code get per-tenant isolation as soon as the customer's domain is assigned to their tenant.

Can a customer have their own API key or webhook?

Yes. A key limited to one tenant can only send as that tenant and only sees its emails, domains and suppressions. A webhook endpoint can be filtered to one or more tenants, so each customer's delivery events go to their own URL.

Can one customer have a dedicated IP?

Yes. A tenant can send from its own dedicated IP, or a pool of them, for $50 per IP per month. Request it under Settings, Billing, Dedicated IPs and pick the tenant. We set it up and tell you when the tenant's mail moves over; nothing changes in your code.

Put your transactional email on solid ground.

Start free on our transactional pool. Move to dedicated IPs or a dedicated server when you need the isolation. Same API either way.