SeedLink
CustomersSign inRequest access

Guides/METRC field guides for Rhode Island

METRC package adjustments in Rhode Island: Quantity is the new total, not a delta, and the adjustments log reports the difference

PUT /packages/v2/adjust sets a package’s quantity to the number in the request; it does not add that number to what the package held. On 2026-09-03, on the Rhode Island sandbox, sending Quantity: -1 to a package holding 40 Each returned HTTP 200 and left the package at -1, not 39, and GET /packages/v2/adjustments logged an AdjustmentQuantity of -41, the delta METRC computed from 40 to the target. Sending Quantity: 40 put the package back to 40, where a delta reading would have given 39. METRC’s own API reference shows an example body with "Quantity": -2.0, which reads unmistakably as subtract two, and that is the trap.

Observed
September 3, 2026
Revised
September 20, 2026
Environment
Rhode Island production and sandbox

What this page is

This page records what SeedLink observed about the package adjustment call on the Rhode Island METRC API, dated, with the call that produced each observation. The delta-versus-absolute proof, the accepted negative quantity, the unit mismatch and the on-transfer refusal were all made on one Rhode Island sandbox facility on 2026-09-03; the manifest that followed a hand adjustment was read on Rhode Island production the same day. It is not METRC documentation and it is not regulatory guidance.

It is also not a description of what SeedLink writes. SeedLink writes no adjustments today; the writes on this page were made on a sandbox package to settle a question that the documentation’s own example answers the wrong way, and the page says so where the sandbox and production have been seen to differ. Other states run their own METRC instances and can differ on every point below.

How every number on this site is observed, dated and bounded is on the methodology page, which also lists what SeedLink does not publish.

What the adjust call takes

The endpoint is PUT /packages/v2/adjust, and the body is an array: one element per package, each with six fields. Five of them are what they look like. The sixth, Quantity, is not.

The adjust request body, one element per package, as sent on the Rhode Island sandbox on 2026-09-03
FieldWhat it carriesWhat was observed
LabelThe tag of the package being adjustedOne package per element; the body is an array
QuantityThe new absolute quantity of the package, not a change to itSending -1 to a package holding 40 Each left it at -1; sending 40 put it back to 40
UnitOfMeasureThe package’s existing unitEach on a Grams package: HTTP 400, the unit cannot be changed
AdjustmentDateThe date of the adjustmentCarried on every call; nothing further observed
AdjustmentReasonOne of the reasons GET /packages/v2/adjust/reasons listsNine reasons in Rhode Island, and every one requires a note
ReasonNoteThe note the reason requiresRequired on all nine reasons; a human statement about physical reality

METRC’s API reference shows an example body for this call with "Quantity": -2.0. Read cold, that is "subtract two", and an integration written against the example sends the shortfall as the quantity. The proof below is what happens to a body written that way.

Sent, read back, logged: the proof

On 2026-09-03 SeedLink made the two writes below on one Rhode Island sandbox facility, against a package holding 40 Each, and read the package and the adjustments log after each. The request takes the target total and the adjustments log reports the delta, and those are two different numbers.

One package holding 40 Each, two adjust calls, and what each read-only endpoint reported afterwards (Rhode Island sandbox, 2026-09-03)
StepSent in the body`GET /packages/v2/{label}` read`GET /packages/v2/adjustments` loggedA delta reading would have given
Before any callNo call yetQuantity = 40No call yet40
The "short by one" the documentation impliesQuantity: -1Quantity = -1AdjustmentQuantity = -4139
RestoreQuantity: 40Quantity = 40Not read39

The decisive number is the -41. A delta request of -1 would have logged -1. METRC logged the difference between the package’s prior 40 and the -1 it was told to hold, which means it treated -1 as the destination. The restore says the same thing from the other side: a delta of 40 on a package at -1 gives 39, and the package read 40.

Both calls returned HTTP 200. Nothing in either response said the package had gone negative, and nothing in either distinguished "set to" from "changed by".

No clamp at zero

METRC accepted a negative package quantity with HTTP 200 and no warning: a package holding 40 Each was left holding -1 and the API raised nothing.

On the sandbox that is a curiosity. Against a production license it is a false inventory statement filed under the user’s own METRC account. So a write path has to refuse a negative result itself, before the call: compute the target from a live read, compare it to zero, and stop. METRC provides no backstop, and the call that files a false statement looks identical to the call that files a true one.

All nine reasons require a note

GET /packages/v2/adjust/reasons returns the reasons an adjustment may carry. On the Rhode Island sandbox on 2026-09-03 it listed 9, and RequiresNote was true on every one of them. There is no note-free adjustment in Rhode Island.

