> For the complete documentation index, see [llms.txt](https://docs.vomevolunteer.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vomevolunteer.com/resources/database/profile-tags/write-operations.md).

# Write Operations

These endpoints create profile tags, and apply or remove them on profiles.

#### Endpoints

```plaintext
POST api/profile-tags/bulk-create/
POST api/profile-tags/assign/
POST api/profile-tags/unassign/
```

## Create profile tags

Accepts a single object or a list of objects. Tag titles are unique within an organization, so a title that already exists is skipped and reported back rather than failing the request. That means you can safely re-run the same import.

```plaintext
POST api/profile-tags/bulk-create/
```

* **tag\_title** (`string`, required): The title of the tag.

#### Example Request Payload

```json
[
    { "tag_title": "Board Member" },
    { "tag_title": "First Aid Certified" }
]
```

#### Example Response

```json
{
    "created": [
        {
            "id": "ec007482-7c9a-4ec0-963d-8cb0048ff2fc",
            "tag_title": "Board Member"
        }
    ],
    "skipped": [
        {
            "tag_title": "First Aid Certified",
            "reason": "already exists"
        }
    ]
}
```

## Assign tags to profiles

Applies every listed tag to every listed profile. Tags are **added** to what the profile already has, so this never removes a tag applied elsewhere.

```plaintext
POST api/profile-tags/assign/
```

* **user\_ids** (`array`, required): The profiles to tag, by Vome ID. A single **user\_id** is also accepted.
* **tag\_ids** (`array`, required): The tags to apply, by ID. A single **tag\_id** is also accepted.

#### Example Request Payload

```json
{
    "user_ids": [
        "a9a1028f-93a6-401d-9867-1fe59aa2d830",
        "d2fcbe43-1eba-419e-a489-3d471f7658ff"
    ],
    "tag_ids": [
        "ec007482-7c9a-4ec0-963d-8cb0048ff2fc"
    ]
}
```

#### Example Response

```json
{
    "assigned": [
        {
            "user_id": "a9a1028f-93a6-401d-9867-1fe59aa2d830",
            "assigned_tag_ids": ["ec007482-7c9a-4ec0-963d-8cb0048ff2fc"]
        }
    ],
    "skipped_user_ids": ["d2fcbe43-1eba-419e-a489-3d471f7658ff"]
}
```

{% hint style="info" %}
A profile that is not in your organization is skipped and listed in **skipped\_user\_ids**. A tag that does not exist fails the whole request, because a silently ignored tag would leave you believing profiles were tagged when they were not.
{% endhint %}

## Remove tags from profiles

Removes every listed tag from every listed profile. The body is the same shape as the assign endpoint.

```plaintext
POST api/profile-tags/unassign/
```

#### Example Response

```json
{
    "removed": [
        {
            "user_id": "a9a1028f-93a6-401d-9867-1fe59aa2d830",
            "removed": 1
        }
    ],
    "skipped_user_ids": []
}
```
