Skip to content

Tags

Tags are colored labels you attach to leads to categorize and filter them. Each tag has a unique label and an optional hex color. You can assign a tag to multiple leads and remove assignments without deleting the tag itself.

{
"object": "tag",
"id": 12,
"label": "VIP",
"color": "#f59e0b",
"created_at": "2025-10-01T14:22:00.000Z"
}
FieldTypeDescription
idintegerTag ID
labelstringUnique display label (max 100 characters)
colorstringHex color code (default #94a3b8)
created_atstringISO-8601 creation timestamp

GET /api/v1/tags

Returns tags sorted by most-recently-created first.

Scope required: tags.read

ParameterTypeDescription
limitintegerPage size, 1–100 (default: 20)
cursorstringOpaque cursor from a previous response’s next_cursor
Terminal window
curl "https://app.benchkey.com/api/v1/tags?limit=20" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch(
"https://app.benchkey.com/api/v1/tags?limit=20",
{ headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } }
);
const { data, has_more, next_cursor } = await res.json();
{
"object": "list",
"data": [
{
"object": "tag",
"id": 12,
"label": "VIP",
"color": "#f59e0b",
"created_at": "2025-10-01T14:22:00.000Z"
},
{
"object": "tag",
"id": 11,
"label": "Insurance",
"color": "#3b82f6",
"created_at": "2025-09-15T10:05:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}

See Pagination for how to page through results.


GET /api/v1/tags/:id

Returns a single tag by ID.

Scope required: tags.read

Terminal window
curl "https://app.benchkey.com/api/v1/tags/12" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch(
"https://app.benchkey.com/api/v1/tags/12",
{ headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } }
);
const tag = await res.json();

Returns the tag object. Returns 404 if not found.


POST /api/v1/tags

Creates a new tag. Labels must be unique across the tenant.

Scope required: tags.write

FieldRequiredDescription
labelyesUnique display label (max 100 characters)
colornoHex color code, 3- or 6-digit (e.g. #f59e0b). Defaults to #94a3b8
Terminal window
curl -X POST https://app.benchkey.com/api/v1/tags \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" \
-H "Content-Type: application/json" \
-d '{
"label": "VIP",
"color": "#f59e0b"
}'
const res = await fetch("https://app.benchkey.com/api/v1/tags", {
method: "POST",
headers: {
Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa",
"Content-Type": "application/json",
},
body: JSON.stringify({ label: "VIP", color: "#f59e0b" }),
});
const tag = await res.json(); // HTTP 201

Returns the created tag object with HTTP 201 Created.

{
"object": "tag",
"id": 12,
"label": "VIP",
"color": "#f59e0b",
"created_at": "2025-10-01T14:22:00.000Z"
}

DELETE /api/v1/tags/:id

Deletes a tag and removes all of its lead assignments. This action cannot be undone.

Scope required: tags.write

Terminal window
curl -X DELETE "https://app.benchkey.com/api/v1/tags/12" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch("https://app.benchkey.com/api/v1/tags/12", {
method: "DELETE",
headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" },
});
const result = await res.json();
{
"object": "tag",
"id": 12,
"deleted": true
}

Returns 404 if the tag does not exist.


POST /api/v1/tags/:id/assignments

Attaches a tag to a lead. If the assignment already exists, the request is a no-op (idempotent). Archived leads are treated as nonexistent, assigning a tag to an archived lead returns 404.

Scope required: tags.write

FieldRequiredDescription
lead_idyesID of the lead to tag
Terminal window
curl -X POST "https://app.benchkey.com/api/v1/tags/12/assignments" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" \
-H "Content-Type: application/json" \
-d '{"lead_id": 501}'
const res = await fetch("https://app.benchkey.com/api/v1/tags/12/assignments", {
method: "POST",
headers: {
Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa",
"Content-Type": "application/json",
},
body: JSON.stringify({ lead_id: 501 }),
});
const result = await res.json(); // HTTP 201
{
"object": "tag_assignment",
"tag_id": 12,
"lead_id": 501
}

DELETE /api/v1/tags/:id/assignments/:lead_id

Detaches a tag from a lead. Returns 404 if the tag or lead does not exist (or the lead is archived). If the assignment does not currently exist the delete still returns 200.

Scope required: tags.write

Terminal window
curl -X DELETE "https://app.benchkey.com/api/v1/tags/12/assignments/501" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch("https://app.benchkey.com/api/v1/tags/12/assignments/501", {
method: "DELETE",
headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" },
});
const result = await res.json();
{
"object": "tag_assignment",
"tag_id": 12,
"lead_id": 501,
"deleted": true
}

HTTP statusCodeMeaning
400missing_fieldA required field is absent (label, lead_id)
400label_too_longlabel exceeds 100 characters
400invalid_colorcolor is not a valid 3- or 6-digit hex value
400invalid_id:id or :lead_id is not a valid positive integer, or exceeds 2,147,483,647
400invalid_lead_idlead_id body field (assign) or :lead_id path param (unassign) is not a valid positive integer, or exceeds 2,147,483,647
400invalid_cursorcursor is malformed
404not_foundTag or lead not found (archived leads are treated as nonexistent)
409duplicate_tagA tag with that label already exists
422assignment_failedTag assignment did not persist
422delete_failedTag delete did not persist
403insufficient_scopeAPI key lacks tags.read or tags.write

See Errors for the full error envelope format.

System status