---
id: tags
slug: /apis/tags
title: 'Tags (api/tags)'
description: 'Query, search, merge and remove asset tags instance-wide through ~/api/tags.'
sidebar_label: 'Overview'
sidebar_position: 1
tags: ['api', 'tags']

draft: false
---

`~/api/tags` is an **instance-wide view of the tag vocabulary**. It answers questions that
cannot be answered by querying assets one at a time: which tags exist, how widely each is used,
and how to clean the vocabulary up by merging near-duplicates or removing tags outright.

## What Tags Are

Tags are free-text values that live on assets. Critically, **a tag has no independent
existence** — it exists only in the context of the assets it has been applied to. There is no
"tag asset" you can create, and no tag object to delete. Removing a tag from the last asset
carrying it removes it from the system.

The consequence is a clean division of labour:

| To do this                                | Use this                                                    |
| ----------------------------------------- | ----------------------------------------------------------- |
| Add or remove a tag **on a single asset**  | [`rest-1.v1/Data`](/apis/rest-1) or [`~/api/asset`](/apis/asset-bulk), writing the `TaggedWith` attribute |
| See the tag vocabulary **across the instance** | `~/api/tags` — this section                              |
| Rename a tag everywhere                    | `~/api/tags/command/merge` — [merge](/apis/tags/merge)      |
| Purge a tag everywhere                     | `~/api/tags/command/remove` — [remove](/apis/tags/remove)   |

## The `TaggedWith` Attribute

Tags are surfaced on assets through the `TaggedWith` attribute definition. It is defined on
`BaseAsset`, so it is inherited broadly, but it is exposed on these asset types in particular:

- `Story`
- `Defect`
- `Task`
- `Test`
- `TestSet`
- `Epic` (Portfolio Item)
- `RegressionTest`
- `RegressionSuite`

:::note This list is not exhaustive
`TaggedWith` is inherited from `BaseAsset`, and additional types expose it. Rather than trust a
static list, ask the instance you are actually working against:

```bash
curl "https://{host}/{instance}/meta.v1/Story?xsl=api.xsl" \
  -H "Accept: application/json"
```

See [Metadata API (meta.v1)](/apis/meta-v1).
:::

## Operations

| Operation                                    | Endpoint                                        |
| -------------------------------------------- | ----------------------------------------------- |
| [Query a single tag](/apis/tags/query)        | `GET ~/api/tags?tag=<tag>`                      |
| [Query all tags](/apis/tags/query-all)        | `GET ~/api/tags/all`                            |
| [Search tags](/apis/tags/search)              | `GET ~/api/tags/command/search?term=<term>`     |
| [Merge tags](/apis/tags/merge)                | `POST ~/api/tags/command/merge`                 |
| [Remove tags](/apis/tags/remove)              | `POST ~/api/tags/command/remove`                |

## Scope Visibility

Every count this API returns is filtered twice. `count` is the total number of usages of a tag
in the system; `visibleCount` is the number of those usages on assets the **calling member** can
actually see. A member restricted to one project will see a small `visibleCount` against a large
`count`.

The command endpoints (`merge`, `remove`) honour the same boundary: they act only on assets the
caller can see and edit. A merge run by a project-scoped member will leave the tag intact
elsewhere in the instance, and the response will not tell you that happened. Run vocabulary
cleanup as a member with instance-wide visibility.

## Permissions

`merge` and `remove` require the **`ManageTags`** privilege.

:::note
`ManageTags` — not Project Admin access — is what the server enforces. The two
often coincide in practice because `ManageTags` is granted to administrative
roles, but they are not the same thing: a user can hold either without the
other.
:::

In the default role configuration, the **System Admin**, **Project Admin**,
and **Member Admin** roles hold `ManageTags`; the other default roles do
not. Instances can customize roles, so check with your administrator when
in doubt.

Querying and searching require only normal authenticated access.

## Related Topics

- [rest-1.v1](/apis/rest-1) — writing `TaggedWith` on an individual asset
- [Bulk API (api/asset)](/apis/asset-bulk) — tagging many assets in one request
- [Attributes](/concepts/attributes)
- [API conventions](/apis/conventions)
