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

# Do-not-call list

> Your workspace's own suppression list — numbers campaigns will never dial.

The **do-not-call list** is a per-workspace set of phone numbers that
[campaigns](/v2/campaigns) will not dial. Add a number and every campaign in the
workspace — running, paused or not yet created — skips it.

Base URL `https://sandbox.voice.miraiminds.co`.

<Warning>
  **This is your suppression list, not the national registry.**

  It suppresses *your* campaigns on *our* platform. It is not TRAI's DND/NCPR
  register, we do not scrub against that register for you, and having a number on
  this list is not a substitute for the consent and DND obligations that sit with
  the business placing the calls. See
  [India calling rules](/v2/limits#india-calling-rules).
</Warning>

## How suppression works

Numbers are checked **at dial time**, in the same database statement that hands
contacts to the dialler. Three consequences worth knowing:

* **Late additions work.** A number added while a campaign is running is
  suppressed from that moment on, even though it was uploaded in the original
  list.
* **Suppression is not deletion.** The contact stays in the campaign with
  [`status: "suppressed"`](/v2/campaigns#contact-statuses) and shows up in the
  report, so you can prove the number was uploaded and not called.
* **Suppressed contacts are never billed.** No dial, no minute, no charge.

It does **not** apply to [`POST /v2/calls`](/v2/calls#create-a-call). A direct
single call is an explicit instruction to ring one number now; refusing it based
on a list would silently swallow transactional calls — a delivery confirmation
to a customer who opted out of marketing, say. Check the list yourself before
placing single calls if that is the behaviour you want.

## The entry object

```json theme={null}
{
  "object": "dnc_entry",
  "phone": "+919876543210",
  "created_at": "2026-08-10T09:44:12Z"
}
```

***

## Add a number

```http theme={null}
POST /v2/dnc
```

```bash theme={null}
curl -X POST https://sandbox.voice.miraiminds.co/v2/dnc \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+919876543210" }'
```

```json title="201 Created" theme={null}
{ "object": "dnc_entry", "phone": "+919876543210", "added": true }
```

Adding a number that is already on the list is **not an error** — you asked for
it to be suppressed and it is suppressed. You get `200 OK` with
`"added": false` instead of `201`:

```json title="200 OK — already on the list" theme={null}
{ "object": "dnc_entry", "phone": "+919876543210", "added": false }
```

Branch on `added` if you are keeping your own count; branch on nothing at all if
you are just making sure. Both answers mean the number will not be dialled.

| Status | `error.code`            | Cause                                                                   |
| :----- | :---------------------- | :---------------------------------------------------------------------- |
| `400`  | `invalid_request`       | `phone` is not E.164 — `+919876543210`, not `9876543210`.               |
| `503`  | `campaigns_unavailable` | Campaigns (and with them this list) are not enabled for your workspace. |

***

## List numbers

```http theme={null}
GET /v2/dnc?limit=&cursor=
```

```bash theme={null}
curl -G https://sandbox.voice.miraiminds.co/v2/dnc \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  --data-urlencode "limit=100"
```

```json title="200 OK" theme={null}
{
  "data": [
    { "object": "dnc_entry", "phone": "+919876543210", "created_at": "2026-08-10T09:44:12Z" },
    { "object": "dnc_entry", "phone": "+919812345678", "created_at": "2026-08-09T16:02:55Z" }
  ],
  "has_more": false,
  "next_cursor": null
}
```

Standard [pagination](/v2/overview#pagination): `limit` 1–100, default 20, and
`cursor` from `next_cursor`.

***

## Remove a number

```http theme={null}
DELETE /v2/dnc/{phone}
```

The number goes in the path, URL-encoded — `+` becomes `%2B`.

```bash theme={null}
curl -X DELETE "https://sandbox.voice.miraiminds.co/v2/dnc/%2B919876543210" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```

`204 No Content` on success. `404 not_found` if the number was not on the list.

<Warning>
  **Removing a number un-suppresses it immediately.** Contacts already marked
  `suppressed` in a campaign stay marked — that status is a record of a decision
  already taken — but any future campaign, and any contact not yet claimed, will
  dial it. Keep an audit trail of who removed what: an opt-out you reversed is the
  complaint you will be asked about.
</Warning>

***

## Keeping it in sync

The list is a set of numbers, and the operations are idempotent, so the simplest
correct integration is also the right one: on every opt-out event in your own
system, `POST` the number. No read-modify-write, no diffing.

```python theme={null}
def on_opt_out(phone: str) -> None:
    r = httpx.post(f"{API}/v2/dnc", headers=auth, json={"phone": phone}, timeout=30)
    if r.status_code not in (200, 201):
        raise RuntimeError(r.json()["error"]["message"])
    # 201 -> newly added, 200 -> already there. Both mean suppressed.
```

Three habits worth having:

1. **Suppress on the call, not after the campaign.** If your agent hears "stop
   calling me", write it to the list from the webhook handler that same minute.
2. **Suppress before you upload.** Scrubbing the list you upload *and* keeping
   the DNC list current are belt and braces; the DNC list is the one that
   protects you from the campaign you forgot to scrub.
3. **Never remove in bulk.** Removals should be individual, deliberate, and
   logged with a reason.
