# Suppress many numbers at once (CSV upload)

Source: https://docs.usetone.ai/reference/compliance/dnc.addMany

> Up to 1,000 per request, as one transaction — it either all lands or none of it does.

`POST /v1/dnc/bulk`
Up to 1,000 per request, as one transaction — it either all lands or none of it does. This is how you bring an existing suppression list with you.

Requires the `write` scope.

## Request body

| Field | Type | | Meaning |
|---|---|---|---|
| `entries` | object[] | required | The suppressions to add, 1-1000. The whole batch is one transaction, so it either all lands or none of it does. |
| `entries[].e164` | string | required | The number to suppress, in E.164. Adding one already on the list is a no-op, not an error. |
| `entries[].lockout90d` | boolean | optional | Apply the TCCCPR 90-day re-consent lockout instead of suppressing permanently — the number becomes contactable again on a specific date rather than never. Only meaningful for an opt-out. |
| `entries[].reason` | string | optional | Why this number was suppressed. Free text, kept for the audit trail. |
| `entries[].source` | string | optional | Where the suppression came from. Recorded on the entry and shown in the evidence pack. Open set — handle an unrecognised value rather than throwing. Today: `manual`, `csv`, `api`, `caller_request`, `complaint`, `carrier_rejection`. |

### Example request

```json
{
  "entries": [
    {
      "e164": "+919876543210",
      "lockout90d": false,
      "reason": "Asked to be removed during a call on 2026-08-20.",
      "source": "manual"
    }
  ]
}
```

## Response



### Example response

```json
{
  "data": [
    {
      "createdAt": "2026-08-25T09:14:22Z",
      "e164": "+919876543210",
      "expiresAt": "2026-11-23T09:14:22Z",
      "id": "8814",
      "reason": "Asked to be removed during a call on 2026-08-20.",
      "removedAt": null,
      "removedReason": null,
      "source": "manual",
      "sourceCallId": null
    }
  ]
}
```
