Tags
Label assets, identities, and results with a shared vocabulary
A tag is a colored label you create once and apply to the things you work with. Tags let you carve up a large library by campaign, season, client, or review state, and then filter on those labels when listing assets, identities, and results.
Tags come in two kinds:
- System tags are provided by the platform and available to everyone. You can apply them, but you cannot edit or delete them.
- Your tags are the ones you create. They are visible to you and to the members of your groups.
Key fields
| Field | Description |
|---|---|
id | Stable identifier you pass when assigning or filtering |
name | Display name, 1 to 64 characters |
color | Six-digit hex color, for example #2E5A3B |
created_by | Email of the creator, null for system tags |
created_at | Creation datetime (UTC, ISO 8601) |
The list endpoint returns everything you can see in one response, split into a system array and a user array.
Creating tags
You can create a tag up front with the create endpoint, or inline while assigning. Every endpoint that accepts tags takes the same pair of fields:
| Field | Description |
|---|---|
tag_ids | Identifiers of existing tags to apply |
new_tags | Tags to create and apply in the same call |
import requests
api_url = "https://v2.api.piktid.com"
asset_id = "a1b2c3d4..."
response = requests.put(
f"{api_url}/assets/{asset_id}/tags",
headers={"Authorization": "Bearer " + access_token},
json={
"tag_ids": ["4f1c...", "9ab2..."],
"new_tags": [{"name": "SS26 campaign", "color": "#2E5A3B"}],
},
)Creating a tag never reuses an existing one by name. Sending the same name twice produces two separate tags. List the tags you already have and reuse their id when you want a single shared label.
Tag names are stored exactly as you send them, including case and spacing. They are not normalized and do not have to be unique.
Editing and deleting
You can rename or recolor any tag you created. Tags created by a teammate are visible and usable but cannot be modified, and system tags are read-only for everyone.
| Situation | Result |
|---|---|
| Your own tag | Update and delete succeed |
| A system tag | 403 Forbidden |
| A teammate's tag | 404 Not Found |
Deleting a tag removes it everywhere at once: it disappears from the tag list, from every object carrying it, and from any filter referencing it. Deletion is not reversible through the API.
What you can tag
| Object | Assign to | Returned as |
|---|---|---|
| Assets | PUT /assets/{asset_id}/tags | user_tags |
| Identities | PUT /identity/{identity_code}/tags | user_tags |
| Job output images | PUT /jobs/{job_id}/outputs/{image_index}/tags | tags |
Assigning follows the same rules everywhere:
- Assignment is additive. A call adds the tags you send and leaves existing ones untouched. There is no replace operation.
- Assigning a tag you already applied is a no-op. The request still succeeds.
- Removing is idempotent. Removing a tag that is not there returns
204 No Content. - Unknown or inaccessible tag identifiers return
400, together with the list of identifiers that could not be found. Nothing is applied when this happens.
Who can assign depends on the object, not on the tag: you can tag anything you can already reach, whether you own it or reach it through a group.
Tagging on upload
The upload endpoint accepts tag_ids and new_tags so a file arrives already labelled. Bulk upload does not take tags: apply them afterwards with the asset endpoint.
If any tag identifier is unknown, the upload fails with 400 and no asset is created. Nothing is uploaded partially tagged.
Tagging output images
Job outputs are versioned: regenerating or retouching an image produces a new version of the same output. Tags belong to the version they were applied to and do not carry forward. Reading results back, each output's tags field reflects only that specific version's own assignments.
Assignment targets the latest version by default. Pass version to target an older one, and group_index when the job produces several groups of outputs per input.
A new version starts with no tags of its own, even if an earlier version of the same output was tagged. GET /jobs/{job_id}/results and both gallery endpoints only ever return the latest version of an output, so a regenerate or retouch will visibly clear its tags until you re-apply them.
Removing a tag works the other way by default: DELETE /jobs/{job_id}/outputs/{image_index}/tags/{tag_id} with no version removes the tag from every version of that output, not just the latest one. Pass version to remove it from one specific version only.
Each result in GET /jobs/{job_id}/results and both gallery endpoints also carries a tags array on every entry in inputs, and, for detail_repair jobs, on every entry in detail_repair_references, so you can label input and output images from a single response.
Filtering
Listing endpoints accept tag_ids as a repeated query parameter, for example ?tag_ids=4f1c...&tag_ids=9ab2....
Matching is inclusive: an object is returned if it carries any of the tags you list. There is no exclusion counterpart, and unknown identifiers simply match nothing rather than returning an error.
Filtering by tag is supported on:
GET /assetsGET /identityGET /jobs/{job_id}/resultsGET /gallery/by-projectGET /gallery/by-job
On results and galleries, an output matches when its latest version carries the tag. Since tags do not carry forward across regenerate/retouch, an output that was tagged and later regenerated without re-tagging no longer matches. This keeps the filter consistent with what tags actually shows for that output.
On GET /assets, tag_ids is separate from the include_tags and exclude_tags parameters, which filter on the fixed asset labels described in Assets. The two can be combined in one request.
Visibility and sharing
Tags are personal but group-visible. You can see and apply:
- every system tag
- every tag you created
- every tag created by a member of one of your groups
There is no separate share step. Joining a group is what makes a teammate's tags available to you.
A tag becomes visible to everyone who can see the object it is applied to, including its name, color, and the email of whoever created it. Treat tag names as shared with your collaborators rather than private notes.
See Groups for how groups themselves work.
Good to know
- There is no limit on how many tags an object can carry, or on how many tags you can create.
- Colors must be a full six-digit hex string starting with
#. Shorthand and alpha values are rejected. - The tag list is not paginated and not searchable. Fetch it once and cache it in your integration.
- Tags are metadata only. Applying one never consumes credits and never affects how a job is processed.
API endpoints
Managing tags
List tags GET
/tagsCreate a tag POST
/tagsEdit a tag PATCH
/tags/{tag_id}Delete a tag DELETE
/tags/{tag_id}Assigning tags
Assign user-defined tags to an asset (additive, create-if-missing). PUT
/assets/{asset_id}/tagsRemove one user-defined tag assignment from an asset. DELETE
/assets/{asset_id}/tags/{tag_id}Remove one tag assignment from an identity. DELETE
/identity/{identity_code}/tags/{tag_id}Assign tag to output image PUT
/jobs/{job_id}/outputs/{image_index}/tagsRemove tag from output image DELETE
/jobs/{job_id}/outputs/{image_index}/tags/{tag_id}