# Edit a sample

`PATCH /v0/labs/sample/{sample_id}`

> **Authentication:** every request must send `X-ConfidentLims-APIKey`, `X-ConfidentLims-Timestamp` (unix seconds) and `X-ConfidentLims-Signature`, an HMAC-SHA256 signature of the request. The examples below call `sign_request()` from the [Request Signing guide](https://api.confidentcannabis.com/v0/docs/request-signing.md) — read it first. Request bodies are form-encoded (`application/x-www-form-urlencoded`), never JSON.

Update one or more fields on a sample. Only the fields you send are changed.

Samples can only be edited while their order is in the 'placed' or 'in progress' status; editing a sample on an order in any other status returns the `invalid_order_status` error. A sample belonging to another lab returns 404 rather than 403.

The IDs for `type_id`, `production_method_id` and `classification_id` are the same ones used when creating a sample, and are listed at `GET /sampletypes`, `GET /sampleproductionmethods` and `GET /sampleclassifications`. The new sample type must belong to the same industry as the sample and its order.

The regulator sample ID cannot be edited through this API, because regulator requirements for changing it differ from state to state.

## Path parameters

- `sample_id` (string, required)

## Body parameters (application/x-www-form-urlencoded)

- `name` (string, optional) — Display name for the sample.
- `strain_name` (string, optional) — Strain the sample came from.
  Example: `Blue Dream`
- `type_id` (integer, optional) — Sample type ID, from `GET /sampletypes`.
- `production_method_id` (integer, optional) — Production method ID, from `GET /sampleproductionmethods`.
- `classification_id` (integer, optional) — Classification ID, from `GET /sampleclassifications`.
- `production_date` (string (date), optional) — Date the sample was harvested or produced.
  Example: `2026-07-28`
- `manifest_id` (string, optional) — Manifest ID in the state's seed-to-sale system.
- `batch_id` (string, optional) — Batch ID from the client's inventory system.
  Example: `BD-2026-08-A`
- `batch_size` (number, optional) — Size of the batch the sample came from.
  Example: `4500`
- `batch_size_unit` (string, optional) — Unit for `batch_size`: `units`, `lb` or `g`.
  Example: `g`
- `lot_id` (string, optional) — Lot ID from the client's inventory system.
- `lot_size` (number, optional) — Size of the lot the sample came from.
- `lot_size_unit` (string, optional) — Unit for `lot_size`: `units`, `lb` or `g`.
- `production_run_id` (string, optional) — Production run ID from the client's system.
- `production_run_size` (number, optional) — Size of the production run.
- `production_run_size_unit` (string, optional) — Unit for `production_run_size`: `units`, `lb` or `g`.
- `units_per_serving` (number, optional) — Serving size, in units.
- `servings_per_container` (number, optional) — Number of servings in one container.
- `unit_description` (string, optional) — What one unit means for this sample.
- `container_description` (string, optional) — What one container means for this sample.
- `regulator_batch_id` (string, optional) — Batch ID in the state's seed-to-sale tracking system.
- `regulator_sample_id2` (string, optional) — (for Leaf) Pre-transfer batch ID.
- `regulator_batch_id2` (string, optional) — (for Leaf) Pre-transfer inventory or lot ID.
- `regulator_lot_id` (string, optional) — Lot ID in the state's seed-to-sale tracking system.
- `harvest_id` (string, optional) — Harvest lot ID in the state's seed-to-sale tracking system.
- `notes` (string, optional) — Free-text notes about the sample.
  Example: `Received in a sealed mylar bag.`
- `lims_id` (string, optional) — Sample ID in the lab's own LIMS.
- `date_samples_collected` (string (date), optional) — Date the sample was collected.
- `custom_field` (string, optional) — Lab-defined custom field.
- `extra_field_1` (string, optional)
- `extra_field_2` (string, optional)
- `extra_field_3` (string, optional)
- `extra_field_4` (string, optional)
- `extra_field_5` (string, optional)
- `extra_field_6` (string, optional)
- `extra_field_7` (string, optional)
- `extra_field_8` (string, optional)
- `extra_field_9` (string, optional)
- `extra_field_10` (string, optional)
- `extra_date_field_1` (string (date), optional)
- `extra_date_field_2` (string (date), optional)
- `extra_date_field_3` (string (date), optional)
- `extra_date_field_4` (string (date), optional)
- `extra_date_field_5` (string (date), optional)
- `extra_bool_field_1` (boolean, optional)
- `extra_bool_field_2` (boolean, optional)
- `extra_bool_field_3` (boolean, optional)
- `extra_bool_field_4` (boolean, optional)
- `extra_bool_field_5` (boolean, optional)
- `external_data` (string, optional) — Arbitrary JSON stored alongside the sample.
- `due_date` (string (date), optional) — Date the results are due back to the client.

## Responses

### 200 Success

Fields (alongside the `success: true` envelope flag):

- `sample` (object)
  - `id` (string) — Sample ID
  - `order_id` (string) — Orders ID
  - `client_id` (integer) — Client ID
  - `lab` (object) — Lab
    - `id` (integer) — Lab ID
    - `name` (string) — Lab Name
  - `order_status_id` (integer) — Order Status ID
  - `order_status_name` (string) — Order Status Name
  - `sample_name` (string) — Name of Sample
  - `strain_name` (string) — Name of Sample Strain
  - `sample_industry_id` (integer) — Sample Industry ID
  - `sample_industry_name` (string) — Sample Industry Name
  - `sample_category_id` (integer) — Sample Category ID
  - `sample_category_name` (string) — Sample Category Name
  - `sample_type_id` (integer) — Sample Type ID
  - `sample_type_name` (string) — Sample Type Name
  - `sample_classification_id` (integer) — Sample Classification ID
  - `sample_classification_name` (string) — Sample Classification Name
  - `production_method_name` (string) — Production Method name
  - `production_method_id` (integer) — Production Method ID
  - `regulator_sample_id` (string) — Unique ID from the state's seed-to-sale tracking system of the sample tested by the lab
  - `regulator_batch_id` (string) — Unique ID from the state's seed-to-sale tracking system of the client's batch from which the sample tested by the lab came
  - `batch_id` (string) — Unique ID from the client's inventory management system of the client's batch from which the sample tested by the lab came
  - `harvest_id` (string) — Unique ID from the state's seed-to-sale tracking system of the client's harvest lot from which the sample tested by the lab came
  - `test_packages` (array of objects)
    - `id` (integer) — Unique ID for Test Package
    - `name` (string) — Test Package Name
    - `price` (number) — Package Price - if 0, call for price
    - `minimum_quantity` (number) — Minimum sample quantity required for testing
  - `last_modified` (timestamp) — Time this sample was last modified
  - `date_published` (timestamp) — Published Date [when sample was published]
  - `initial_weight` (number) — Sample weight at order verification
  - `initial_weight_unit` (number) — Unit type for Initial Weight
  - `test_types` (array of objects)
    - `id` (integer) — Unique ID for Test Type
    - `name` (string) — Test Type Name
    - `abbreviation` (string) — Test Type Abbreviation
  - `cover_image` (object)
    - `filename` (string)
    - `public_key` (string (uuid)) — Unique public key for file
    - `url` (string) — Public URL to access file
  - `images` (array of objects) — Will also contain cover image
    - `filename` (string)
    - `public_key` (string (uuid)) — Unique public key for file
    - `url` (string) — Public URL to access file
  - `notes` (string) — Notes about the sample
  - `batch_size` (number) — Size of the client's batch from which the sample tested by the lab came
  - `batch_size_unit` (string) — Unit type for batch size (units, lb, or g)
  - `lot_id` (string) — Unique ID from the client's inventory management system of the client's lot from which the sample tested by the lab came
  - `lot_size` (number) — Size of the client's lot from which the sample tested by the lab came
  - `lot_size_unit` (string) — Unit type for lot size (units, lb, or g)
  - `production_run_id` (string) — Unique ID from the client's inventory management system of the client's production run from which the sample tested by the lab came
  - `production_run_size` (number) — Size of the client's production run from which the sample tested by the lab came
  - `production_run_size_unit` (string) — Unit type for production run size (units, lb, or g)
  - `manifest_id` (string) — Unique ID from the state's seed-to-sale tracking system of the sample manifest from which the sample tested by the lab came
  - `regulator_lot_id` (string) — Unique ID from the state's seed-to-sale tracking system of the client's lot from which the sample tested by the lab came
  - `regulator_sample_id2` (string) — (for Leaf) Pre-Transfer Batch ID
  - `regulator_batch_id2` (string) — (for Leaf) Pre-Transfer Inventory/Lot ID
  - `production_date` (timestamp) — Harvest/Production Date [when sample was produced]
  - `date_samples_collected` (timestamp) — Collection Date [when sample was collected]
  - `public_url` (string) — Unique URL for viewing this sample or CoA without requiring a login. Should be added to CoAs and used for QR codes or other barcode images so end consumers can verify the integrity of the data
  - `units_per_serving` (number) — Serving Size
  - `servings_per_container` (number) — Number of Servings in one Container
  - `unit_description` (string) — Information describing what a "unit" means for this sample (i.e 1 Bottle)
  - `container_description` (string) — Information describing what a "unit" means for this sample (i.e 1 Gummy)
  - `regulatory_category_id` (integer) — Unique ID for sample's regulatory category
  - `solvents_used` (string) — Information about the solvents used in testing
  - `has_coa` (boolean) — True if sample has a Certificate of Analysis
  - `coa` (object) — URL expires after one hour
    - `filename` (string)
    - `public_key` (string (uuid)) — Unique public key for file
    - `url` (string) — Public URL to access file
  - `coa_additions` (array of objects) — URLs expire after one hour
    - `filename` (string)
    - `public_key` (string (uuid)) — Unique public key for file
    - `url` (string) — Public URL to access file
  - `order_lims_id` (string) — Orders lims ID
  - `lims_id` (string) — Sample lims ID
  - `weight_on_hand` (number) — Current weight on hand
  - `weight_on_hand_unit` (string) — Unit type for weight measurements (units, g, or ml)
  - `has_lab_data` (boolean) — True if sample has test results
  - `has_lab_data_draft` (boolean) — True if sample has draft test results
  - `has_coa_draft` (boolean) — True if sample has a draft Certificate of Analysis
  - `coa_draft` (object) — URL expires after one hour
    - `filename` (string)
    - `public_key` (string (uuid)) — Unique public key for file
    - `url` (string) — Public URL to access file
  - `logs` (array of objects)
    - `user_name` (string) — Name of user who added log
    - `user_id` (integer) — Unique ID for user who added log
    - `log_time` (timestamp) — Timestamp of log creation time
    - `message` (string) — Log Content
  - `custom_field` (string) — Custom Field
  - `external_data` (any) — Custom External Json Data
  - `extra_field_1` (string) — Custom data field
  - `extra_field_2` (string) — Custom data field
  - `extra_field_3` (string) — Custom data field
  - `extra_field_4` (string) — Custom data field
  - `extra_field_5` (string) — Custom data field
  - `extra_field_6` (string) — Custom data field
  - `extra_field_7` (string) — Custom data field
  - `extra_field_8` (string) — Custom data field
  - `extra_field_9` (string) — Custom data field
  - `extra_field_10` (string) — Custom data field
  - `extra_date_field_1` (timestamp) — Custom data field for dates
  - `extra_date_field_2` (timestamp) — Custom data field for dates
  - `extra_date_field_3` (timestamp) — Custom data field for dates
  - `extra_date_field_4` (timestamp) — Custom data field for dates
  - `extra_date_field_5` (timestamp) — Custom data field for dates
  - `extra_bool_field_1` (boolean) — Custom data field for yes/no fields
  - `extra_bool_field_2` (boolean) — Custom data field for yes/no fields
  - `extra_bool_field_3` (boolean) — Custom data field for yes/no fields
  - `extra_bool_field_4` (boolean) — Custom data field for yes/no fields
  - `extra_bool_field_5` (boolean) — Custom data field for yes/no fields
  - `test_package_total_price` (number) — Total price of test packages with custom client pricing and discounts included
  - `due_date` (timestamp) — Due date
  - `has_rushed_test_types` (boolean) — True if sample has rushed test types
  - `rushed_test_types` (array of strings) — List of rushed test type abbreviations

Example:

```json
{
  "success": true,
  "sample": {
    "id": "2601-0143-1",
    "order_id": "2601-0143",
    "client_id": 812,
    "lab": {
      "id": 44,
      "name": "Cascade Analytics"
    },
    "order_status_id": 3,
    "order_status_name": "In Progress",
    "sample_name": "Blue Dream Flower",
    "strain_name": "Blue Dream",
    "sample_industry_id": 1,
    "sample_industry_name": "Cannabis & Hemp",
    "sample_category_id": 1,
    "sample_category_name": "Plant",
    "sample_type_id": 1,
    "sample_type_name": "Flower - Cured",
    "sample_classification_id": 9,
    "sample_classification_name": "Sativa Dominant",
    "production_method_id": 3,
    "production_method_name": "Greenhouse",
    "regulator_sample_id": "1A4060300003B71000001234",
    "regulator_batch_id": "1A4060300003B71000001180",
    "batch_id": "BD-2026-08-A",
    "harvest_id": "HARVEST-2026-07-BD",
    "test_packages": [
      {
        "id": 12,
        "name": "Compliance Panel",
        "price": 275.0,
        "minimum_quantity": 1
      }
    ],
    "last_modified": "2026-08-14T18:03:12",
    "date_published": null,
    "order_lims_id": "ORD-2026-0143",
    "lims_id": "S-2026-0143-1",
    "initial_weight": 12.0,
    "initial_weight_unit": "g",
    "test_types": [
      {
        "id": 1,
        "name": "Cannabinoids",
        "abbreviation": "CAN"
      }
    ],
    "cover_image": null,
    "images": [],
    "notes": "Received in a sealed mylar bag.",
    "batch_size": 4500.0,
    "batch_size_unit": "g",
    "lot_id": "LOT-BD-118",
    "lot_size": 4500.0,
    "lot_size_unit": "g",
    "production_run_id": null,
    "production_run_size": null,
    "production_run_size_unit": null,
    "manifest_id": "0000012345",
    "regulator_lot_id": null,
    "regulator_sample_id2": null,
    "regulator_batch_id2": null,
    "production_date": "2026-07-28",
    "date_samples_collected": "2026-08-12",
    "public_url": "https://orders.confidentcannabis.com/verify/2fd1c0a9",
    "units_per_serving": null,
    "servings_per_container": null,
    "unit_description": null,
    "container_description": null,
    "regulatory_category_id": 7,
    "solvents_used": null,
    "has_coa": false,
    "coa": null,
    "coa_additions": [],
    "weight_on_hand": 9.5,
    "weight_on_hand_unit": "g",
    "has_lab_data": false,
    "has_lab_data_draft": false,
    "has_coa_draft": false,
    "logs": [
      {
        "user_name": "API",
        "user_id": null,
        "log_time": "2026-08-14T18:03:12",
        "message": "Sample edited via API"
      }
    ],
    "custom_field": null,
    "external_data": null,
    "test_package_total_price": 275.0,
    "due_date": "2026-08-19",
    "has_rushed_test_types": false,
    "rushed_test_types": []
  }
}
```

### 400 Bad request

The request was malformed or failed validation. Validation failures include per-field messages in `error_details`. Possible `error_code` values: `invalid_request`, `request_too_old`.

### 401 Unauthorized

Authentication failed. Possible `error_code` values: `missing_api_key`, `invalid_api_key`, `invalid_credentials_type`, `api_access_restricted`, `api_access_denied`, `missing_signature`, `missing_timestamp`, `invalid_timestamp`, `invalid_signature`.

### 403 Permission denied

The API key is valid but does not have permission for this endpoint (for example, a client key calling a labs endpoint). Possible `error_code` values: `permission_denied`.

### 404 Not found

The requested record does not exist or is not visible to this organization. Possible `error_code` values: `not_found`.

## Examples

### cURL

```bash
# X-ConfidentLims-Signature: see the Request Signing guide - https://api.confidentcannabis.com/v0/docs/request-signing.md
curl -X PATCH 'https://api.confidentcannabis.com/v0/labs/sample/{sample_id}' \
  -H 'X-ConfidentLims-APIKey: YOUR_API_KEY' \
  -H 'X-ConfidentLims-Timestamp: UNIX_TIMESTAMP' \
  -H 'X-ConfidentLims-Signature: REQUEST_SIGNATURE'
```

### Python

```python
import time
import requests

# sign_request() is defined in the Request Signing guide:
# https://api.confidentcannabis.com/v0/docs/request-signing.md
from sign_request import sign_request

API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'
path = '/v0/labs/sample/{sample_id}'

data = {
    # optional form fields go here - they are signed too
}

headers = {'X-ConfidentLims-Timestamp': str(int(time.time()))}
headers['X-ConfidentLims-Signature'] = sign_request(
    'PATCH', path, headers, data, API_KEY, API_SECRET)
headers['X-ConfidentLims-APIKey'] = API_KEY

response = requests.patch(
    'https://api.confidentcannabis.com' + path,
    headers=headers,
    data=data,
)
print(response.json())
```

### JavaScript

```javascript
// signRequest() is defined in the Request Signing guide:
// https://api.confidentcannabis.com/v0/docs/request-signing.md
import { signRequest } from './sign_request.js';

const API_KEY = 'YOUR_API_KEY';
const API_SECRET = 'YOUR_API_SECRET';
const path = "/v0/labs/sample/{sample_id}";

const data = {
  // optional form fields go here - they are signed too
};

const headers = { 'X-ConfidentLims-Timestamp': String(Math.floor(Date.now() / 1000)) };
headers['X-ConfidentLims-Signature'] = signRequest(
  "PATCH", path, headers, data, API_KEY, API_SECRET);
headers['X-ConfidentLims-APIKey'] = API_KEY;

const response = await fetch("https://api.confidentcannabis.com" + path, {
  method: "PATCH",
  headers,
  body: new URLSearchParams(data),
});
console.log(await response.json());
```

---

HTML version: https://api.confidentcannabis.com/v0/docs/labs/edit-sample  
OpenAPI spec for this section: https://api.confidentcannabis.com/v0/docs/labs/openapi.json  
Request Signing guide: https://api.confidentcannabis.com/v0/docs/request-signing.md
