# Tags API — Manage User Tags for Samples

> Add, remove, and list user tags for samples on Spectra Analyze. GET/POST/DELETE /api/samples/{hash}/usertags/ for custom sample organization.

With this API, users can list existing tags and add/remove one or more tags for any sample on the Spectra Analyze appliance. The API only allows working with User Tags (custom tags created by users), and cannot be used to modify System Tags (non-editable tags generated by Spectra Core during file analysis). Learn more about [tags and how they work](../tags.md) on the Spectra Analyze appliance.

The API accepts GET, POST, and DELETE requests with a single sample hash per request. Supported hash types are SHA1, SHA256, MD5. The sample hash is a required parameter that must be provided in every request.

## Retrieve User Tags for a sample

```
GET /api/tag/{sample_hash}/
```

Lists existing tags for the requested sample, if there are any. The sample hash is a required parameter that must be provided in the request. Supported hash types are SHA1, SHA256, MD5.

Only User Tags are returned in the response - if the sample has any System Tags, they will not be included in the response. If the requested sample doesn’t have any User Tags at all, the response contains an empty list.

### Request Format

**Request Parameters**

| NAME        | REQUIRED | DESCRIPTION                                                  | TYPE         |
| :---------- | :------- | :----------------------------------------------------------- | :----------- |
| sample_hash | Required | Hash of the sample for which the user wants to list existing User Tags. The sample must be present on the appliance prior to sending a request. Supported hash types: SHA1, SHA256, MD5 | path, string |

**Request Examples**

**cURL**

```bash
# Add --insecure before the URL if you are using a self-signed SSL certificate
curl -X GET 'https://appliance.example.com/api/tag/00b814bad1ede64dd87ecf218d5e90f13dd408ae/' \
  --header 'Authorization: Token exampletoken'
```

**Python**

```python

# Change the values of url, token, and hash_value
token = "exampletoken"
hash_value = "6229448f764c8692579e242d1479ee529632203a"
url = f"https://appliance.example.com//api/tag/{hash_value}/"

headers = {
    "Authorization": f"Token {token}"
}

# Add verify=False in the request if you are using a self-signed SSL certificate
response = requests.get(url, headers=headers)
print(response.text)
```

### Response Format

**Response Examples**

```json
[
   "tag1",
   "tag2",
   "tag3",
   "Tag_1"
]
```

**Response Status Codes**

| CODE | DESCRIPTION                                                  |
| :--- | :----------------------------------------------------------- |
| 200  | Successful request                                           |
| 403  | Authentication credentials were not provided. The API token must be included in every request. / Invalid API token. |
| 404  | Malformed hash or missing trailing slash in the endpoint. / Sample does not exist on the appliance. |

## Create User Tags for a sample

```
POST /api/tag/{sample_hash}/
```

Adds one or more User Tags to the requested sample, regardless of whether the sample already has any tags. The prerequisite is that the sample exists on the appliance.

**Tip: Users who wish to add tags to samples that exist in the ReversingLabs Spectra Intelligence cloud, but are not present on the appliance, can download them from the cloud using the [Download API](./download-api.md).**
Alternatively, the ReversingLabs Spectra Intelligence File Download API (TCA-0201) can be used in combination with the [Submissions API](./submissions.md).

In this workflow, the Spectra Intelligence File Download API is used to fetch samples from the cloud to the local system. The users can then upload those samples to Spectra Analyze and add tags to them in the upload POST request. For more information about using the Spectra Intelligence File Download API, contact ReversingLabs Support.

The sample hash is a required parameter that must be provided in the request. Supported hash types are SHA1, SHA256, MD5.

All POST requests to this API must contain the `Content-Type: application/json` header. Tags must be provided in the request body according to the following format:

```json
{"tags": ["tag1", "tag2", ...]}
```

The response to a successful request is a list of tags added to the sample.

If the request contains one or more duplicate User Tags (tags that have already been added to the sample), those will be ignored. Such duplicate tags won’t be added to the sample, and won’t be listed in the response.

If the user attempts to add a tag that is identical to a System Tag already added to the sample, it will be ignored. However, it is possible to add a User Tag identical to a System Tag if the requested sample does not have that System Tag.

For example, `antisandbox` is a System Tag. If the requested sample has this tag, attempting to add a tag called `antisandbox` will not succeed. If the requested sample doesn’t have it, the `antisandbox` tag will be added as a User Tag, and listed in the response.

If the request contains only duplicate tags, the response will be empty. If other valid, unique tags are sent in the same request with duplicate tags, then only the unique tags will be added to the sample and listed in the response.

If any of the tags in the request is malformed, the request will fail and no tags will be added to the sample. The response will indicate which tag was malformed by the number of its element in the `tags` array.

### Request Format

**Request Parameters**

| NAME        | REQUIRED | DESCRIPTION                                                  | TYPE         |
| :---------- | :------- | :----------------------------------------------------------- | :----------- |
| sample_hash | Required | Hash of the sample to which the user wants to add one or more User Tags. The sample must be present on the appliance prior to sending a request. Supported hash types: SHA1, SHA256, MD5 | path, string |
| tags        | Required | One or more tags to add to the requested sample. A single tag must be between 2 and 40 characters long (including spaces), matching the supported pattern. Supported characters for tags are `[a-z0-9][a-z0-9 /._-]`. Tags are case-sensitive and distinguish spaces from underscores. In other words, `Example` and `example` are two separate tags; `test_tag` and `test tag` are separate tags, too. The following examples are **valid tags**: `malware_1`, `ClassifiedByYARA`, `false-positive`, `Better.Test/Tag`. The following examples illustrate **invalid tags**: `Ž++`, `#hashtag`, `*.exe`. | form, array  |

