Quiet hours, blocked messages in your log, and opt-out import

Three additions to the checks every send passes through. The full list, in order, is now at Compliance checks.

  • Quiet hours. A marketing message outside 8:00am to 9:00pm in the recipient's local time (read from the area code) is refused with 403 quiet_hours, or held until 8:00am with "quiet_hours": "defer". Broadcasts, batches, recurring schedules and automations hold by default, recipient by recipient.
  • category (marketing, transactional, otp) on POST /v1/messages, batches and schedules. Without it, broadcasts and numbers registered for Marketing are marketing and everything else is transactional, so codes, receipts and alerts are unaffected.
  • Who will notice. If you send from a number registered for the Marketing use case, or send broadcasts, messages that fall in a recipient's quiet hours are now refused or held. Turn the check off in Console → Compliance if you handle quiet hours yourself.
  • Blocked messages are in your log. Every send we refuse (opted out, quiet hours, unregistered sender, content, allowance, spend limit, credits) is stored with status: "blocked" and a failure reason, and is never charged. GET /v1/messages?status=blocked, blocked_reason and failure_code filters, a Blocked filter in Logs, and reason columns in the CSV export.
  • message.blocked now fires for every blocked send, not only opt-outs, and carries message_id. New event: message.deferred.
  • Bring your opt-outs. A migration now asks for the opt-out list from your previous provider, or your confirmation that there is none, before it runs. See Opt-out.
  • Sandbox: +15005550015 is always in quiet hours.
  • Node and Python SDKs 2.4.0: category and quietHours (quiet_hours in Python) on messages.send, the quiet_hours error code with sendAfter, and the blocked status.

All changes