> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.voicebip.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.voicebip.com/_mcp/server.

# Contact Erasure (NDPR Right to Erasure)

> How to permanently anonymize a phone number's data using DELETE /v1/contacts/{e164}.

NDPR Article 3.1(9) gives data subjects the right to have their personal data erased. When one of your end-users makes that request, you fulfill it by calling `DELETE /v1/contacts/{e164}`. The operation runs atomically across your workspace's call and message history and is irreversible.

## The request

```bash
curl -X DELETE "https://api.voicebip.com/v1/contacts/+2348031234567" \
  -H "Authorization: Bearer pk_live_xxx"
```

The `{e164}` path parameter must be a valid E.164 number (leading `+`, 7–15 digits). Nigerian numbers look like `+2348031234567`.

## The response

```json
{
  "erased": true,
  "e164": "+2348031234567",
  "records_affected": 12
}
```

`records_affected` is the combined count of call records and message records that were modified. A value of `0` is valid — it means the number had no history in your workspace.

## What gets anonymized

The operation is scoped to **your workspace only**. It touches two tables:

| Data type        | What happens                                                                                                                      |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Call transcripts | Replaced with `["[REDACTED]"]`. The call record row is kept (for your own call-count analytics), but the transcript text is gone. |
| Call recordings  | `recording_url` is set to `NULL`. The audio file is no longer accessible.                                                         |
| Message bodies   | Replaced with `[REDACTED]`. The message row is kept, but the content is gone.                                                     |

Phone numbers on the call and message rows (`from_number`, `to_number`) are **not** hashed or removed — the rows need to stay linked to your agents and conversations. Only the content fields that carry the data subject's words are anonymized.

An entry is written to `voicebip_v1.audit_log` with `action = 'data.erasure'` and `reason = 'ndpr_right_to_erasure'` so you have a compliance paper trail.

## Opt-out lists are not affected

Calling this endpoint does **not** remove the number from any opt-out record. If the contact previously sent `STOP` to one of your SMS agents, that opt-out flag stays in place. This is intentional: erasing content history is a separate concern from suppression. If you want to also clear the opt-out flag after erasure — for example, because the user wants a fresh start — you would need to do that through a separate internal operation; there is no public API endpoint for that today.

## Idempotency

The call is safe to make more than once for the same number. If there is nothing left to anonymize, `records_affected` returns `0` and `erased` is still `true`. No error is raised.

## Error responses

| HTTP status | `error_code`       | Meaning                        |
| ----------- | ------------------ | ------------------------------ |
| `400`       | `INVALID_ARGUMENT` | `e164` is missing or malformed |
| `401`       | `UNAUTHORIZED`     | Invalid or missing API key     |

## Build a "Delete my data" flow, not a bulk job

NDPR right-to-erasure requests come from individual data subjects. The right pattern is a user-triggered flow in your product UI — a "Delete my data" button that calls this endpoint for the requesting user's number. Bulk-erasing all contacts as a routine cleanup job is not what this endpoint is for; use your workspace's configured retention period for that.

A minimal server-side handler:

```typescript
// Node.js / Express example
app.post('/user/delete-my-data', requireAuth, async (req, res) => {
  const userPhone = req.user.phone; // E.164, from your auth system

  const response = await fetch(
    `https://api.voicebip.com/v1/contacts/${encodeURIComponent(userPhone)}`,
    {
      method: 'DELETE',
      headers: { Authorization: `Bearer ${process.env.VOICEBIP_API_KEY}` },
    }
  );

  if (!response.ok) {
    return res.status(500).json({ error: 'erasure_failed' });
  }

  const { records_affected } = await response.json();
  // Log locally, email the user confirmation, etc.
  res.json({ erased: true, records_affected });
});
```

Keep your own record of when the erasure was completed — you may need to demonstrate compliance to NITDA.