The pre-dial gate
Five checks that run before every call, and the audit rows they leave whether they pass or block.
India regulates who may be called, about what, and when. TCCCPR liability sits with the sender — you — and there is no statutory safe harbour for using a vendor. What Tone can do is run the checks and keep the evidence that you ran them.
What runs, in order
Every dial — direct, campaign, or BYO — runs all six, inside the same transaction as the call record.
| # | Check | Can block? | |
|---|---|---|---|
| 1 | dlt | no — warns | Your registration and whether the from-number suits the purpose |
| 2 | a2p | no — warns | Whether an auto-dialer pre-declaration is on file with your access provider |
| 3 | time_window | yes | The calling band for the agent's purpose, in IST |
| 4 | dnc | yes | Your suppression list — the only list we hard-block on |
| 5 | carrier_dnd | never | Carrier metadata, advisory only |
| 6 | consent | no — warns, promotional only | Whether consent is on record. A valid consent also overrides a carrier DND flag — never a suppression |
Each writes a row with an outcome of pass, warn or block, whatever it
decided. The table is append-only at the database level: nothing can edit or
delete a check after the fact, which is the entire point of having one.
curl -H "Authorization: Bearer $TONE_KEY" \
"$TONE_API/v1/compliance/checks?e164=%2B919876543210&outcome=block"The A2P pre-declaration
TCCCPR regulation 4 requires notifying your Originating Access Provider, in
writing and in advance, that auto-dialer / robo-call technology is in use.
File the declaration with your access provider, then record its reference
under Compliance → Auto-dialer pre-declaration — the a2p check warns on
every call placed without one, on every purpose, and each evidence record
cites the declaration when it exists.
Why carrier DND only warns
The authoritative Do-Not-Call register is deliberately not exposed to telemarketers — that is its design, not an oversight. What a carrier returns is metadata, and the carrier disclaims it. Blocking on advisory data would silently drop legitimate calls and give you no way to tell which; passing it through labelled as advisory lets you decide.
🔴 Tone does not claim authoritative NCPR scrubbing, and you should not either. What we block on is your own suppression list plus cross-customer opt-outs, labelled as such.
Calling windows
Narrowed from the industry default of 08:00 because we cannot read an individual recipient's registered preference band, so the safe assumption is the tightest one.
| Purpose | Window (IST) | Basis |
|---|---|---|
promotional | 09:00 – 21:00 | TCCCPR preference band |
collections | 08:00 – 19:00 | RBI recovery-agent rules |
service | none | Schedule II — may not be blocked |
transactional | none | Schedule II — may not be blocked |
There is no override, and no request field reaches the gate. A caller who could opt out of being checked would make every audit row meaningless.
Where purpose comes from
From durable configured state, never from the request:
- A Tone agent supplies its own
purpose. - A BYO number has no agent, so the organization's declared sender
classification is used. Set it in the dashboard under Telephony → Compliance
→ Sender classification; dialling before declaring one is a
422.
Checking without dialling
If you dial on your own carrier, ask for the verdict directly. It writes the same
audit rows a dial writes, and answers 200 either way — a refusal is a verdict,
not an error.
curl "$TONE_API/v1/compliance/check" -X POST \
-H "Authorization: Bearer $TONE_KEY" -H 'content-type: application/json' \
-d '{"e164":"+919876543210","purpose":"promotional"}'See Compliance as an API.
When a call is blocked
403, with error.code naming which check stopped it:
| Code | From |
|---|---|
blocked_dnd | dnc, carrier_dnd or a stale scrub |
blocked_opt_out | consent, time_window, or a recorded outcome |
blocked_dlt_invalid | dlt or a2p |
error.details carries checkType and reason, and the audit row is already
written — so a block is fully explainable after the fact from
GET /v1/compliance/evidence.
Sealed evidence records
Beyond the raw audit rows, every call attempt — completed calls and refused dials — produces one sealed evidence record: the legal basis to call (your DNC result, the consent record relied on, the carrier signal), how the call was placed (DLT registration, A2P declaration, calling window, the number's status at dial time, whether the AI disclosure was spoken and when), and the outcome.
Each record carries a sha256 of its canonical content plus the previous record's hash, forming a per-organisation chain: editing any record breaks its own hash, and deleting or reordering one breaks every later link.
# the record for one call, or the same as a PDF at /evidence.pdf
curl -H "Authorization: Bearer $TONE_KEY" \
"$TONE_API/v1/calls/{id}/evidence"
# prove the chain's integrity, on demand
curl -H "Authorization: Bearer $TONE_KEY" \
"$TONE_API/v1/compliance/evidence-records/verify"The table is append-only at the database level, and its rows survive even an organisation deletion. Records seal shortly after a call ends; a refused dial seals in the same transaction as its refusal.