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

# Submit a bulk end-user deletion request

POST https://example.ada.support/api/v2/end-users/delete
Content-Type: application/json

Submits a request to erase all personal data associated with the supplied identifiers. Replace `example` with your AI Agent's handle. A successful call returns a `202` with a `job_id` you can poll for status. Requests that set `client_reference` are idempotent for 24 hours: an identical resubmission within that window returns the original job instead of creating a new one. Requests that omit `client_reference` are not deduplicated. Separately, the erasure engine rejects an identifier submitted within the previous 7 days, and a single identifier in that cooldown can fail an entire job.

Reference: https://docs.ada.cx/reference/end-users/bulk-deletion/submit-a-bulk-end-user-deletion-request

## Request

### Body (application/json)

This endpoint expects a DeletionRequest.

- `identifiers` (list of DeletionIdentifier, required) — The identifiers to erase. At least one is required, and a single request accepts at most 1000.
- `client_reference` (string, optional, nullable) — Optional caller-supplied reference echoed back on the job. It is also the idempotency key: two identical requests that set the same reference within 24 hours resolve to the same job. Requests that omit it are not deduplicated.

## Response

### 202

The deletion request was accepted and a job was created.

- `job_id` (string, optional) — Identifier of the created deletion job. Use it to poll job status.
- `status` (enum, optional) — Lifecycle state of a deletion job. `queued` and `in_progress` are non-terminal; `completed`, `partial`, and `failed` are terminal.
  - Allowed values: `queued`, `in_progress`, `completed`, `partial`, `failed`
- `submitted_count` (integer, optional) — Number of identifiers received in the request.
- `created_at` (string, optional) — Time the job was created, in ISO 8601 format.

## Errors

### 400 Bad Request Error

Invalid request body, for example no identifiers.

- `any`

### 401 Unauthorized Error

Authentication token is missing or invalid. Try generating a new token.

- `any`

### 403 Forbidden Error

The token is not authorized to perform this operation.

- `any`

### 413 Content Too Large Error

The request body exceeds the maximum size of 512 KB. Split the identifiers across multiple requests.

- `any`

### 429 Too Many Requests Error

Too many requests. Retry after slowing the request rate.

- `any`

### 500 Internal Server Error

Something went wrong on Ada's end.

- `any`

## Types

### DeletionIdentifier

A single reference to the end user(s) whose data should be erased.

- `type` (enum, required) — The kind of identifier supplied. `variable_match` selects every end user whose stored variable equals the value.
  - Allowed values: `email`, `chatter_id`, `external_id`, `end_user_id`, `variable_match`
- `value` (string, required) — The identifier value. Email values are normalized and matched case-insensitively; `external_id` values are trimmed and lowercased at intake.
- `variable` (string, optional, nullable) — Name of the stored variable to match against `value`. Required only when `type` is `variable_match`; leave null for all other types.

## Examples

**Request**

```json
{
  "identifiers": [
    {
      "type": "email",
      "value": "end-user@example.com"
    },
    {
      "type": "end_user_id",
      "value": "6463dbcfafb2e65a02fbc5ee"
    },
    {
      "type": "variable_match",
      "value": "acme-corp",
      "variable": "company"
    }
  ],
  "client_reference": "ticket-4821"
}
```

**Response**

```json
{
  "job_id": "job_01HXW...ZK",
  "status": "queued",
  "submitted_count": 3,
  "created_at": "2026-07-10T14:05:00Z"
}
```

**SDK Code**

```python
import requests

url = "https://example.ada.support/api/v2/end-users/delete"

payload = {
    "identifiers": [
        {
            "type": "email",
            "value": "end-user@example.com"
        },
        {
            "type": "end_user_id",
            "value": "6463dbcfafb2e65a02fbc5ee"
        },
        {
            "type": "variable_match",
            "value": "acme-corp",
            "variable": "company"
        }
    ],
    "client_reference": "ticket-4821"
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://example.ada.support/api/v2/end-users/delete';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{"identifiers":[{"type":"email","value":"end-user@example.com"},{"type":"end_user_id","value":"6463dbcfafb2e65a02fbc5ee"},{"type":"variable_match","value":"acme-corp","variable":"company"}],"client_reference":"ticket-4821"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://example.ada.support/api/v2/end-users/delete"

	payload := strings.NewReader("{\n  \"identifiers\": [\n    {\n      \"type\": \"email\",\n      \"value\": \"end-user@example.com\"\n    },\n    {\n      \"type\": \"end_user_id\",\n      \"value\": \"6463dbcfafb2e65a02fbc5ee\"\n    },\n    {\n      \"type\": \"variable_match\",\n      \"value\": \"acme-corp\",\n      \"variable\": \"company\"\n    }\n  ],\n  \"client_reference\": \"ticket-4821\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://example.ada.support/api/v2/end-users/delete")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"identifiers\": [\n    {\n      \"type\": \"email\",\n      \"value\": \"end-user@example.com\"\n    },\n    {\n      \"type\": \"end_user_id\",\n      \"value\": \"6463dbcfafb2e65a02fbc5ee\"\n    },\n    {\n      \"type\": \"variable_match\",\n      \"value\": \"acme-corp\",\n      \"variable\": \"company\"\n    }\n  ],\n  \"client_reference\": \"ticket-4821\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://example.ada.support/api/v2/end-users/delete")
  .header("Content-Type", "application/json")
  .body("{\n  \"identifiers\": [\n    {\n      \"type\": \"email\",\n      \"value\": \"end-user@example.com\"\n    },\n    {\n      \"type\": \"end_user_id\",\n      \"value\": \"6463dbcfafb2e65a02fbc5ee\"\n    },\n    {\n      \"type\": \"variable_match\",\n      \"value\": \"acme-corp\",\n      \"variable\": \"company\"\n    }\n  ],\n  \"client_reference\": \"ticket-4821\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://example.ada.support/api/v2/end-users/delete', [
  'body' => '{
  "identifiers": [
    {
      "type": "email",
      "value": "end-user@example.com"
    },
    {
      "type": "end_user_id",
      "value": "6463dbcfafb2e65a02fbc5ee"
    },
    {
      "type": "variable_match",
      "value": "acme-corp",
      "variable": "company"
    }
  ],
  "client_reference": "ticket-4821"
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://example.ada.support/api/v2/end-users/delete");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"identifiers\": [\n    {\n      \"type\": \"email\",\n      \"value\": \"end-user@example.com\"\n    },\n    {\n      \"type\": \"end_user_id\",\n      \"value\": \"6463dbcfafb2e65a02fbc5ee\"\n    },\n    {\n      \"type\": \"variable_match\",\n      \"value\": \"acme-corp\",\n      \"variable\": \"company\"\n    }\n  ],\n  \"client_reference\": \"ticket-4821\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = [
  "identifiers": [
    [
      "type": "email",
      "value": "end-user@example.com"
    ],
    [
      "type": "end_user_id",
      "value": "6463dbcfafb2e65a02fbc5ee"
    ],
    [
      "type": "variable_match",
      "value": "acme-corp",
      "variable": "company"
    ]
  ],
  "client_reference": "ticket-4821"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://example.ada.support/api/v2/end-users/delete")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```