Emails

Send a transactional email

post/emails

Request

  • Base URL: https://api.groundmail.dev
  • URL: https://api.groundmail.dev/emails
  • Auth: HTTP bearer

Headers

Idempotency-Keystring

Optional idempotency key (max 256 chars). Retries with the same key and identical body return the original response. Same key with a different body, or a concurrent in-flight request, returns 409.

Request body

subjectstring

Required unless using template (optional override when sending with a template).

htmlstring
htmlBodystring

Alias for html

html_bodystring

Alias for html

textstring
textBodystring

Alias for text

text_bodystring

Alias for text

plain_bodystring

Alias for text

tagstring

Optional delivery tag override.

headersobject

Custom headers after server-side safety filtering.

scheduled_atstring date-time

Schedule delivery for a future ISO 8601 timestamp. Returns status scheduled.

scheduledAtstring date-time

Alias for scheduled_at.

unsubscribeboolean

Opt in to managed unsubscribe for this send. Injects RFC 8058 List-Unsubscribe headers and replaces {{unsubscribe_url}} in subject/html/text. When sending with a template, inherits the template's unsubscribe_enabled setting unless overridden here.

category'transactional' | 'product' | 'newsletter'

Optional send-level category override. Defaults to the template's category when sending with a template, otherwise transactional. product (onboarding, lifecycle and notification email) supports category-scoped opt-out and auto-enables managed unsubscribe. Transactional and product email are sent from separate IP pools. newsletter (opt-in newsletters) is accepted only for approved accounts: it is sent from its own IPs, separate from transactional and product email, always carries List-Unsubscribe and one-click unsubscribe (unsubscribe: false is a validation_error), honours category opt-outs, and has its own daily ramp-up limit. On an account that is not approved it fails with 403 newsletter_not_enabled and nothing is sent.

tenantstring

Send as one of your tenants (its external_id or id). The send uses that tenant's domains, suppression list, sending ramp, daily limit and pause switch. Readers who unsubscribe from a tenant's email are suppressed or opted out for that tenant only, so other tenants can still mail them. Omit it to send from the account as a whole; a send from a domain a tenant owns is that tenant's even without tenant. A key limited to one tenant always sends as its tenant. On an account without tenants, naming one returns 403 tenants_not_enabled.

Example request

{
  "attachments": [
    {
      "content_type": "application/pdf"
    }
  ]
}

Response

Email accepted for delivery

idstring required

Public message ID (msg_…)

statusstring required

held when content scanning stopped the email for review before sending (new senders only); you get email.delivered or email.failed once it is reviewed.

testtrue

Present (and true) on a test send: a test key (gm_test_…) or only simulator addresses. Nothing was delivered; the outcome and webhooks are simulated.

Example response

{
  "status": "sent"
}

Changes

No recorded changes to this operation across all 2 revisions of this API.