Skip to main content

Contact compliance

This is the product's central guarantee: no message goes out without passing through the compliance engine — evaluated immediately before each send, with the freshest state from the database, not as a static configuration checked once a day. Collecting at the wrong time, on the wrong day or from the wrong person is not just bad practice: depending on the state, it is a legal violation.

The veto order

Before every send, the engine evaluates four barriers, in this order. The first one that fails decides the message's fate:

  1. Active suppression — overrides any step condition. If a suppression covering the person, the debt or the channel exists, the message is suppressed (it does not go out, with the reason recorded).
  2. legal hold — a charge under legal hold generates no contact at all.
  3. Legal window of the jurisdiction — outside the allowed time window for the debtor's state, the message is rescheduled to the next opening, never dropped.
  4. Per-person limits — daily cap, weekly cap and minimum interval between contacts. Exceeded, it is rescheduled.

The outcome is always one of three: send, suppress (with a typed reason) or reschedule (with the next allowed time computed). Everything is recorded.

There is no "national window" in Brazilian law — collection-hours rules are state-level. The system maintains a library of policies per jurisdiction, versioned and with effective dates:

  • São Paulo (BR-SP) — Lei estadual 15.426/2014 (São Paulo state contact-hours law): Monday to Friday 8am–8pm, Saturday 8am–2pm; prohibited on Sundays and holidays.
  • Conservative national default (BR) — applied when no state law is mapped for the debtor's state: the same conservative window (Mon–Fri 8am–8pm, Sat 8am–2pm, Sundays and holidays prohibited).

The jurisdiction comes from the state (UF) of the debtor's address; a debtor without a valid state on file falls under the conservative national rule. The policy can also vary by channel and by person type (individual/company), and resolution follows this precedence: your organization's rule for the specific state → the state rule in the legal library → your organization's national rule → the national rule in the library. If nothing matches, the conservative default built into the code applies.

Times are evaluated in the organization's timezone (default America/Sao_Paulo).

Holidays

When the policy prohibits holidays (the default), the engine blocks national holidays: the fixed ones (Jan 1st, Tiradentes, May 1st, Sep 7th, Oct 12th, Nov 2nd, Nov 15th, Black Awareness Day — Lei 14.759/2023 (the law that made it a national holiday) — and Christmas) and the movable ones computed from Easter (Carnival Monday and Tuesday, Good Friday and Corpus Christi). A send that would land on a holiday is rescheduled to the next day with an open window.

Per-person limits — not per charge

Frequency limits apply to the person, summing across all channels, all charges and all collection rules. A debtor with five debts does not receive five times more messages.

LimitDefault
Maximum per day2 contacts
Maximum per week6 contacts
Minimum interval between contacts4 hours

These are the conservative defaults; they can be customized per organization (the account's contactPolicy setting). Only messages actually sent/delivered/read count toward the limit — suppressions and failures do not consume quota. If the cap is exceeded, the send is rescheduled.

Suppressions: why a contact must NOT happen

A suppression is a typed record, with scope and evidence — different from a channel preference. "I don't want WhatsApp" is one thing; "this debt must not be collected" is another. The 12 types:

TypeSituation
opt_outDebtor asked not to be contacted
third_partyThird-party contact (the well-known "not me")
invalid_contactInvalid email/phone
deceasedDeceased person
fraudSuspected fraud
disputeOpen dispute over the debt
judicialCourt order
lawyer_representedDebtor represented by a lawyer
bankruptcyJudicial reorganization / bankruptcy
prescriptionTime-barred debt
vulnerablePerson in a situation of vulnerability
channel_blockedChannel blocked by the provider

Each suppression has a scope: it can apply to a person, to a specific debt, or both — and to a specific channel or all of them (empty channel = all). It also has effective dates (activeFrom/expiresAt) and can be revoked with a record. During evaluation, a single active suppression covering the person or the debt, on the channel in question or on all channels, is enough to veto the send — and suppression takes precedence over everything: step conditions, campaigns, operational urgency.

Creating and revoking suppressions enters the audit trail with type, scope, origin and evidence.

Rescheduling — never a silent drop

When the veto is time-based (outside the window, daily/weekly limit, minimum interval), the engine computes the next allowed moment — today's window opening, the start of the next business day with an open window, or the end of the minimum interval — and reschedules. The message does not vanish: it goes out at the first legal opportunity, and the record shows the reason for the delay (outside_legal_window_BR-SP, daily_contact_limit, min_contact_interval...).

Last line of defense: revalidation in the worker

Compliance at scheduling time is not enough: the payment may arrive with the job already queued. That is why the worker revalidates everything immediately before handing off to the provider: charge paid, cancelled, written off or negotiated, an "I already paid" claim pending verification, legal hold and a paused rule — any of these blocks the send at the last millisecond, with the reason recorded.