Revoke one consent record
⚠️ Revoking consent does NOT stop calls on its own: the ledger passes or warns, it never blocks. Only the suppression list blocks. If the recipient asked not to be called, use the opt-out endpoint, which revokes and suppresses in one transaction.
Requires the write scope. A key with less gets 403 insufficient_scope.
Authorization: Bearer tone_live_… or tone_test_…. The prefix IS the environment: a test key reaches only the sandbox, and no request field bridges the two.
In: header
Path Parameters
The consent record's id.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/consent/string/revoke" \ -H "Content-Type: application/json" \ -d '{ "reason": "Recipient asked to be removed by email." }'{ "data": { "active": true, "capturedAt": "2026-08-20T11:02:00Z", "createdAt": "2026-08-25T09:14:22Z", "e164": "+919876543210", "evidenceRef": "form-sub-88213", "expiresAt": "2026-11-23T09:14:22Z", "id": "8814", "kind": "explicit", "purpose": "promotional", "revokedAt": null, "revokedReason": null, "scope": "Order updates and delivery reminders.", "source": "api" }}Import many consents at once (CSV upload, CRM export)
Up to 1,000 per request. Rows are accepted INDIVIDUALLY: a record that violates policy (an inferred consent missing expiresAt, a number inside its 90-day opt-out lockout) is refused with its index and reason while the rest import — fix and resubmit only the rejected rows. 🔴 Set capturedAt on every imported record: it defaults to now, which dates your whole back catalogue to the day of the import.
Suppress a number (idempotent)
Adding a number already on the list is a no-op rather than an error, so a replayed webhook or a retried job cannot fail here. Use lockout90d for an opt-out, which becomes contactable again on a date, rather than a permanent suppression.