Consent Management

Log, query, and export TCPA consent records with the senderZ Compliance API.

Before you send a single message, US law requires that you have documented proof the recipient consented to hear from you. The Telephone Consumer Protection Act (TCPA) carries fines of $500 to $1,500 per unsolicited message, and the burden of proof falls on the sender. senderZ gives you a purpose-built Consent API so every consent record is timestamped, attributed, and exportable for audits.

TCPA defines three levels of consent. The type you need depends on what you are sending.

Required for marketing and promotional messages. The recipient must have signed a clear written agreement (physical or electronic) that specifically authorizes you to send marketing texts to their phone number. Web forms with a checkbox like “I agree to receive promotional texts from [Company]” count as express written consent, provided the language is clear and the checkbox is not pre-checked.

Required for transactional and informational messages such as appointment reminders, order confirmations, and account alerts. The recipient provides their phone number voluntarily in a context where they would reasonably expect to receive texts — for example, entering their number during checkout or on a support form.

The weakest form. Exists when there is an ongoing business relationship but no explicit opt-in. senderZ accepts implied consent records for your internal tracking, but we strongly recommend upgrading to express or express written consent for all contacts. Relying on implied consent is risky in a TCPA dispute.

POST /v1/compliance/consent

Create a consent record for a phone number.

Request Body

phone_number string Required

The phone number that gave consent, in E.164 format (e.g. +15551234567).

consent_type string Required

One of express_written, express, or implied.

consent_source string

How consent was collected. Common values: web_form, sms_keyword, api, manual, checkout_form, paper_form. You can pass any string value that describes your collection method.

ip_address string

The IP address of the person who consented, if collected via a web form. Strengthens your audit trail significantly.

Example Request

curl -X POST https://api.senderz.com/v1/compliance/consent \
  -H "Authorization: Bearer sz_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+15551234567",
    "consent_type": "express_written",
    "consent_source": "web_form",
    "ip_address": "203.0.113.42"
  }'
201 Created
{
  "data": {
    "id": "01JCNS789GHI",
    "phone_number": "+15551234567",
    "consent_type": "express_written",
    "consent_source": "web_form",
    "consented_at": "2026-04-15T10:30:00Z"
  }
}

What Gets Stored

Every consent record is written to the consent_log table with the following fields:

FieldDescription
idUnique record ID (ULID)
tenant_idYour tenant ID (set automatically from your API key)
phone_numberThe consenting phone number
consent_typeexpress_written, express, or implied
consent_sourceHow consent was collected
consented_atISO 8601 timestamp of when consent was given
ip_addressIP address, if provided
created_atWhen the record was written to senderZ

Records are immutable. You cannot update or delete a consent record — this is intentional. Audit trails must be tamper-proof. If a contact revokes consent, that is tracked separately through the opt-out system.

If you are migrating from another platform or importing an existing contact list, you can call POST /v1/compliance/consent in a loop for each contact. There is no dedicated batch endpoint, but the API supports up to 100 requests per second per tenant, so importing thousands of records takes only seconds.

for (const contact of contacts) {
  await fetch('https://api.senderz.com/v1/compliance/consent', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sz_live_YOUR_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      phone_number: contact.phone,
      consent_type: contact.consentType,
      consent_source: 'migration_import',
    }),
  })
}

You can export your full consent log as a CSV file from the developer portal. Navigate to Compliance > Consent Log > Export CSV. The export includes every consent record for your tenant, sorted by date.

Keep these exports stored securely for at least four years. TCPA enforcement actions can reference messages sent years ago, and your consent log is your primary defense.

Audit Readiness Checklist

A complete audit trail for any phone number should include:

  1. Consent record — When and how the recipient agreed to receive messages, logged via POST /v1/compliance/consent.
  2. Consent type — Express written for marketing, express for transactional.
  3. Source and IP — Where the consent was collected and from what IP address.
  4. Message history — Available via GET /v1/messages filtered by phone number.
  5. Opt-out record — If the recipient later texted STOP, the opt-out timestamp is in your opt-out list.

If you are ever asked to demonstrate compliance — by a carrier, a regulator, or in a legal proceeding — these five data points together form a defensible audit trail.

Best Practices

  1. Log consent at the moment it happens. Do not batch-log consent days later from memory. The timestamp matters.
  2. Use express_written for all marketing. It is the only consent type that fully protects you under TCPA for promotional messages.
  3. Include the consent source. “web_form” is more defensible than no source at all. Be specific — “signup_page_v2” is even better.
  4. Capture IP addresses from web forms. This is the strongest evidence that a real person submitted the form.
  5. Export monthly. Download your consent CSV once a month and store it in a secure, off-platform location. If senderZ is ever unreachable during an audit, you still have your records.
  6. Never pre-check consent checkboxes. Under TCPA and CTIA guidelines, consent must be affirmative. A pre-checked box does not count as express written consent.