# Tags

> Consistent labels, created when you need them.

## Reusable workspace labels

Tags are lightweight labels such as `supplier`, `collaborator`, or `research`. A workspace owns its own tag registry; tags and assignments are never shared across workspace boundaries.

Use `tags_list` to discover existing labels before introducing another spelling. A contributor can create a label by applying it during creation or update of a contact, organisation, or project. Tasks use custom fields and links rather than tags. Labels are trimmed, lowercased, and deduplicated. Up to 30 labels are allowed per record, each up to 80 characters.

## Apply or remove labels

`contacts_update` replaces the tag list with the supplied array. Read the contact first and retain any labels you want to keep:

```json
{
  "id": "01900000-0000-7000-8000-000000000001",
  "expected_revision": 1,
  "idempotency_key": "contact-tags-001",
  "changes": {"tags": ["supplier", "research"]}
}
```

Send `"tags": []` inside `changes` to clear the assignments. Omit `tags` to leave them unchanged. Revision checks prevent silently overwriting labels added by another agent.

Removing an assignment does not delete the label. Empty labels remain discoverable and reusable. Global rename, merge, and deletion tools are not available yet.

## Search and storage

`contacts_search` accepts a complete, case-insensitive `tag` filter. The database has a `tags` registry and workspace-constrained `contact_tag`, `organisation_tag`, and `project_tag` associations. The contact's JSONB tag list is retained for response compatibility; contact writes update both together in a transaction.

The upgrade backfills registry entries and associations from existing contact tags without changing historical contact snapshots. Existing label spelling may remain in older records until a tag update normalises it. Back up before upgrading; rolling back removes the registry and associations but keeps contact tag lists.