Adjustment reasons returned by GET /packages/v2/adjust/reasons, Rhode Island sandbox, 2026-09-03
Reason`RequiresNote`
Dryingtrue
Entry Errortrue
OCR Investigationtrue
Processing Losstrue
Quality Control Sampletrue
Scale Variancetrue
Spoilagetrue
Thefttrue
Wastetrue

The reason and the note are a human judgement about physical reality, which is the other reason an integration should not fabricate them. On one Rhode Island production correction the cultivator’s own reason was Entry Error, with a note giving the real count: a person who counted, saying what they counted.

The unit must match the package, and a third of packages are in grams

UnitOfMeasure is not a conversion. Adjusting a Grams package with Each on 2026-09-03 returned HTTP 400 with the message The Unit of Measure must match the existing package (Grams), cannot be changed to Each. The field has to repeat the unit the package already has, which means the package has to be read live before it is adjusted.

This is not a rare shape: of the 1,355 packages the three connected cultivators shipped in the 540 days to 2026-09-03, 472 (34.8%) were mass-denominated, and every product category shipped one way only.

Shipped denomination by product category across 1,355 packages, three Rhode Island cultivators, the 540 days to 2026-09-03 (GET /packages/v2/transferred)
Product categoriesShipped inPackagesPackages the other way
Bud/Flower, Shake/Trim, Concentrate, Wet Whole Plant, Infused Bud/FlowerGrams472None by count
Edible, Tinctures, Vape Cart, Pre-Packaged Bud, pre-rollsCount883None by mass

The category says which unit to look for; the live read confirms it. The 400 comes from the same endpoint, with the same status, as the refusal in the next section.

A package on a transfer is locked to the API, not to a person

PUT /packages/v2/adjust on a package that is part of a transfer template or a dispatched transfer returned HTTP 400 with the message Package <label> cannot be Adjusted because it is part of an existing Transfer. The identical call on a package with no transfer returned HTTP 200 (both on 2026-09-03, Rhode Island sandbox). The lock is the transfer, not permissions: same credentials, same body, different package.

That window is where a short count is actually found: at the loading dock, when a template or a dispatched transfer already exists. The case the API refuses is the common one, not the edge.

METRC Connect can still adjust such a package, and the manifest follows. On Rhode Island production a cultivator adjusted a package on a dispatched, in-transit manifest (dispatched 2026-09-02 at 01:24 UTC, adjusted 2026-09-03 at 05:21 UTC, by -21) and the transfer’s ShippedQuantity moved from 100 to 79 on its own; the delivery had not yet been received. There is no API equivalent, and what a person did in the web UI is not evidence of what the API allows.

It also explains why a manifest is never edited. A transfer template carries no quantity: PackageLabel, WholesalePrice, GrossWeight and GrossUnitOfWeightName only. The package is adjusted and the manifest ships what the package holds.

What PUT /packages/v2/adjust answered on the Rhode Island sandbox on 2026-09-03, and what to do about each
The callThe packageMETRC answeredWhat to do
UnitOfMeasure: EachA Grams package, no transferHTTP 400: The Unit of Measure must match the existing package (Grams), cannot be changed to Each.Read the package first and send the unit it reports
A valid bodyOn a transfer template or a dispatched transferHTTP 400: Package <label> cannot be Adjusted because it is part of an existing Transfer.Do not retry. The correction is made by a person in METRC Connect, and the manifest follows the package
The identical bodyThe same shape of package, no transferHTTP 200The adjustment applied; the earlier refusal was the transfer, not the credentials
Quantity: -1Holding 40 Each, no transferHTTP 200, no warning; the package then read -1Refuse a negative target before the call; METRC does not

Both 400s come from the same endpoint with the same status. Classify on METRC’s message text, never on the status code: one means "send the right unit", the other means "stop, a person has to do this".

What SeedLink does with a short count

SeedLink writes no adjustments today. The path that works for a real short count runs the other way round: the cultivator fixes the count in METRC Connect first, which is the one door that is open while the package sits on a manifest; the integration then reads the package live, sees that it already holds the target, and corrects only its own records.

Two things fall out of the proof for anyone who does write the call. The target is computed from a live read of the package, never from a remembered balance, because the request replaces the balance rather than moving it. And a target below zero is refused before the request is built, because METRC accepts it.

Check it yourself, and the sandbox caveat

Two read-only calls show the two numbers side by side on any package that has been adjusted: the package’s running balance, and the delta METRC computed for the adjustment.

GET /packages/v2/{label}?licenseNumber=<your license>
  read Quantity: the running balance

GET /packages/v2/adjustments?licenseNumber=<your license>
  find the row for that label; read AdjustmentQuantity: the delta METRC computed

