Tags
Tag definitions, and assigning them to records one at a time or in bulk.
entityType (campaign, contact, mailbox, domain, reply, account, linkedin_account, person) lists the tags that can go on that type: every user tag, plus system tags and sender configs whose scope includes it. With entityId, the list is the tags assigned to that campaign, contact, mailbox, domain, account, LinkedIn account, or person. systemKey lists only the workspace's system tag with that key, created on first use: systemKey=champion returns the Champion tag a person carries to be watched for a job change. Reply and LinkedIn conversation assignments use POST /v1/tags/{tagId}/assignments. includeUsage=true adds usage to each tag: live assignment counts in this workspace (campaignCount, contactCount, replyCount for email messages, linkedinConversationCount, inboxCount, domainCount, accountCount, linkedinAccountCount). Without it usage is absent. entityType=campaign&includeEntityIds=true adds entityIds to each tag: the ids of the workspace's live campaigns carrying it, so every campaign's tags take one call. Another entityType with it is 400 validation_failed; without it entityIds is absent.
Parameters
usage (assignment counts per entity type) to every tag on the page.entityType=campaign, true adds entityIds (the live campaigns carrying it) to every tag on the page.champion finds the Champion tag for people.400 workspace_required).Response 200
data is a list of TagModel. Each item has these fields. The response also carries pagination.
entityType=campaign&includeEntityIds=true; absent otherwise. The ids, ascending, of the workspace's live campaigns that carry the tag.curl -X GET "https://api.ken.so/v1/tags" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": [
{
"id": 341,
"name": "Hot lead",
"description": "Asked for a call or pricing",
"color": "#FFD6A5",
"type": "contact",
"entityTypes": [
"contact",
"reply"
],
"isConfig": false,
"isSystem": false,
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-10-14T09:41:27Z"
}
],
"pagination": {
"nextCursor": "eyJpZCI6ODE1fQ",
"hasMore": true,
"total": 1,
"isTotalCapped": true
}
}Requires the workspace settings permission (owners, admins and editors by default). entityTypes (campaign, contact, mailbox, domain, reply, account, linkedin_account, person) is the scopes the tag lists under; omitted or empty means every scope. Any tag that is not a system tag can be assigned to any entity type whatever its scopes. A name already used in the workspace (case-insensitive) is 400 validation_failed. color defaults to #E4D0FF.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 201
data is a TagModel.
entityType=campaign&includeEntityIds=true; absent otherwise. The ids, ascending, of the workspace's live campaigns that carry the tag.curl -X POST "https://api.ken.so/v1/tags" \
-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 '{
"name": "Hot lead",
"description": "Asked for a call or pricing",
"color": "#FFD6A5",
"entityTypes": [
"contact",
"reply"
]
}'{
"success": true,
"data": {
"id": 341,
"name": "Hot lead",
"description": "Asked for a call or pricing",
"color": "#FFD6A5",
"type": "contact",
"entityTypes": [
"contact",
"reply"
],
"isConfig": false,
"isSystem": false,
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-10-14T09:41:27Z"
}
}Parameters
400 workspace_required).Response 200
data is a TagModel.
entityType=campaign&includeEntityIds=true; absent otherwise. The ids, ascending, of the workspace's live campaigns that carry the tag.curl -X GET "https://api.ken.so/v1/tags/812" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"id": 341,
"name": "Hot lead",
"description": "Asked for a call or pricing",
"color": "#FFD6A5",
"type": "contact",
"entityTypes": [
"contact",
"reply"
],
"isConfig": false,
"isSystem": false,
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-10-14T09:41:27Z"
}
}Absent fields stay unchanged. null description clears it. Requires the workspace settings permission (owners, admins and editors by default).
Parameters
400 workspace_required).Request body
application/json, optional: object.
Response 200
data is a TagModel.
entityType=campaign&includeEntityIds=true; absent otherwise. The ids, ascending, of the workspace's live campaigns that carry the tag.curl -X PATCH "https://api.ken.so/v1/tags/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 '{}'{
"success": true,
"data": {
"id": 341,
"name": "Hot lead",
"description": "Asked for a call or pricing",
"color": "#FFD6A5",
"type": "contact",
"entityTypes": [
"contact",
"reply"
],
"isConfig": false,
"isSystem": false,
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-10-14T09:41:27Z"
}
}Soft-deletes the definition and its assignments. Requires the workspace settings permission (owners, admins and editors by default).
Parameters
400 workspace_required).Response 204
curl -X DELETE "https://api.ken.so/v1/tags/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
entityType is campaign, contact, mailbox, domain, account, or linkedin_account or person with entityId. reply uses messageId. linkedin_conversation uses conversationId. A tag that is not a system tag can be assigned to any entity type; a system tag only to its scopes. Assigning a tag the entity already has succeeds and changes nothing. An entity outside the workspace, or a deleted one, is 404 not_found. Mailbox, domain and LinkedIn account tags need Delivery edit; person tags need Accounts edit, like account tags. The route itself needs workspace membership.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a TagAssignmentModel.
curl -X POST "https://api.ken.so/v1/tags/812/assignments" \
-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 '{
"entityType": "string",
"entityId": 812,
"messageId": "msg_ZW1haWw6NDAyMjg0LjJAZXhhbXBsZS5jb20",
"conversationId": "string"
}'{
"success": true,
"data": {
"tagId": 812,
"entityType": "string",
"entityId": 812,
"messageId": "msg_ZW1haWw6NDAyMjg0LjJAZXhhbXBsZS5jb20",
"conversationId": "string"
}
}Query parameters, not a body: entityType plus entityId, messageId, or conversationId. A missing entityType is validation_failed. The route needs workspace membership; the entity type adds its page edit access, as on assign.
Parameters
400 workspace_required).Response 200
data is a TagAssignmentModel.
curl -X DELETE "https://api.ken.so/v1/tags/812/assignments" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"tagId": 812,
"entityType": "string",
"entityId": 812,
"messageId": "msg_ZW1haWw6NDAyMjg0LjJAZXhhbXBsZS5jb20",
"conversationId": "string"
}
}Assign a tag to up to 1,000 entities in one call
/v1/tags/{tagId}/assignments/bulk-createtags.bulk-assignEach item has the shape of the single assignment body. Items run one at a time in request order through the same path as POST /v1/tags/{tagId}/assignments. An entity outside the workspace is not_found and is not written. results is in request order; status is assigned, not_found, validation_failed, or failed. The whole request is rejected, with nothing written, when items is empty, has more than 1,000 entries, or has a null entry. A tag outside the workspace is 404. The route needs workspace membership; each item's entity type adds its page edit access, as on assign.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a TagAssignmentBulkResult.
curl -X POST "https://api.ken.so/v1/tags/812/assignments/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 '{
"items": [
{
"entityType": "string",
"entityId": 812,
"messageId": "msg_ZW1haWw6NDAyMjg0LjJAZXhhbXBsZS5jb20",
"conversationId": "string"
}
]
}'{
"success": true,
"data": {
"succeeded": 1,
"failed": 1,
"results": [
{
"index": 1,
"status": "string",
"error": "string"
}
]
}
}Remove a tag from up to 1,000 entities in one call
/v1/tags/{tagId}/assignments/bulk-deletetags.bulk-unassignSame body, validation, and per-item behavior as bulk-create, through the same path as DELETE /v1/tags/{tagId}/assignments. A successful item is removed. The route needs workspace membership; each item's entity type adds its page edit access, as on assign.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a TagAssignmentBulkResult.
curl -X POST "https://api.ken.so/v1/tags/812/assignments/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 '{
"items": [
{
"entityType": "string",
"entityId": 812,
"messageId": "msg_ZW1haWw6NDAyMjg0LjJAZXhhbXBsZS5jb20",
"conversationId": "string"
}
]
}'{
"success": true,
"data": {
"succeeded": 1,
"failed": 1,
"results": [
{
"index": 1,
"status": "string",
"error": "string"
}
]
}
}