# Adjust weight on hand

`POST /v0/labs/sample/{sample_id}/weight_on_hand`

> **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.

Record a change to the sample's weight on hand.

The first adjustment is taken as the sample's initial weight on hand; every
later adjustment appends to a log of alterations over time. An
`amount_changed` of `0` records nothing and simply returns the current weight.

`unit` must be `g` or `ml` or `units`, and `change_reason` must be an integer from the
enum below.

## Change reasons

Unless the lab reports to a regulator, `change_reason` uses this default enum:

- `0` other
- `1` initial
- `2` destroyed
- `3` used
- `4` returned
- `5` lost
- `6` stolen
- `7` addition

Labs in a METRC state should use a reason from their own state's list instead.
Reasons outside a state's list are accepted without error, but the weight change
may reach METRC incorrectly. `0` is an allowable value everywhere; in most
states it is not forwarded to METRC at all.

- **METRC CA**
  - `0` other (Allowable value, not sent to METRC)
  - `2` Scale Variance
  - `3` Sample Tested
  - `106` Sample Tested
  - `101` Waste (Unusable Product)
  - `108` Damage
  - `215` Enforcement Testing
  - `107` Incorrect Quantity
  - `214` Male Plants
  - `213` Mandated Destruction
  - `212` Onsite Testing
  - `211` Over Pulled
  - `210` Research & Development
  - `105` Scale Variance
  - `209` Spoilage
  - `104` State-Authorized Adjustment
  - `103` Theft
  - `208` Trade Sample
  - `207` Under Pulled
  - `102` Voluntary Surrender
  - `206` Weight Change Due to Moisture
- **METRC IL**
  - `0` other (Allowable value, not sent to METRC)
  - `288` Consumed During Testing
  - `287` Entry Error
  - `290` Inventory Audit
  - `286` Package Material
  - `285` Scale Variance
  - `284` Spoilage
  - `283` Theft
  - `282` Waste
- **METRC LA**
  - `0` other (Allowable value, not sent to METRC)
  - `111` Test Sample Waste (Lab only)
  - `116` Potency Testing
  - `122` Contaminant Testing
  - `121` Drying
  - `120` During Transfer
  - `119` Entry Error
  - `118` Package Material
  - `117` Plants Unpacked
  - `115` R&D Testing
  - `114` Scale Variance
  - `113` Spoilage
  - `112` State-Ordered Destruction/State Mandated Destruction
  - `110` Theft
  - `109` Waste
- **METRC MA**
  - `0` other (Allowable value, not sent to METRC)
  - `2` Test Sample Destruction
  - `3` Sample Used During Testing
  - `5` Waste
  - `128` Sample Used During Testing
  - `125` Test Sample Destruction
  - `135` API Related Error
  - `134` Drying
  - `133` Entry Error
  - `132` Over/Under Pulled
  - `131` Package Material
  - `130` Plants Unpacked
  - `129` Processing Loss
  - `127` Scale Variance
  - `126` Spoilage
  - `124` Theft
  - `123` Waste
- **METRC MD**
  - `0` other (Allowable value, not sent to METRC)
  - `2` Drying
  - `3` Waste
  - `5` Spoilage
  - `136` Waste
  - `139` Scale Variance
  - `144` API Adjustment Error
  - `143` Drying
  - `142` Entry Error
  - `141` MCA Inspector Obtained Product
  - `140` Plants Unpacked
  - `138` Spoilage
  - `137` Theft
  - `263` Unaccounted Product
- **METRC ME**
  - `0` other (Allowable value, not sent to METRC)
  - `151` Sample Used During Testing
  - `147` Test Sample Destruction
  - `156` API Related Error
  - `155` Drying
  - `154` Entry Error
  - `153` Over/Under Pulled
  - `152` R&D Sample
  - `150` Scale Variance
  - `149` Spoilage
  - `148` State Mandated Destruction
  - `146` Theft
  - `145` Waste
- **METRC MI**
  - `0` other (Allowable value, not sent to METRC)
  - `3` Waste
  - `6` Scale Variance
  - `157` Waste
  - `159` Spoilage
  - `162` Drying
  - `161` Entry Error
  - `160` Scale Variance
  - `158` Theft
- **METRC MN**
  - `0` other (Allowable value, not sent to METRC)
  - `170` Consumed During Testing
  - `164` Test Sample Destruction
  - `169` Drying
  - `168` Entry Error
  - `295` Hazardous Waste
  - `294` Non-Hazardous Waste
  - `167` Package Material
  - `307` Quantity Discrepancy
  - `165` Spoilage
  - `306` State Investigation
  - `163` Theft
- **METRC MO**
  - `0` other (Allowable value, not sent to METRC)
  - `182` Consumed During Testing
  - `171` Waste
  - `183` API Error
  - `181` Damaged
  - `180` Drying
  - `179` Mandatory State Destruction
  - `178` Moisture Weight Change
  - `177` Over/Under Pulled
  - `176` Package Material
  - `175` Recall
  - `174` Spoilage
  - `173` Theft
  - `172` Typing Error
- **METRC MS**
  - `0` other (Allowable value, not sent to METRC)
  - `281` Drying
  - `280` During Transfer
  - `279` Entry Error
  - `278` Package Material
  - `277` Scale Variance
  - `276` Spoilage
  - `275` Theft
  - `274` Waste
- **METRC MT**
  - `0` other (Allowable value, not sent to METRC)
  - `247` Contaminant Testing
  - `240` Waste
  - `246` Drying
  - `245` Entry Error
  - `244` Scale Variance
  - `243` Spoilage
  - `242` State Mandated Destruction
  - `241` Theft
