# Delete API — Remove Samples from Spectra Analyze

> Delete samples and analysis data from Spectra Analyze. DELETE /api/samples/{hash}/ removes files, metadata, and extracted children.

## Delete a sample

``DELETE /api/samples/{hash_value}/``

Delete the sample with the requested hash value. All related data, including extracted samples and metadata, will be deleted from the Spectra Analyze instance.

**Note:** there are two exceptions when the sample will not be deleted:

1. when the requested hash matches an extracted file rather than an independently uploaded sample
2. when the requested hash matches an uploaded sample that is currently being processed

In these cases, the `405 Method Not Allowed` status code is returned in the response for SHA1 hashes. The 404 status code is returned instead of 405 for MD5 and SHA256 hashes.

### Request Format

**Request Parameters**

| NAME       | REQUIRED | DESCRIPTION                                                  | TYPE         |
| :--------- | :------- | :----------------------------------------------------------- | :----------- |
| hash_value | Required | Hash of the sample that should be deleted from the appliance. Only one hash can be submitted in one request. Supported hash types: SHA1, SHA256, SHA512, MD5 | path, string |

**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/samples/00d33e57051fdd38407b9251bf2843645d567342/' \
  --header 'Authorization: Token exampletoken'
```

**Python**

```python

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

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)
print(response.text)
```

### Response Format

**Response Examples**

```json
"code": 200,
        "message": "Sample deleted successfully.",
        "detail": {
                "md5”: "07958b6f37e9f49ca71c3b4ebf755d26"
                "sha1": "00d33e57051fdd38407b9251bf2843645d567342"
                "sha256": "0249d5eeeca4c373af785047f7ac488f1632a20ee97acdba81b1bcbb89cf6b86"
                "sha512": "1bbe06bcc7052503f65ed4ae2e4c93e4875170b7863 …"
        }
}
```

**Empty response**

When trying to delete a sample that does not exist on the Spectra Analyze instance, an empty response is returned.

```
{
   "message":"Not found.",
   "code":404,
   "detail":{}
}
```

**Response Fields**

| FIELD NAME | TYPE    |
| :--------- | :------ |
| code       | integer |
| message    | string  |
| detail     | object  |

`detail`:

| FIELD NAME | TYPE   |
| :--------- | :----- |
| sha1       | string |
| sha256     | string |
| sha512     | string |
| md5        | string |

**Response Status Codes**

| CODE | DESCRIPTION        |
| :--- | :----------------- |
| 200  | OK                 |
| 404  | Not Found          |
| 405  | Method Not Allowed |

## Delete multiple samples

**Important: The API should be used with caution, because using it simultaneously with other actions such as uploading or reanalyzing samples may cause issues.**


This API provides two endpoints:

- Endpoint 1 is used to send a list of samples that should be removed.
- Endpoint 2 is used to check the status of the sample removal task.

### Request removing samples

```
POST /api/samples/v2/delete_bulk/
```

Endpoint 1 accepts a POST request with a list of sample hashes to be deleted from the Spectra Analyze appliance. Sample removal is initialized as an asynchronous task. Requested samples, their extracted files, and all their metadata are deleted from the appliance database and from the disk. Samples that cannot be deleted will be skipped.

The response to the POST request contains the ID of the removal task. This ID can then be used in a GET request to Endpoint 2 to check the status of the removal task. The status can be checked for up to 36 hours from the moment the task is initialized.

#### Request Format

**Request Parameters**

| NAME        | REQUIRED | DESCRIPTION                                                  | TYPE        |
| :---------- | :------- | :----------------------------------------------------------- | :---------- |
| hash_values | Required | Hash of the sample(s) that should be deleted from the appliance. At least one hash must be provided in the request. Different hash types can be used in a request. Supported hash types: SHA1, SHA256, MD5 | 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/samples/v2/delete_bulk/' \
  --header 'Authorization: Token exampletoken' \
  --header 'Content-Type: application/json' \
  --data '{"hash_values":["988881adc9fc3655077dc2d4d757d480b5ea0e11", "f1d2d2f924e986ac86fdf7b36c94bcdf32beec15"]}'
```

**Python**

```python

# Change the token
token = "exampletoken"
# Change the hostname in the URL
url = "https://appliance.example.com/api/samples/v2/delete_bulk/"
json={"hash_values": ["988881adc9fc3655077dc2d4d757d480b5ea0e11", "f1d2d2f924e986ac86fdf7b36c94bcdf32beec15"]}

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
{
   "id": "516164e6-4e4a-b18c-0cc51a1368d2"
}
```

**Response Status Codes**

| CODE | DESCRIPTION                  |
| :--- | :--------------------------- |
| 200  | Task successfully initiated. |
| 400  | Validation error.            |

### Check sample removal status

```
GET /api/samples/v2/delete_bulk/status/?id={task_id}
```

The second endpoint accepts a GET request with the required *id* parameter. The value of this parameter should match the *id* value returned in the response to the POST request previously sent to Endpoint 1.

The sample removal task may not delete all requested samples, even if the request is successful. Likewise, even if the request fails, some hashes may still be deleted from the appliance.

The response to the GET request contains information about the status of the sample removal task, expressed as a standard status code and a descriptive message. Additionally, it can contain the *details* section, listing which hashes from the POST request are currently (not) present on the appliance.

#### Request Format

**Request Parameters**

| NAME    | REQUIRED | DESCRIPTION                                                  | TYPE          |
| :------ | :------- | :----------------------------------------------------------- | :------------ |
| task_id | Required | The ID of the sample removal task. Use the *id* value from the **Endpoint 1** response with this parameter. | query, 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/samples/v2/delete_bulk/status/?id=1234' \
  --header 'Authorization: Token exampletoken'
```

**Python**

```python

# Change the values of url, token, and ID
token = "exampletoken"
ID = "123" # From the response of the bulk delete API
url = f"https://appliance.example.com/api/samples/v2/delete_bulk/status/?id={ID}"

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
{
   "msg": "Task {task_id} finished successfully. Note: this does not necessarily mean that all requested samples were deleted. See detail for samples that currently exist and samples that do not."
   "detail": {
      "samples_not_exists": [
         "988881adc9fc3655077dc2d4d757d480b5ea0e11",
         "f1d2d2f924e986ac86fdf7b36c94bcdf32beec15"],
      "samples_exists": [
         "f14cede58a12140639e3cffbb7c6dc97ed74fd86"],
   }
}
```

**Response Fields**

| FIELD NAME | DATA TYPE |
| :--------- | :-------- |
| code       | integer   |
| msg        | string    |
| detail     | array     |

| FIELD NAME         | DESCRIPTION                                                  | TYPE   |
| :----------------- | :----------------------------------------------------------- | :----- |
| samples_not_exists | Hashes that were requested to be deleted and are currently not present on the appliance. | string |
| samples_exists     | Hashes that were requested to be deleted and are currently present on the appliance. | string |

**Response Status Codes**

| CODE | DESCRIPTION                                                  |
| :--- | :----------------------------------------------------------- |
| 200  | Task finished.                                               |
| 202  | Task is still running.                                       |
| 404  | Task ID not found.                                           |
| 500  | Error while executing task. It is possible that some samples were deleted; check the response for more details. |
