> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendora.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# DNC List

> Manage your Do-Not-Contact list to ensure compliant outreach.

## Overview

The **DNC (Do Not Contact) list** is a workspace-wide blocklist. Any lead whose phone number or email appears on the DNC list will never receive outreach from Sendora, the system checks this list at every point in the campaign journey before placing a call, sending an SMS, or sending an email.

You can manage the DNC list via API to:

* Sync opt-outs from external CRMs or unsubscribe pages
* Bulk-upload phone numbers or emails that should never be contacted
* Remove entries that were added in error

## Adding a DNC entry

```bash theme={"dark"}
curl -X POST https://api.sendora.ai/api/v1/public/dnc \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14155550100",
    "reason": "Customer requested no further contact"
  }'
```

Either `phone` or `email` (or both) must be provided:

```json theme={"dark"}
{ "email": "john@example.com", "reason": "Unsubscribed via email link" }
```

```json theme={"dark"}
{ "phone": "+14155550100", "email": "john@example.com", "reason": "TCPA opt-out" }
```

## Listing DNC entries

```bash theme={"dark"}
GET /api/v1/public/dnc?page=1&limit=50
```

Supports `search` to filter by phone or email:

```bash theme={"dark"}
GET /api/v1/public/dnc?search=john@example.com
```

Returns:

```json theme={"dark"}
{
  "items": [
    {
      "id": "dnc_abc123",
      "phone": null,
      "email": "john@example.com",
      "reason": "Unsubscribed via email link",
      "created_at": "2026-06-10T09:30:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "per_page": 50
}
```

## Removing a DNC entry

If an entry was added in error, remove it:

```bash theme={"dark"}
DELETE /api/v1/public/dnc/{entry_id}
```

Returns `204 No Content`. The operation is idempotent, deleting a non-existent entry returns 204.

<Warning>
  Removing a DNC entry re-enables outreach to that contact. Only do this when you have explicit opt-in consent.
</Warning>

## How DNC enforcement works

Before every outreach action, Sendora runs a DNC preflight check:

1. Looks up the lead's phone number and email in the DNC table
2. If found → the step is skipped and logged as `dnc_blocked`
3. The lead's `status` is set to `dnc` and `automation_paused = true`
4. All further campaign steps for that lead are cancelled

This check happens server-side regardless of how the lead was enrolled, there is no way to bypass it through the API.

## Syncing opt-outs from external systems

A common pattern: catch unsubscribes/opt-outs from your email provider or CRM webhook and immediately write them to Sendora's DNC list.

```python theme={"dark"}
# Example: process a Mailchimp unsubscribe webhook
@app.post("/hooks/mailchimp")
async def mailchimp_hook(payload: dict):
    if payload.get("type") == "unsubscribe":
        email = payload["data"]["email"]
        await sendora.post("/api/v1/public/dnc", json={
            "email": email,
            "reason": "Mailchimp unsubscribe"
        })
    return {"ok": True}
```

## Compliance notes

* TCPA requires honoring opt-out requests within 10 business days. Adding immediately via this API satisfies that.
* CAN-SPAM / CASL opt-outs are handled automatically when a lead clicks an unsubscribe link in a Sendora email, they are added to DNC and the `reply.received` webhook fires so your system can sync.
* If you maintain a suppression list in your CRM, sync it to Sendora's DNC list before launching any campaign.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.