Tags API¶
You can create, read, update, and delete tags programmatically, read how a tag is used, and move, remove, or merge it across its assets.
Tip
For complete API documentation, including request/response schemas, visit the API docs.
All endpoints use the base URL of your Qualytics deployment (e.g., https://your-instance.qualytics.io/api) and require a Personal API Token. Every endpoint requires the Member role. Creating, editing, and deleting a global tag requires the Admin role, and a team's tag also the Editor team permission on that team. Merging a tag requires the Admin role. See Tag Permissions for the full matrix.
Tags are applied from the asset
Putting a tag on an asset, or taking it off one asset, is done through that asset's own endpoint, by sending its full list of tag names. See, for example, the Datastore Tags API. The endpoints on this page manage the tags themselves and act on many assets at once.
Name or ID
The older endpoints address a tag by its name in the path, such as /global-tags/PII. The tag page endpoints address it by its numeric ID, such as /global-tags/42/summary. Encode a name with spaces or special characters in the URL.
Error Responses¶
| Status Code | Description |
|---|---|
401 Unauthorized |
Missing or invalid API token. |
403 Forbidden |
The user does not have the required role or team permission, or the endpoint needs the Data Catalog module. |
404 Not Found |
No tag you can see has the specified name or ID, or the team does not exist. |
409 Conflict |
A tag with that name already exists, or the tag's assets are being updated by another change. Try again in a moment. |
422 Unprocessable Entity |
Invalid request body, such as an invalid name or color, a weight outside -10 to 10, a move or merge onto the same tag or an external tag, or a team tag applied outside its team's datastores. |
Error response examples
409 Conflict (name taken):
422 Unprocessable Entity (external tags in a move, remove, or merge):
List Tags¶
Returns a paginated list of the tags you can see: global and external tags, plus the tags of your teams. Each tag comes with its asset count and quality score.
Endpoint: GET /global-tags
Permission: Member role or above
| Query Parameter | Type | Description |
|---|---|---|
name |
string |
Match a piece of the tag name, ignoring case. |
type |
list of strings |
global, external, or both (the default). |
category |
list of strings |
Only tags in these categories. |
scope |
list |
global for global tags (external ones included), or a team ID for that team's tags. Several values combine with OR. |
filters |
string (JSON) |
Narrows the list by category or scope, written as a JSON object. See Filtering Lists. |
sort_name, sort_created, sort_weight, sort_color, sort_category, sort_asset_count |
asc / desc |
Sort by name, creation date, weight, color, category, or number of tagged assets. |
Example request and response
Request:
curl -X GET "https://your-instance.qualytics.io/api/global-tags?category=Sensitivity&sort_weight=desc" \
-H "Authorization: Bearer YOUR_TOKEN"
Response (abbreviated):
Filtering Lists¶
GET /api/global-tags accepts a filters parameter: a JSON object with one entry per filter, saying how that filter's values should match.
curl -G "https://your-instance.qualytics.io/api/global-tags" \
--data-urlencode 'filters={"scope":{"in":["global"]},"category":{"empty":false}}' \
-H "Authorization: Bearer YOUR_TOKEN"
This returns the global tags that have a category.
| Key | Returns |
|---|---|
in |
The items that match at least one of the values. |
not_in |
The items that match none of the values. |
all_of |
The items that match every value, on filters an item can have several of, such as tags. |
empty |
The items with no value (true) or at least one (false), on filters an item can lack. |
- Different filters combine with AND, and so do keys on the same filter.
emptycan't be combined with other keys on the same filter.- A filter sent both as its own parameter and inside
filtersreturns a422. Put all of that filter's conditions infilters. in,not_inandall_ofeach take between 1 and 20 values.- A filter or key the endpoint doesn't accept returns a
422that names it. The API docs list what each endpoint accepts.
List Categories¶
Returns every category in use, as a list of strings.
Endpoint: GET /global-tags/categories
Permission: Member role or above
Get a Tag¶
Returns one tag by name.
Endpoint: GET /global-tags/{name}
Permission: Member role or above
Example response
An external tag also carries the integration it was imported from.
Create a Tag¶
Endpoint: POST /global-tags
Permission: Admin role for a global tag. For a team tag, the Editor team permission on that team, other than the Public team.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string |
Yes | global. |
name |
string |
Yes | Unique across the workspace. From 2 to 255 characters, with at least one letter. Only letters A-Z, digits, spaces, and _, -, . are allowed. Leading and trailing spaces are removed. |
color |
string |
No | A hex color code, such as #FF2000. |
description |
string |
No | What the tag means, in Markdown. |
category |
string |
No | The tag's category. |
weight_modifier |
integer |
No | From -10 to 10. Defaults to 1. |
team_id |
integer |
No | The team that owns the tag. Leave it out for a global tag. |
Example request
Tags Created From Other Endpoints¶
When you save a flow, check, check template, table, file, field, anomaly, or datastore through the API, or ask AgentQ to apply tags, a tag name that doesn't exist yet creates a new global tag. Only Admins can create tags this way, and the name follows the same rules as above:
- A refused name fails the request with
422 Unprocessable EntityandCan't create tag '<name>'. <reason>, and the asset is not saved. AgentQ applies no tags in that case and tells you why. - Spaces at the start and end of a new name are refused instead of removed, except on datastores, which trim them before creating the tag.
- Existing tags whose names predate these rules keep working on assets.
Update a Tag¶
Two endpoints update a tag. PUT addresses it by name and replaces the name, description, and category with what you send. PATCH addresses it by ID and changes only the fields you send.
Endpoints: PUT /global-tags/{name} and PATCH /global-tags/{id}
Permission: Same as creating the tag. Changing team_id requires the Admin role.
The body takes the same fields as Create a Tag, with type set to the tag's current type. A type cannot be changed.
- Scope: Send
team_idto restrict the tag to a team, ornullto make it global. Leave it out to keep the current scope. Restricting the tag removes it from every asset outside the team's datastores, and making it global again does not put it back. See Changing a Tag's Scope. - External tags: Send
"type": "external"withcategoryandweight_modifieronly. Their name, description, and color come from the data catalog.
Example request (change the weight)
Delete a Tag¶
Deletes the tag and removes it from every asset that carries it, existing anomalies included. This cannot be undone. To keep the assets tagged, merge the tag instead.
Endpoints: DELETE /global-tags/{name} and POST /global-tags/{id}/delete
Permission: Same as creating the tag.
Read How a Tag Is Used¶
These endpoints return what the tag's page shows.
| Endpoint | Returns | Requires Data Catalog |
|---|---|---|
GET /global-tags/{id}/summary |
The number of assets carrying the tag, by type and by datastore, the number of Flows, how many assets are in datastores you can't access (hidden_count), and when and where the tag was last applied. |
|
GET /global-tags/{id}/quality-score |
The tag's current quality score, across the tables and files that carry it. | |
GET /global-tags/{id}/quality-scores |
The score history. granularity picks the interval, day by default. |
|
GET /global-tags/{id}/activity |
The timeline: changes to the tag, assets tagged and untagged, merges, scans, Flow runs, and comments. Pages through with size (up to 100) and the cursor from the previous page. |
|
GET /global-tags/{id}/activity/{entry_id}/assets |
The assets one timeline entry touched, as they were then. | |
GET /global-tags/{id}/assets |
The assets carrying the tag, paginated. |
The assets endpoint takes these query parameters:
| Query Parameter | Type | Description |
|---|---|---|
asset_type |
list of strings |
datastore, container, field, check, template, anomaly, flow, or operation. |
datastore |
list of integers |
Only assets in these datastores. |
container |
list of integers |
Only assets in these tables or files. |
check_status |
list of strings |
Active or Draft, for checks. |
anomaly_impact_level |
list of strings |
The impact levels of anomalies. |
table_type |
list of strings |
table, view, file, or computed. |
search |
string |
Match the asset's name or identifier. |
sort |
string |
created (default) or name. |
direction |
string |
desc (default) or asc. |
page, size |
integer |
Page number, and page size up to 100. |
Each asset in the response says whether you can edit it (editable), which decides whether a move or remove can reach it.
Explore the Tag Map¶
These endpoints return what the Map tab draws: the tagged assets as nodes, grouped by datastore, and the edges that connect them. Anomalies on the map are open ones only. All four require the Data Catalog module and the Member role or above, and take a JSON body.
| Endpoint | Returns |
|---|---|
POST /global-tags/{id}/graph |
The first view of the map: the datastores and their first tables, the check templates and Flows that belong to no datastore (standalone), how many assets are in datastores you can't access (hidden_count), and where each branch continues. |
POST /global-tags/{id}/graph/children |
One more page of a branch: the tables or operations of a datastore, or the fields, checks, or anomalies of a table. |
POST /global-tags/{id}/graph/search |
The assets that match a search, grouped by type. |
POST /global-tags/{id}/graph/locate |
One table, field, check, or anomaly with the path that leads to it, to center the map on it. |
Every request takes a scope, which holds the same filters as the assets endpoint (datastore, container, search, check_status, anomaly_impact_level, and table_type) plus layers: any of fields, checks (checks and check templates), anomalies, and automation (Flows and operations), all four by default. On the first endpoint, these fields sit at the top level of the body, next to datastore_offset and standalone_offset, which page through datastores and standalone assets.
| Endpoint | Field | Description |
|---|---|---|
graph/children |
node_type |
datastore or container. |
graph/children |
node_id |
The ID of that datastore or table. |
graph/children |
relation |
containers or operations under a datastore. fields, checks, or anomalies under a table. |
graph/children |
offset, size |
Where the page starts, and its size: up to 20 tables, or up to 12 of anything else (12 by default). |
graph/children |
search |
Match the name or ID of the items in the branch. |
graph/children |
check |
With anomalies, only the anomalies this check raised. |
graph/search |
search |
The name or ID to match, 1 to 200 characters. Required. |
graph/search |
kind |
Only one type: datastore, container, field, check, anomaly, operation, flow, or template. |
graph/search |
offset, size |
Where the page starts, and its size, up to 20 (5 by default). |
graph/locate |
asset_type |
container, field, check, or anomaly. Required. |
graph/locate |
asset_id |
The asset's ID. Required. |
Each node says whether it carries the tag (tagged) and, in stats, how many open anomalies that carry the tag it reaches. Within a branch, the nodes with the most open anomalies come first.
Example request
Move, Remove, and Merge¶
These actions change many assets at once. Move and remove reach only the assets you can edit. Moving or removing the tag on a datastore, a table or file, a field, or a check template also moves or removes it on the assets it reaches, such as the checks of a field or of a template. External tags cannot be moved, removed, or merged, and cannot be the target.
All three require the Data Catalog module, and each returns { "success": true }.
Preview the Change¶
Returns what an action would change, without changing anything: the number of assets by type and by datastore, the Flows and other references that would switch, the assets that already carry the target tag, and the assets the action would skip with the reason.
Endpoint: POST /global-tags/{id}/impact
Permission: Member role or above. A merge preview requires the Admin role.
| Field | Type | Description |
|---|---|---|
action |
string |
move, remove, or merge. |
target_id |
integer |
The tag that replaces it. Required for move and merge. |
assets |
list |
The assets to act on, each as {"asset_type": ..., "asset_id": ...}, up to 1,000. Leave it out for every asset carrying the tag. |
POST /global-tags/{id}/impact/assets takes the same body, plus paging and filters, and lists the assets the action would change.
Move a Tag¶
Takes the tag off the assets and puts target_id on them instead. Both tags stay.
Endpoint: POST /global-tags/{id}/move
Permission: Member role or above, on the assets you can edit.
Example request
Remove a Tag¶
Takes the tag off the assets. The tag stays in the library.
Endpoint: POST /global-tags/{id}/remove
Permission: Member role or above, on the assets you can edit.
The body takes assets, as in Preview the Change. Leave it out to remove the tag from every asset you can edit.
Merge a Tag¶
Moves everything that uses the tag (assets, Flows, schedules, and saved filters) to target_id, then deletes the tag. This cannot be undone.
Endpoint: POST /global-tags/{id}/merge
Permission: Admin role