Skip to main content
A tag is a free-form label scoped to your org. Articles attach to tags many-to-many. Tags are flat (no hierarchy) and reusable across knowledge bases and categories — use them to slice content by audience, surface area, or any orthogonal axis that doesn’t fit the category tree.

When to reach for tags

Audience slicing

b2b, b2c, enterprise — surface different subsets of the same KB to different chatbots.

Search filters

Let users narrow KB search by topic without rebuilding your category tree.

Internal flags

needs-review, legal-approved, stale — workflow state that doesn’t belong on the status field.

Anatomy

{
  "object": "article_tag",
  "id": "5d694e14-5440-4f5d-9e8a-7c3b2a1d0f9e",
  "name": "customer-facing",
  "created_at": "2026-05-22T14:00:00Z"
}
Tags carry just an id, a name, and a creation timestamp. There is no description, color, or hierarchy. The name is unique per org.

The two surfaces

Tags live behind two related endpoints:

Tag CRUD

POST /article-tags, GET /article-tags, DELETE /article-tags/{id} manage the tag rows themselves — create reusable labels, list them, retire them.

Article tag assignments

GET /articles/{id}/tags returns the tags on one article. PUT /articles/{id}/tags replaces the full set of assignments in a single call.
There is no “add a single tag to an article” endpoint — assignments are replaced as a set. Send the full list of tag_ids you want the article to carry.

Creating tags

curl https://api.awardee.dev/v1/article-tags \
  -X POST \
  -H "Authorization: Bearer aw_live_4f8a3c7e2d1b9a5c6f8e3d2c1b4a9f7e" \
  -H "Content-Type: application/json" \
  -d '{ "name": "customer-facing" }'

Listing tags

GET /article-tags paginates. Pass search to fuzzy-match on name.
curl "https://api.awardee.dev/v1/article-tags?search=customer&page_size=50" \
  -H "Authorization: Bearer aw_live_4f8a3c7e2d1b9a5c6f8e3d2c1b4a9f7e"

Assigning tags to an article

PUT /articles/{id}/tags replaces the assignment set. Send the complete list of tag_ids you want; anything not in the list is unassigned.
curl https://api.awardee.dev/v1/articles/8f3a9d2e-1b4c-4f5d-9e8a-7c3b2a1d0f9e/tags \
  -X PUT \
  -H "Authorization: Bearer aw_live_4f8a3c7e2d1b9a5c6f8e3d2c1b4a9f7e" \
  -H "Content-Type: application/json" \
  -d '{
    "tag_ids": [
      "5d694e14-5440-4f5d-9e8a-7c3b2a1d0f9e",
      "1b4c4f5d-9e8a-7c3b-2a1d-0f9e8f3a9d2e"
    ]
  }'
To clear all tags from an article, send {"tag_ids": []}. To add a single tag to an article that already has tags, first GET /articles/{id}/tags, append the new id, then PUT the full list back.
List endpoints (GET /articles) return tag_names inline on each article. Use that to avoid a follow-up tag lookup for every row.

Deleting a tag

DELETE /article-tags/{id} removes the tag and unassigns it from every article that carried it. Articles themselves are untouched. There is no soft-delete — recreate the tag and re-assign if you change your mind.
curl https://api.awardee.dev/v1/article-tags/5d694e14-5440-4f5d-9e8a-7c3b2a1d0f9e \
  -X DELETE \
  -H "Authorization: Bearer aw_live_4f8a3c7e2d1b9a5c6f8e3d2c1b4a9f7e"
A 204 confirms the delete. The articles that had the tag remain — only the assignment rows are dropped.