Blocklist entries
Emails and domains Kenso never contacts: add, import from CSV, annotate and remove.
Add up to 1,000 blocklist values of one type
/v1/blocklist-entries/bulk-createblocklist-entries.bulk-createSend values, or entries ([{ "value": "...", "reason": "..." }]) for a reason per value, not both. Optional reason applies to every value without its own. Per-value outcomes are succeeded or failed. Duplicates stay failed with already_exists and keep their own reason. A domain a customer account or a blocklist rule already lists becomes manual under its id, with the reason sent, and is in succeeded with claimed: true, as on the single add. A shared mail provider domain (gmail.com, hotmail.co.uk, web.de) fails with shared_mail_provider; any other malformed value with invalid. To undo the add, bulk-delete only the succeeded ids without claimed: true: a claimed entry was blocked before the add, and deleting it unblocks the domain. Requires WriteAccess.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a BlocklistBulkResult.
curl -X POST "https://api.ken.so/v1/blocklist-entries/bulk-create" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"type": "string",
"values": [
"string"
],
"reason": "string",
"entries": [
{
"value": "string",
"reason": "string"
}
]
}'{
"success": true,
"data": {
"succeeded": [
{
"id": 7712,
"type": "domain",
"value": "competitor.example.com",
"createdAt": "2026-09-23T15:02:11Z",
"source": "manual",
"reason": "Current customer"
}
],
"failed": [
{
"value": "string",
"code": "string",
"message": "string"
}
]
}
}Remove up to 1,000 blocklist entries by id
/v1/blocklist-entries/bulk-deleteblocklist-entries.bulk-deleteBody { "ids": [...] }. Removes them in one transaction and runs the own-domain and rule reconciles once, so undoing a large upload takes one call per 1,000 entries. To undo a bulk add, send only its succeeded ids without claimed: true: a claimed entry was blocked before the add (by a customer account or a rule), and a customer entry deleted here stays off. succeeded lists every id that is off the blocklist after the call, in request order, including an id already gone. An own-domain entry, and a rule entry while blocklist rules are on, stay and are in failed with invalid_state and the single delete's message. Requires WriteAccess.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a BlocklistBulkDeleteResult.
curl -X POST "https://api.ken.so/v1/blocklist-entries/bulk-delete" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"ids": [
812
]
}'{
"success": true,
"data": {
"succeeded": [
1
],
"failed": [
{
"id": 812,
"error": {
"code": "string",
"message": "string"
}
}
]
}
}List blocklist entries in the current workspace
/v1/blocklist-entriesblocklist-entries.listOrdered by id, which follows creation: sort=createdAt (the default) is oldest first, sort=-createdAt newest first; keep the same sort while paging. Optional filters: type (email or domain), value (an exact match), q (a case-insensitive substring of the value or the reason), source (comma-separated manual, own_domain, customer, rule) and hasReason. includeTotal=true adds pagination.total, every entry the filters match. includeCounts=true adds counts: the workspace's entries in all, emails, domains, from the CRM (customer and rule) and with no reason, whatever the filters. Requires ReadAccess.
Parameters
manual, own_domain, customer and rule.true lists entries with a reason, false those without one.createdAt (oldest first, the default) or -createdAt (newest first).true adds pagination.total, every entry the filters match.true adds counts, the workspace's entries per filter.400 workspace_required).Response 200
data is a list of BlocklistEntryModel. Each item has these fields. The response also carries pagination, counts.
manual, or own_domain for a domain mirrored from the workspace's own domains. An own_domain entry cannot be deleted here (409 invalid_state); remove the domain in Settings > Company instead, or ask Kenso support to change the Primary domain. customer for a domain of an account marked a customer; clearing the account's Customer flag removes it. rule for a domain a blocklist rule adds from Kenso's CRM: it comes off once no enabled rule matches it, and it cannot be deleted here (409 invalid_state); change or turn off the rule instead. Adding the same value here makes it manual.Opted out or bounced, Customer in HubSpot, Customer account); own-domain rows have none.true on a create or bulk-create result when a customer account or a blocklist rule already listed the domain and this call made that entry manual, same id. Omitted otherwise.curl -X GET "https://api.ken.so/v1/blocklist-entries" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": [
{
"id": 7712,
"type": "domain",
"value": "competitor.example.com",
"createdAt": "2026-09-23T15:02:11Z",
"source": "manual",
"reason": "Current customer"
}
],
"pagination": {
"nextCursor": "eyJpZCI6ODE1fQ",
"hasMore": true,
"total": 1,
"isTotalCapped": true
},
"counts": {
"all": 1,
"emails": 1,
"domains": 1,
"fromCrm": 1,
"noReason": 1
}
}Add one email or domain to the blocklist
/v1/blocklist-entriesblocklist-entries.createOptional reason (at most 200 characters) says why the value is blocked. A duplicate entry is validation_failed and keeps its own reason. A domain a customer account or a blocklist rule already lists becomes manual under its id, with this reason, and comes back with claimed: true. A shared mail provider domain (gmail.com, hotmail.co.uk, web.de) is validation_failed with detail code shared_mail_provider: block those addresses one by one. Requires WriteAccess.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 201
data is a BlocklistEntryModel.
manual, or own_domain for a domain mirrored from the workspace's own domains. An own_domain entry cannot be deleted here (409 invalid_state); remove the domain in Settings > Company instead, or ask Kenso support to change the Primary domain. customer for a domain of an account marked a customer; clearing the account's Customer flag removes it. rule for a domain a blocklist rule adds from Kenso's CRM: it comes off once no enabled rule matches it, and it cannot be deleted here (409 invalid_state); change or turn off the rule instead. Adding the same value here makes it manual.Opted out or bounced, Customer in HubSpot, Customer account); own-domain rows have none.true on a create or bulk-create result when a customer account or a blocklist rule already listed the domain and this call made that entry manual, same id. Omitted otherwise.curl -X POST "https://api.ken.so/v1/blocklist-entries" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"type": "domain",
"value": "competitor.example.com",
"reason": "Current customer"
}'{
"success": true,
"data": {
"id": 7712,
"type": "domain",
"value": "competitor.example.com",
"createdAt": "2026-09-23T15:02:11Z",
"source": "manual",
"reason": "Current customer"
}
}Set or clear why a blocklist entry is blocked
/v1/blocklist-entries/{entryId}blocklist-entries.updateBody { "reason": "..." }, at most 200 characters; null or blank clears it. reason is required. Requires WriteAccess. An entry outside the workspace is not_found.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a BlocklistEntryModel.
manual, or own_domain for a domain mirrored from the workspace's own domains. An own_domain entry cannot be deleted here (409 invalid_state); remove the domain in Settings > Company instead, or ask Kenso support to change the Primary domain. customer for a domain of an account marked a customer; clearing the account's Customer flag removes it. rule for a domain a blocklist rule adds from Kenso's CRM: it comes off once no enabled rule matches it, and it cannot be deleted here (409 invalid_state); change or turn off the rule instead. Adding the same value here makes it manual.Opted out or bounced, Customer in HubSpot, Customer account); own-domain rows have none.true on a create or bulk-create result when a customer account or a blocklist rule already listed the domain and this call made that entry manual, same id. Omitted otherwise.curl -X PATCH "https://api.ken.so/v1/blocklist-entries/812" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"reason": "string"
}'{
"success": true,
"data": {
"id": 7712,
"type": "domain",
"value": "competitor.example.com",
"createdAt": "2026-09-23T15:02:11Z",
"source": "manual",
"reason": "Current customer"
}
}Remove one blocklist entry
/v1/blocklist-entries/{entryId}blocklist-entries.deleteRequires WriteAccess. An entry outside the workspace is not_found.
Parameters
400 workspace_required).Response 204
curl -X DELETE "https://api.ken.so/v1/blocklist-entries/812" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
HTTP/1.1 204 No Content
Import blocklist rows from a CSV file
/v1/blocklist-entries/importsblocklist-entries.importMultipart field file is a .csv with email and/or domain columns and an optional reason column; a cell over 200 characters is cut, never failing the file. Optional form field reason (at most 200 characters) applies to every row without its own. Rows already on the blocklist keep their own reason, and a shared mail provider in the domain column (gmail.com) is skipped. Requires WriteAccess.
Parameters
400 workspace_required).Request body
multipart/form-data, optional.
Response 200
data is a BlocklistImportModel.
curl -X POST "https://api.ken.so/v1/blocklist-entries/imports" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \ -F "file=@./file" \ -F 'reason=string'
{
"success": true,
"data": {
"status": "string"
}
}