MOLTED EMAIL

Suppressions & Consent

Manage suppression lists, record consent, and enforce compliance across scopes.

Suppressions prevent email from being sent to specific recipients. Consent records track the legal basis for contacting someone. Both are enforced automatically by the policy engine.

Suppression scopes

Suppressions can be applied at three levels:

ScopeDescription
globalBlocked across all tenants. Checked first.
tenantBlocked for a specific tenant.
campaignBlocked for a specific campaign only.

When evaluating a send request, global suppressions are checked first, then tenant, then campaign.

Add a suppression

CLI
molted suppressions add --email user@example.com --reason manual_dnc --scope tenant
CLI - with expiration
molted suppressions add --email user@example.com --reason no_engagement --scope tenant \
  --expires-at 2027-01-01T00:00:00Z

CLI flags

FlagTypeRequiredDescription
--emailstringYesEmail address to suppress. Must be a valid email format.
--reasonstringYesReason code (see table below).
--scopestringYesSuppression scope: global, tenant, or campaign.
--campaign-idstringNoCampaign ID. Required when --scope is campaign.
--sourcestringNoSource of the suppression (for your own tracking).
--expires-atstringNoISO 8601 expiry timestamp. If omitted, suppression is permanent.

Via the API

POST https://api.molted.email/v1/suppressions
curl
curl -X POST https://api.molted.email/v1/suppressions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "recipientEmail": "user@example.com",
    "scope": "tenant",
    "reasonCode": "manual_dnc",
    "expiresAt": "2027-01-01T00:00:00Z"
  }'
FieldTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
recipientEmailstringYesEmail address to suppress.
scopestringYesSuppression scope: global, tenant, or campaign.
reasonCodestringYesReason code (see table below).
campaignIdstringNoCampaign ID. Required when scope is campaign.
sourcestringNoSource of the suppression (for your own tracking).
expiresAtstringNoISO 8601 expiry timestamp. If omitted, suppression is permanent.

Reason codes

CodeDescription
complaintRecipient marked an email as spam.
hard_bounceEmail address hard-bounced.
manual_dncManually added to do-not-contact list.
legal_requestSuppressed due to a legal request (e.g., GDPR erasure).
role_accountRole account (e.g., info@, admin@) that should not receive automated email.
domain_suppressedEntire domain is suppressed.
no_engagementContact has not engaged with prior emails. Consider using --expires-at for temporary suppression.

Remove a suppression

CLI
molted suppressions remove SUPPRESSION_ID
curl
curl -X DELETE "https://api.molted.email/v1/suppressions/SUPPRESSION_ID?tenantId=tenant_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"

List suppressions

CLI
molted suppressions list --email user@example.com
curl
curl "https://api.molted.email/v1/suppressions?tenantId=tenant_abc123&recipientEmail=user@example.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
ParameterTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
recipientEmailstringNoFilter by email address.

Consent records document the legal basis for contacting someone. The policy engine checks consent before marketing sends -- missing consent blocks the send with reason no_consent. Transactional emails (receipts, password resets) are exempt.

CLI
molted consent record --email alice@example.com \
  --type explicit_opt_in --source signup-form --jurisdiction EU
CLI - revoke consent
molted consent record --email alice@example.com \
  --type explicit_opt_in --revoked-at 2026-06-15T00:00:00Z

CLI flags

FlagTypeRequiredDescription
--emailstringYesRecipient email address.
--typestringYesLegal basis (see table below).
--sourcestringNoWhere consent was collected (e.g., signup-form).
--jurisdictionstringNoJurisdiction code (e.g., EU, US-CA, UK, BR). Free-form, used for compliance reporting.
--granted-atstringNoWhen consent was granted (ISO 8601). Defaults to now.
--revoked-atstringNoWhen consent was revoked (ISO 8601). Set this to revoke existing consent.

Via the API

POST https://api.molted.email/v1/consent
curl
curl -X POST https://api.molted.email/v1/consent \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "recipientEmail": "alice@example.com",
    "basis": "explicit_opt_in",
    "source": "signup-form",
    "jurisdiction": "EU"
  }'
BasisDescription
explicit_opt_inRecipient explicitly agreed to receive email. Strongest basis, required for EU.
legitimate_interestBusiness relationship justifies contact.
contractualEmail is necessary to fulfill a contract.
legal_obligationEmail is legally required.

Use consent check to verify whether you have a valid legal basis to send marketing email to a recipient.

CLI
molted consent check --email alice@example.com
curl
curl "https://api.molted.email/v1/consent?tenantId=tenant_abc123&recipientEmail=alice@example.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "hasConsent": true,
  "basis": "explicit_opt_in",
  "source": "signup-form",
  "jurisdiction": "EU",
  "grantedAt": "2026-01-15T10:00:00Z"
}

Marketing sends to this address are allowed.

Response
{
  "hasConsent": false
}

No consent record exists. Marketing sends to this address will be blocked by the policy engine with reason no_consent. Transactional sends are unaffected.

To unblock marketing sends, record consent:

molted consent record --email alice@example.com \
  --type explicit_opt_in --source signup-form --jurisdiction EU
Response
{
  "hasConsent": false,
  "revokedAt": "2026-06-15T00:00:00Z"
}

Consent was previously granted but has been revoked. Marketing sends are blocked. To re-enable, record a new consent with a fresh legal basis.

  • Consent is per-email address, not per-contact.
  • The policy engine auto-checks consent on every marketing send -- you do not need to call consent check manually before sending.
  • consent check is useful for pre-flight validation in your agent logic, or for building UI that shows consent status.
  • Transactional templates bypass consent checks entirely.