# Erase Recipients' Email Data

## API Overview

The Recipients' Data Erasure API allows Twilio SendGrid customers to delete their own customers' email-related personal data from the Twilio SendGrid Platform. This feature helps customers comply with data privacy regulations.

> \[!NOTE]
>
> The Recipients' Data Erasure API isn't enabled for all customers by default.
>
> * **For customers who signed up after July 25, 2023**: This API is already enabled for your account.
> * **For customers who signed up before July 25, 2023**: Check your account scopes by making a `GET /v3/scopes` request. If the `recipients.erasejob.read` and `recipients.erasejob.create` scopes are missing, contact [Support](https://support.sendgrid.com/hc/en-us) to enable them.

## Operation overview

```json
{"path":"https://api.sendgrid.com/v3/recipients/erasejob","method":"post","servers":[{"url":"https://api.sendgrid.com","description":"for global users and subusers"},{"url":"https://api.eu.sendgrid.com","description":"for EU regional subusers"}]}
```

**This operation allows you to delete your recipients' personal email data**

The Delete Recipients' Email Data operation accepts a list of 5,000 `email_addresses` or a total payload size of 256Kb per request, whichever comes first. Upon a successful request with this operation, SendGrid will run a search on the email addresses provided against the SendGrid system to identify matches. SendGrid will then delete all personal data associated with the matched users such as the recipients' names, email addresses, subject lines, categories, and IP addresses.

This endpoint is rate limited to 100 requests per minute. If more requests need to be made, consider using the batch option to include multiple email addresses in each request (up to 5,000 addresses per request).

All email addresses are filtered for uniqueness and tested for structural validity—any invalid addresses will be returned in an error response.

Please note that recipient data is deleted for the account making the request only—deletions do not cascade from a parent account to its Subusers' recipients. To delete a Subuser's recipients' data, you can use the `on-behalf-of` header.

## Operation details

### Authentication

API Key

### Headers

```json
[{"in":"header","name":"Authorization","required":true,"default":"Bearer <<YOUR_API_KEY_HERE>>","schema":{"type":"string"}},{"name":"on-behalf-of","in":"header","description":"The `on-behalf-of` header allows you to make API calls from a parent account on behalf of the parent's Subusers or customer accounts. You will use the parent account's API key when using this header. When making a call on behalf of a customer account, the property value should be \"account-id\" followed by the customer account's ID (e.g., `on-behalf-of: account-id <account-id>`). When making a call on behalf of a Subuser, the property value should be the Subuser's username (e.g., `on-behalf-of: <subuser-username>`). See [**On Behalf Of**](/docs/sendgrid/api-reference/how-to-use-the-sendgrid-v3-api/on-behalf-of) for more information.","required":false,"schema":{"type":"string"},"refName":"#/components/parameters/OnBehalfOf","modelName":"__components_parameters_OnBehalfOf"}]
```

### Request body

```json
{"schema":{"title":"EmailAddress","type":"object","required":["email_addresses"],"example":{"email_addresses":["user1@example.com","user2@example.com"]},"refName":"RecipientsDataErasureEraseRecipientsRequest","modelName":"RecipientsDataErasureEraseRecipientsRequest","properties":{"email_addresses":{"type":"array","description":"List of unique recipient email addresses whose PII will be erased. You may include a maximum of 5,000 addresses or a maximum payload size of 256Kb, whichever comes first.","maxItems":5000,"minItems":1,"items":{"type":"string"}}}},"example":{"email_addresses":["user1@example.com","user2@example.com"]},"encodingType":"application/json"}
```

### Responses

```json
[{"responseCode":"202","schema":{"description":"The request was accepted for processing","content":{"application/json":{"schema":{"title":"JobId","type":"object","required":["job_id"],"example":{"job_id":"12a975bd-c742-4713-8f47-cb3ae4e56c74"},"refName":"RecipientsDataErasureJobId","modelName":"RecipientsDataErasureJobId","properties":{"job_id":{"type":"string","description":"The job ID associated with the data erasure request."}}}}}}},{"responseCode":"400","schema":{"description":"The request was formatted incorrectly or missing required parameters.","content":{"application/json":{"schema":{"title":"Bad Request","type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"title":"Error","type":"object","required":["message","field"],"refName":"RecipientsDataErasureErrorV1","modelName":"RecipientsDataErasureErrorV1","properties":{"message":{"type":"string","description":"The message representing the error from the API"},"field":{"type":"string","description":"The field associated with the error"}}}}}},"example":{"errors":[{"message":"Email_address user1@gml.com is not valid","field":"email_addresses"}]}}},"headers":{"X-RateLimit-Limit":{"description":"The number of requests allowed during the  window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"The amount of time (in seconds) until the current window is over and the limit is reset","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"The number of request remaining in the 60-second window before encountering a 429 error.","schema":{"type":"integer"}}},"refName":"#/components/responses/RecipientsDataErasure400","modelName":"__components_responses_RecipientsDataErasure400"}},{"responseCode":"401","schema":{"description":"Request lacks valid authentication credentials","headers":{"X-RateLimit-Limit":{"description":"The number of requests allowed during the  window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"The amount of time (in seconds) until the current window is over and the limit is reset","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"The number of request remaining in the 60-second window before encountering a 429 error.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"Unauthorized","type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"title":"Error","type":"object","required":["message","field"],"refName":"RecipientsDataErasureErrorV1","modelName":"RecipientsDataErasureErrorV1","properties":{"message":{"type":"string","description":"The message representing the error from the API"},"field":{"type":"string","description":"The field associated with the error"}}}}}},"example":{"errors":[{"message":"Failed to authenticate","field":""}]}}},"refName":"#/components/responses/RecipientsDataErasure401","modelName":"__components_responses_RecipientsDataErasure401"}},{"responseCode":"403","schema":{"description":"Not authorized to make the request","headers":{"X-RateLimit-Limit":{"description":"The number of requests allowed during the  window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"The amount of time (in seconds) until the current window is over and the limit is reset","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"The number of request remaining in the 60-second window before encountering a 429 error.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"Forbidden","type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"title":"Error","type":"object","required":["message","field"],"refName":"RecipientsDataErasureErrorV1","modelName":"RecipientsDataErasureErrorV1","properties":{"message":{"type":"string","description":"The message representing the error from the API"},"field":{"type":"string","description":"The field associated with the error"}}}}}},"example":{"errors":[{"message":"Not authorized","field":""}]}}},"refName":"#/components/responses/RecipientsDataErasure403","modelName":"__components_responses_RecipientsDataErasure403"}},{"responseCode":"404","schema":{"description":"Not Found","headers":{"X-RateLimit-Limit":{"description":"The number of requests allowed during the  window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"The amount of time (in seconds) until the current window is over and the limit is reset","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"The number of request remaining in the 60-second window before encountering a 429 error.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"Not Found","type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"title":"Error","type":"object","required":["message","field"],"refName":"RecipientsDataErasureErrorV1","modelName":"RecipientsDataErasureErrorV1","properties":{"message":{"type":"string","description":"The message representing the error from the API"},"field":{"type":"string","description":"The field associated with the error"}}}}}},"example":{"errors":[{"message":"Not Found","field":""}]}}},"refName":"#/components/responses/RecipientsDataErasure404","modelName":"__components_responses_RecipientsDataErasure404"}},{"responseCode":"429","schema":{"description":"User has sent too many requests in a given amount of time","headers":{"X-RateLimit-Limit":{"description":"The number of requests allowed during the  window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"The amount of time (in seconds) until the current window is over and the limit is reset","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"The number of request remaining in the 60-second window before encountering a 429 error.","schema":{"type":"integer"}},"X-Envoy-Ratelimited":{"description":"Indicating that you've been ratelimited","schema":{"type":"boolean"}}},"refName":"#/components/responses/RecipientsDataErasure429","modelName":"__components_responses_RecipientsDataErasure429"}},{"responseCode":"500","schema":{"description":"Internal Server Error","headers":{"X-RateLimit-Limit":{"description":"The number of requests allowed during the  window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"The amount of time (in seconds) until the current window is over and the limit is reset","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"The number of request remaining in the 60-second window before encountering a 429 error.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"Internal Server Error","type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"title":"Error","type":"object","required":["message","field"],"refName":"RecipientsDataErasureErrorV1","modelName":"RecipientsDataErasureErrorV1","properties":{"message":{"type":"string","description":"The message representing the error from the API"},"field":{"type":"string","description":"The field associated with the error"}}}}}},"example":{"errors":[{"message":"Internal Server Error","field":""}]}}},"refName":"#/components/responses/RecipientsDataErasure500","modelName":"__components_responses_RecipientsDataErasure500"}}]
```

Erase Recipients' Email Data

```js
const client = require("@sendgrid/client");
client.setApiKey(process.env.SENDGRID_API_KEY);

const data = {
  email_addresses: ["user1@example.com", "user2@example.com"],
};

const request = {
  url: `/v3/recipients/erasejob`,
  method: "POST",
  body: data,
};

client
  .request(request)
  .then(([response, body]) => {
    console.log(response.statusCode);
    console.log(response.body);
  })
  .catch((error) => {
    console.error(error);
  });
```

```python
import os
from sendgrid import SendGridAPIClient


sg = SendGridAPIClient(os.environ.get("SENDGRID_API_KEY"))

data = {"email_addresses": ["user1@example.com", "user2@example.com"]}

response = sg.client.recipients.erasejob.post(request_body=data)

print(response.status_code)
print(response.body)
print(response.headers)
```

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using SendGrid;

public class Program {
    public static async Task Main() {
        string apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");
        var client = new SendGridClient(apiKey);

        var data =
            @"{
            ""email_addresses"": [
                ""user1@example.com"",
                ""user2@example.com""
            ]
        }";

        var response = await client.RequestAsync(
            method: SendGridClient.Method.POST, urlPath: "recipients/erasejob", requestBody: data);

        Console.WriteLine(response.StatusCode);
        Console.WriteLine(response.Body.ReadAsStringAsync().Result);
        Console.WriteLine(response.Headers.ToString());
    }
}
```

```java
import com.sendgrid.*;
import java.io.IOException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Arrays;