after a hand adjustment from an old count to a new count:
  Quantity           = the new count
  AdjustmentQuantity = the new count minus the old count

The proof itself needs a write, so it belongs on the sandbox and never on a production license. SeedLink’s proof was: send Quantity: -1, read both endpoints, then send the original count to restore the package. If the package reads the number you sent and the log reads the difference, the call is absolute.

One sandbox caveat. On 2026-07-23 the single-package GET after an adjust reported the last adjustment amount as Quantity rather than the running balance on the Rhode Island sandbox. The 2026-09-03 reads were consistent, and the adjustments log is what settles the question either way, so anyone verifying this should prefer production reads or read the adjustments log alongside the package.

Questions

Is Quantity in PUT /packages/v2/adjust a delta or the new total?
The new total. On the Rhode Island sandbox on 2026-09-03 a package holding 40 Each was sent Quantity: -1 and then held -1, not 39; the adjustments log recorded -41, the delta METRC computed. Sending 40 restored it to 40.
Why does METRC’s API reference show "Quantity": -2.0?
It is the example body in the reference for this call, and it reads as "subtract two". The observed behaviour is that the package is set to the number sent. We do not know why the example is written that way.
What happens if the new total is negative?
METRC accepts it. A package went to -1 with HTTP 200 and no warning on 2026-09-03. Against a production license that is a false inventory statement under your own account, so refuse a negative target before the call is made.
Which adjustment reasons need a note?
All of them. GET /packages/v2/adjust/reasons listed 9 reasons on 2026-09-03 with RequiresNote true on every one: Drying, Entry Error, OCR Investigation, Processing Loss, Quality Control Sample, Scale Variance, Spoilage, Theft and Waste.
Can I adjust a package in a different unit of measure?
No. A Grams package adjusted with Each returned HTTP 400 and the message The Unit of Measure must match the existing package (Grams), cannot be changed to Each. Read the package’s unit live and send that.
Can I adjust a package that is already on a manifest?
Not through the API. A package on a template or a dispatched transfer returned HTTP 400 with Package <label> cannot be Adjusted because it is part of an existing Transfer. A person can adjust it in METRC Connect, and on production the transfer’s ShippedQuantity followed, from 100 to 79, while the delivery was still in transit.
Do I fix the manifest quantity instead?
There is nothing on the manifest to fix. A transfer template carries no quantity, only PackageLabel, WholesalePrice, GrossWeight and GrossUnitOfWeightName. The package is adjusted and the manifest ships what the package holds.

Sources and how to cite this page

  • PUT /packages/v2/adjust, GET /packages/v2/{label} and GET /packages/v2/adjustments on one Rhode Island sandbox facility, 2026-09-03: the delta-versus-absolute proof (Quantity -1 then 40 on a package holding 40 Each), the accepted negative, the unit-mismatch 400, and the on-transfer 400 beside its no-transfer 200.
  • GET /packages/v2/adjust/reasons, Rhode Island sandbox, 2026-09-03: nine reasons, RequiresNote true on each.
  • Read-only probe of one dispatched outgoing transfer and its package on Rhode Island production, 2026-09-03: ShippedQuantity 100 to 79 after a METRC Connect adjustment of -21.
  • Single-package GET after an adjust on a different Rhode Island sandbox facility, 2026-07-23.
  • SeedLink METRC field guide (docs/METRC.md), section Manifest and order reconciliation: the denomination split across 1,355 packages shipped in the 540 days to 2026-09-03.

SeedLink, "METRC package adjustments in Rhode Island: Quantity is the new total, not a delta, and the adjustments log reports the difference", observed 2026-09-03, revised 2026-09-20, https://www.seedlink.net/guides/metrc/adjust-is-absolute

Every figure above carries the date it was observed and the environment it was observed in. A count belongs to one facility on one day; the field names, orderings and error messages are the durable part.

Machine-readable copy of this page, with the same facts, dates and sources: /guides/metrc/adjust-is-absolute/data.json

Related

  • A METRC transfer template becomes a manifest only when a person dispatches it in METRC Connect: Rhode Island exposes no dispatch endpoint
  • The Rhode Island METRC API returns an empty HTTP 200 when the required date filters are missing, and several other traps produce the same empty answer
  • Combining two METRC packages of one item in Rhode Island is one POST with two ingredients, and the drained sources stay active until you finish them
  • METRC item UnitWeight in Rhode Island: it persists only when the category has RequiresUnitWeight true, and the PUT returns 200 either way
  • All metrc field guides for rhode island
  • Methodology: what SeedLink publishes and what it does not
SeedLink
GuidesMethodologyContactPrivacyTermsFor Rhode Island buyers
© 2026 SeedLink