---
title: "Create or update tags"
method: PUT
path: "/tags"
tags: ["Tags"]
---

# Create or update tags

`PUT /tags`

## Request

- Base URL: `https://api.surense.com/api/v1`
- URL: `https://api.surense.com/api/v1/tags`
- Auth: OAuth 2
  - Client credentials
  - Token URL: `https://api.surense.com/oauth/token` scopes: `global:metadata:manage`

Upserts a batch of tags in the caller's tenant in a single transaction:

- a record **without** `id` creates a new tag and publishes a tag-created domain event (`ETagCreatedEvent`);
- a record **with** `id` updates the `label` and `active` flag of that existing tag (no event is published for updates).

Tags not mentioned in the request are left untouched — this is not a full replace, and tags cannot be deleted through this operation (use `DELETE /tags/{tagId}`). The response contains only the created/updated tags, in request order.

**Authorization:** requires the `global:metadata:manage` scope.

**Errors (400):** empty `tags` list; the same `label` used twice in one request; a blank label or a label longer than 255 characters; missing `active`; an `id` that does not exist in the tenant; a concurrent modification of the same tag. Duplicate labels are only checked within the request, not against tags that already exist. Any error rolls back the whole batch.

## Request body

- UpdateTagsRequest: Batch of tags to create and/or update in the caller's tenant
  - `tags` Record[], required: Tags to create or update; at least one.
    - `id` string, uuid: ID of an existing tag to update. Omit (or null) to create a new tag; an unknown ID is rejected with 400.
    - `label` string, required: Display label. Non-blank, at most 255 characters, unique within the request.
    - `active` boolean, required: Whether the tag is active (offered for selection). Required.

## Response `200`

The created and updated tags, in request order.

- TagValue[]
  - `tenantId` string, uuid
  - `agencyId` string, uuid
  - `createdDate` string, date-time
  - `createdBy` string, uuid
  - `creatorName` string
  - `lastModifiedDate` string, date-time
  - `lastModifiedBy` string, uuid
  - `version` integer
  - `id` string, uuid: Tag ID
  - `label` string: Display label (1-255 characters)
  - `active` boolean: Whether the tag is active (offered for selection)

## Other responses

- `400`: Invalid request (see description) — nothing is saved.
- `403`: The token lacks the `global:metadata:manage` scope.

---

[API](https://skmtc.dev/surense/apis/tags-api.md) - [All operations](https://skmtc.dev/surense/apis/tags-api/llms.txt) - [OpenAPI document](https://skmtc.dev/surense/apis/tags-api/revisions/90f42c1ba756?raw)