public class Example {
    public static void main(String[] args) throws IOException {
        try {
            SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
            Request request = new Request();
            request.setMethod(Method.POST);
            request.setEndpoint("/recipients/erasejob");
            request.setBody(new JSONObject(new HashMap<String, Object>() {
                {
                    put("email_addresses", Arrays.asList("user1@example.com", "user2@example.com"));
                }
            }).toString());
            Response response = sg.api(request);
            System.out.println(response.getStatusCode());
            System.out.println(response.getBody());
            System.out.println(response.getHeaders());
        } catch (IOException ex) {
            throw ex;
        }
    }
}
```

```go
package main

import (
	"fmt"
	"github.com/sendgrid/sendgrid-go"
	"os"
)

func main() {
	apiKey := os.Getenv("SENDGRID_API_KEY")
	host := "https://api.sendgrid.com"
	request := sendgrid.GetRequest(apiKey, "/v3/recipients/erasejob", host)
	request.Method = "POST"
	request.Body = []byte(`{
  "email_addresses": [
    "user1@example.com",
    "user2@example.com"
  ]
}`)
	response, err := sendgrid.API(request)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	} else {
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
	}
}
```

```php
<?php
// Uncomment the next line if you're using a dependency loader (such as Composer) (recommended)
// require 'vendor/autoload.php';

// Uncomment next line if you're not using a dependency loader (such as Composer)
// require_once '<PATH TO>/sendgrid-php.php';

$apiKey = getenv("SENDGRID_API_KEY");
$sg = new \SendGrid($apiKey);
$request_body = json_decode('{
    "email_addresses": [
        "user1@example.com",
        "user2@example.com"
    ]
}');

try {
    $response = $sg->client
        ->recipients()
        ->erasejob()
        ->post($request_body);
    print $response->statusCode() . "\n";
    print_r($response->headers());
    print $response->body() . "\n";
} catch (Exception $ex) {
    echo "Caught exception: " . $ex->getMessage();
}
```

```ruby
require 'sendgrid-ruby'
include SendGrid

sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
data = JSON.parse('{
  "email_addresses": [
    "user1@example.com",
    "user2@example.com"
  ]
}')

response = sg.client.recipients.erasejob.post(request_body: data)
puts response.status_code
puts response.headers
puts response.body
```

```bash
curl -X POST "https://api.sendgrid.com/v3/recipients/erasejob" \
--header "Authorization: Bearer $SENDGRID_API_KEY" \
--header "Content-Type: application/json" \
--data '{"email_addresses": ["user1@example.com", "user2@example.com"]}'
```