- **METRC NJ**
  - `0` other (Allowable value, not sent to METRC)
  - `190` Consumed During Testing
  - `184` Waste
  - `189` Drying
  - `308` Enforcement Investigation
  - `188` Entry Error
  - `187` Scale Variance
  - `186` Spoilage
  - `185` Theft
- **METRC NV**
  - `0` other (Allowable value, not sent to METRC)
  - `2` Package Destruction/Waste
  - `3` Test Sample Consumed in Testing
  - `4` Entry Error
  - `5` Nevada Dept.of Agriculture
  - `6` Scale Variance
  - `251` Test Sample Consumed in Testing
  - `255` Package Destruction/Waste
  - `292` API Adjustment Error
  - `259` Drying
  - `258` Entry Error
  - `257` Nevada Dept.of Agriculture
  - `256` Over Pulled
  - `254` Plants Unpacked
  - `253` Scale Variance
  - `252` Spoilage
  - `250` Theft
  - `249` Transfer Error
  - `291` Unaccounted Product Variance
  - `248` Under Pulled
- **METRC NY**
  - `0` other (Allowable value, not sent to METRC)
  - `305` Consumed During Testing
  - `298` Waste
  - `304` Damage During Transfer
  - `303` Drying
  - `302` Entry Error
  - `301` Scale Variance
  - `300` Spoilage
  - `299` Theft
- **METRC OH**
  - `0` other (Allowable value, not sent to METRC)
  - `2` Laboratory Testing
  - `3` Destruction - Waste/Other
  - `5` Laboratory Testing
  - `6` Plant Material - Moisture Gain/Loss
  - `194` Laboratory Testing
  - `195` Destruction - Waste/Other
  - `199` Data Entry Error
  - `198` Destruction - Expired
  - `197` Destruction - Failed Testing
  - `196` Destruction - Recall
  - `297` Inventory Reconciliation
  - `296` Loss, Theft, or Diversion
  - `192` Plant Material - Moisture Gain/Loss
  - `191` Scale Variance
- **METRC OK**
  - `0` other (Allowable value, not sent to METRC)
  - `220` Sample Used During Testing
  - `224` Contaminant Testing
  - `225` API Related Error
  - `223` Damage/Spoilage
  - `222` Drying
  - `221` Mandatory State Destruction
  - `219` Scale Variance
  - `218` Test Sample Destruction
  - `217` Theft
  - `216` Typing/Entry Error
- **METRC OR**
  - `0` Moisture Loss/Gain
  - `2` Sample Destroyed (Lab Use Only)
  - `3` Waste
  - `231` Sample Destroyed (Lab Use Only)
  - `226` Waste
  - `239` API Adjustment Error
  - `238` API Conversion Error
  - `237` During License-to-License Transfer
  - `236` Entry Error
  - `234` Moisture Loss/Gain
  - `233` Package Material
  - `232` Plant Death
  - `230` Scale Variance
  - `229` Spoilage
  - `228` Theft
  - `227` Trade Sample
- **METRC RI**
  - `0` other (Allowable value, not sent to METRC)
  - `205` Consumed during Testing
  - `200` Waste
  - `204` Entry Error
  - `317` QA Sample to RIDOH
  - `203` Scale Variance
  - `202` Spoilage
  - `201` Theft
- **METRC SD**
  - `0` other (Allowable value, not sent to METRC)
  - `260` Waste
  - `262` Drying
  - `261` Entry Error
- **METRC Tribal Nations**
  - `0` other (Allowable value, not sent to METRC)
  - `312` Test Sample Consumed in Testing
  - `309` Waste
  - `316` Entry Error
  - `315` Plants Unpacked
  - `314` Scale Variance
  - `313` Spoilage
  - `311` Theft
  - `310` Transfer Error
- **METRC 29 Palms**
  - `0` other (Allowable value, not sent to METRC)
  - `265` Waste (Unusable Product)
  - `273` Damage
  - `272` Enforcement Testing
  - `271` Incorrect Quantity
  - `270` Mandated Destruction
  - `269` Over Pulled
  - `268` TCC-Authorized Adjustment
  - `267` Theft
  - `266` Under Pulled
  - `264` Weight Change Due to Moisture

## Path parameters

- `sample_id` (string, required)

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

- `unit` (string, required) — Unit for `amount_changed`: `g` or `ml` or `units`.
  Example: `g`
- `amount_changed` (number, required) — Signed amount to add to the weight on hand; negative values reduce it. `0` records nothing and returns the current weight.
  Example: `-2.5`
- `change_reason` (integer, required) — Integer reason ID for the change; see the description above.
  Example: `3`

## Responses

### 200 Success

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

- `weight_on_hand` (object)
  - `weight` (integer) — The current weight on hand
  - `unit` (string) — Units the weight on hand is measured in(One of "g" or "units")

Example:

```json
{
  "success": true,
  "weight_on_hand": {
    "weight": 9.5,
    "unit": "g"
  }
}
```

### 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 POST 'https://api.confidentcannabis.com/v0/labs/sample/{sample_id}/weight_on_hand' \
  -H 'X-ConfidentLims-APIKey: YOUR_API_KEY' \
  -H 'X-ConfidentLims-Timestamp: UNIX_TIMESTAMP' \
  -H 'X-ConfidentLims-Signature: REQUEST_SIGNATURE' \
  --data-urlencode 'unit=g' \
  --data-urlencode 'amount_changed=-2.5' \
  --data-urlencode 'change_reason=3'
```

### 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}/weight_on_hand'

data = {
    "unit": "g",
    "amount_changed": "-2.5",
    "change_reason": "3",
}

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

response = requests.post(
    '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}/weight_on_hand";

const data = {
  "unit": "g",
  "amount_changed": "-2.5",
  "change_reason": "3",
};

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

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

---

HTML version: https://api.confidentcannabis.com/v0/docs/labs/adjust-weight-on-hand  
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
