Email

CASL and suppressions

Email is transactional by default. Commercial email needs CASL consent on file, and bounces, complaints and unsubscribes add an address to your suppression list.

CASL and commercial email

Email is transactional by default: receipts, password resets, alerts and account notices. Transactional email needs no consent record.

Set is_commercial to true for anything that promotes a product or service. A commercial email goes to exactly one recipient, needs CASL consent on file for that address, and carries an unsubscribe footer and a one click unsubscribe header that mail clients honour. Record email consent the same way as for SMS, with email_address instead of phone_number.

Marketing email must set is_commercial to true. It defaults to false, and a transactional send also reaches people who unsubscribed, so a promotional email sent without the flag would get around their unsubscribe and CASL consent.

const { data, error } = await honkio.consents.create({
  emailAddress: 'ada@example.com',
  consentType: 'express',
  sourceDescription: 'Newsletter checkbox on acme.ca/signup',
})
if (error) throw new Error(error.message)
console.log(data.status, data.email_address)
// Before a commercial send: would it pass the CASL check?
const { data, error } = await honkio.consents.check({ emailAddress: 'ada@example.com' })
if (error) throw new Error(error.message)
console.log(data.allowed, data.consentType ?? data.reason)
// Then a commercial send to that one address:
const { data, error } = await honkio.emails.send({
  from: 'news@mail.acme.ca',
  to: 'ada@example.com',
  subject: 'Fall sale',
  html: '<p>20% off this week.</p>',
  isCommercial: true,
})
if (error) throw new Error(error.message)
console.log(data.id)

DELETE /v1/compliance/consents/email/:address revokes that address's active consents (needs compliance:m or compliance:d); it answers 404 NOT_FOUND when none are active. Opt-outs and suppressions are separate and untouched.

This is how the API applies CASL, not legal advice about your own messages.

Suppressions

Hard bounces and spam complaints add an address to your suppression list automatically, and no email is sent to it again. An unsubscribe adds it too, but blocks commercial email only: receipts, password resets and other transactional email still reach the address. An address you block yourself gets no email at all. You can list suppressions, or remove one when the person asks to hear from you again.

const { data, error } = await honkio.suppressions.list({ reason: 'hard_bounce' })
if (error) throw new Error(error.message)
for (const s of data.data) console.log(s.email_address, s.reason, s.created_at)
// Sent with reason "manual", which every manual suppression has
const { error } = await honkio.suppressions.create({ emailAddress: 'ada@example.com' })
if (error) throw new Error(error.message)
const { error } = await honkio.suppressions.remove('ada@example.com')
if (error) throw new Error(error.message)