curl --request PUT \
--url https://api.attio.com/v2/workspace_blocklist_addresses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"data": {
"addresses": [
{
"address": "lists@acme.com",
"enforcement_level": "blocked"
},
{
"address": "https://www.newsletter.example.com",
"enforcement_level": "blocked"
},
{
"address": "jane@acme.com",
"enforcement_level": "protected"
}
]
}
}
'import requests
url = "https://api.attio.com/v2/workspace_blocklist_addresses"
payload = { "data": { "addresses": [
{
"address": "lists@acme.com",
"enforcement_level": "blocked"
},
{
"address": "https://www.newsletter.example.com",
"enforcement_level": "blocked"
},
{
"address": "jane@acme.com",
"enforcement_level": "protected"
}
] } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: {
addresses: [
{address: 'lists@acme.com', enforcement_level: 'blocked'},
{address: 'https://www.newsletter.example.com', enforcement_level: 'blocked'},
{address: 'jane@acme.com', enforcement_level: 'protected'}
]
}
})
};
fetch('https://api.attio.com/v2/workspace_blocklist_addresses', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.attio.com/v2/workspace_blocklist_addresses",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'addresses' => [
[
'address' => 'lists@acme.com',
'enforcement_level' => 'blocked'
],
[
'address' => 'https://www.newsletter.example.com',
'enforcement_level' => 'blocked'
],
[
'address' => 'jane@acme.com',
'enforcement_level' => 'protected'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.attio.com/v2/workspace_blocklist_addresses"
payload := strings.NewReader("{\n \"data\": {\n \"addresses\": [\n {\n \"address\": \"lists@acme.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"https://www.newsletter.example.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"jane@acme.com\",\n \"enforcement_level\": \"protected\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.attio.com/v2/workspace_blocklist_addresses")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"addresses\": [\n {\n \"address\": \"lists@acme.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"https://www.newsletter.example.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"jane@acme.com\",\n \"enforcement_level\": \"protected\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.attio.com/v2/workspace_blocklist_addresses")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"addresses\": [\n {\n \"address\": \"lists@acme.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"https://www.newsletter.example.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"jane@acme.com\",\n \"enforcement_level\": \"protected\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"address": "jane@acme.com",
"address_type": "email_address",
"enforcement_level": "blocked",
"created_at": "2026-10-28T09:12:44.210000000Z"
}
]
}{
"status_code": 400,
"type": "invalid_request_error",
"code": "validation_type",
"message": "Body payload validation error."
}{
"status_code": 403,
"type": "auth_error",
"code": "unauthorized",
"message": "A user-level access token can only manage the workspace blocklist if the member it acts for is a workspace admin."
}{
"status_code": 409,
"type": "invalid_request_error",
"code": "uniqueness_conflict",
"message": "One or more addresses were changed by a concurrent request. Please retry."
}Add or update workspace blocklist addresses
An address is an email address (jane@acme.com) or a domain (acme.com).
Sets each address in the request to the given enforcement level on the workspace blocklist. The address itself is its key: there is no separate ID.
An address that isn’t on the workspace blocklist is added. An address already at the requested level is left unchanged, so this endpoint is safe to retry. An address at the other level is moved to the requested level.
This endpoint only adds and updates the addresses in the request. Addresses on the workspace blocklist that aren’t in the request are left alone; it never replaces the whole list.
Addresses are normalized: email addresses and domains are trimmed and lowercased, a URL is reduced to its hostname, and a leading www. is removed. The response returns the normalized value, which is the key for the address. Duplicate addresses are collapsed, and a request that gives the same address two different enforcement levels is rejected.
The request is applied all or nothing. Protected changes take effect immediately. Blocked changes take effect once each connected mailbox has re-synced, which may take a few minutes.
A user-level access token can only call this endpoint if the workspace member it acts for is a workspace admin.
This endpoint is in alpha and may be subject to breaking changes as we gather feedback.
Required scopes: email_calendar_blocklist:read-write.
Supported token levels: workspace, user.
curl --request PUT \
--url https://api.attio.com/v2/workspace_blocklist_addresses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"data": {
"addresses": [
{
"address": "lists@acme.com",
"enforcement_level": "blocked"
},
{
"address": "https://www.newsletter.example.com",
"enforcement_level": "blocked"
},
{
"address": "jane@acme.com",
"enforcement_level": "protected"
}
]
}
}
'import requests
url = "https://api.attio.com/v2/workspace_blocklist_addresses"
payload = { "data": { "addresses": [
{
"address": "lists@acme.com",
"enforcement_level": "blocked"
},
{
"address": "https://www.newsletter.example.com",
"enforcement_level": "blocked"
},
{
"address": "jane@acme.com",
"enforcement_level": "protected"
}
] } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: {
addresses: [
{address: 'lists@acme.com', enforcement_level: 'blocked'},
{address: 'https://www.newsletter.example.com', enforcement_level: 'blocked'},
{address: 'jane@acme.com', enforcement_level: 'protected'}
]
}
})
};
fetch('https://api.attio.com/v2/workspace_blocklist_addresses', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.attio.com/v2/workspace_blocklist_addresses",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'addresses' => [
[
'address' => 'lists@acme.com',
'enforcement_level' => 'blocked'
],
[
'address' => 'https://www.newsletter.example.com',
'enforcement_level' => 'blocked'
],
[
'address' => 'jane@acme.com',
'enforcement_level' => 'protected'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.attio.com/v2/workspace_blocklist_addresses"
payload := strings.NewReader("{\n \"data\": {\n \"addresses\": [\n {\n \"address\": \"lists@acme.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"https://www.newsletter.example.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"jane@acme.com\",\n \"enforcement_level\": \"protected\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.attio.com/v2/workspace_blocklist_addresses")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"addresses\": [\n {\n \"address\": \"lists@acme.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"https://www.newsletter.example.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"jane@acme.com\",\n \"enforcement_level\": \"protected\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.attio.com/v2/workspace_blocklist_addresses")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"addresses\": [\n {\n \"address\": \"lists@acme.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"https://www.newsletter.example.com\",\n \"enforcement_level\": \"blocked\"\n },\n {\n \"address\": \"jane@acme.com\",\n \"enforcement_level\": \"protected\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"address": "jane@acme.com",
"address_type": "email_address",
"enforcement_level": "blocked",
"created_at": "2026-10-28T09:12:44.210000000Z"
}
]
}{
"status_code": 400,
"type": "invalid_request_error",
"code": "validation_type",
"message": "Body payload validation error."
}{
"status_code": 403,
"type": "auth_error",
"code": "unauthorized",
"message": "A user-level access token can only manage the workspace blocklist if the member it acts for is a workspace admin."
}{
"status_code": 409,
"type": "invalid_request_error",
"code": "uniqueness_conflict",
"message": "One or more addresses were changed by a concurrent request. Please retry."
}Was this page helpful?