**Request Examples**

**cURL**

```bash
# Add --insecure before the URL if you are using a self-signed SSL certificate
curl -X POST 'https://appliance.example.com/api/tag/00b814bad1ede64dd87ecf218d5e90f13dd408ae/' \
  --header 'Authorization: Token exampletoken' \
  --header 'Content-Type: application/json' \
  --data '{"tags":["new-tag", "Another_Tag"]}'
```

**Python**

```python

# Change the values of token and hash_value
token = "exampletoken"
hash_value = "examplehash"
# Change the hostname in the URL
url = f"https://appliance.example.com/api/tag/{hash_value}/"

json = {"tags": ["new-tag", "Another_Tag"]}

headers = {'Authorization': f'Token {token}'}

# Add verify=False in the request if you are using a self-signed SSL certificate
response = requests.post(url, headers=headers, json=json)
print(response.text)
```

### Response Format

**Response Examples**

```json
[
   "new-tag",
   "Another_Tag"
]
```

**Response Status Codes**

| CODE | DESCRIPTION                                                  |
| :--- | :----------------------------------------------------------- |
| 200  | Successful request                                           |
| 403  | Authentication credentials were not provided. The API token must be included in every request. / Invalid API token. |
| 404  | Malformed hash or missing trailing slash in the endpoint. / Sample does not exist on the appliance (but may exist in the Spectra Intelligence cloud). |

## Delete User Tags from a sample

``DELETE /api/tag/{sample_hash}/``

Removes one or more User Tags from the requested sample. The prerequisite is that the sample exists on the Spectra Analyze appliance.

The sample hash is a required parameter that must be provided in the request. Supported hash types are SHA1, SHA256, MD5.

All POST requests to this API must contain the `Content-Type: application/json` header. Tags must be provided in the request body according to the following format:

```json
{"tags": ["tag1", "tag2", ...]}
```

The response to a successful request is a list of removed tags.

If any of the tags in the request is malformed, the request will fail and no tags will be removed. The response will indicate which tag was malformed by the number of its element in the `tags` array.

Tags that don’t exist for the sample are ignored and not included in the response. If the request contains a combination of tags that exist and tags that don’t, only the existing ones will be removed and included in the response.

### Request Format

**Request Parameters**

| NAME        | REQUIRED | DESCRIPTION                                                  | TYPE         |
| :---------- | :------- | :----------------------------------------------------------- | :----------- |
| sample_hash | Required | Hash of the sample from which the user wants to remove one or more User Tags. The sample must be present on the appliance prior to sending a request. Supported hash types: SHA1, SHA256, MD5 | path, string |
| tags        | Required | One or more tags to remove from the requested sample. A single tag must be between 2 and 40 characters long (including spaces), matching the supported pattern. Supported characters for tags are `[a-z0-9][a-z0-9 /._-]`. Tags are case-sensitive and distinguish spaces from underscores. In other words, `Example` and `example` are two separate tags; `test_tag` and `test tag` are separate tags, too. The following examples are **valid tags**: `malware_1`, `ClassifiedByYARA`, `false-positive`, `Better.Test/Tag`. The following examples illustrate **invalid tags**: `Ž++`, `#hashtag`, `*.exe`. | form, array  |

**Request Examples**

**cURL**

```bash
# Add --insecure before the URL if you are using a self-signed SSL certificate
curl -X DELETE 'https://appliance.example.com/api/tag/00b814bad1ede64dd87ecf218d5e90f13dd408ae/' \
  --header 'Authorization: Token exampletoken' \
  --header 'Content-Type: application/json' \
  --data '{"tags":["new-tag", "Another_Tag"]}'
```

**Python**

```python

# Change the values of token and hash_value
token = "exampletoken"
hash_value = "examplehash"
# Change the hostname in the URL
url = f"https://appliance.example.com/api/tag/{hash_value}/"

json = {"tags": ["example-tag-1", "Example_Tag_2"]}

headers = {'Authorization': f'Token {token}'}

# Add verify=False in the request if you are using a self-signed SSL certificate
response = requests.delete(url, headers=headers, json=json, verify=False)
print(response.text)
```

### Response Format

**Response Examples**

```json
[
   "delete-this-tag",
   "Old Tag"
]
```

**Response Status Codes**

| CODE            | DESCRIPTION                                                  |
| :-------------- | :----------------------------------------------------------- |
| 200             | Successful request                                           |
| 400 Bad Request | Validation error. Returned when the list of tags is empty, when one or more tags contain unsupported characters, and when the `tags` field is missing in the request body. |
| 403             | Authentication credentials were not provided. The API token must be included in every request. / Invalid API token. |
| 404             | Malformed hash or missing trailing slash in the endpoint. / Sample does not exist on the appliance (but may exist in the Spectra Intelligence cloud). |
