Blog/Metrc Receive: How One-Paste Manifest State Pull S...

Metrc Receive: How One-Paste Manifest State Pull Should Actually Work

A Metrc-native receive flow is one form: paste a manifest number, see every package and its lab tests, capture per-package Accept / Accept + Adjust / Reject decisions, and POST to Metrc before the local commit lands. This guide walks the wire-level conventions for Metrc v2 (envelope shape, licenseNumber as query param, lab tests by packageId), strict acknowledgement, symmetric Shipped + Adjustment + Net received UX, and how it removes the POS-vs-Metrc-vs-spreadsheet drift that breaks weekly reconciliation.
By LineNow Team·Published ·13 min read

If you run a dispensary in a Metrc state, your receive flow is half logistics and half regulatory wire. The truck pulls up, the driver hands you a printed manifest, and what follows is supposed to be: confirm every package against the manifest, decide Accept / Accept-with-adjustment / Reject for each one, post that decision to Metrc, and only put the stock on your shelf in a way your POS can see it. In practice, most operators do it in three systems — Metrc, the POS, and a spreadsheet — and the cracks between them are where every audit finding hides.

This guide is for the regulated retailer who wants the Metrc receive to be one form: paste a manifest number, see every package and its lab tests, capture variance and reject decisions, and let the software post the per-package acknowledgement to Metrc before anything commits locally. That is what a Metrc-native receive flow should look like in 2026 — and it is what LineNow does.

If you are tired of paying for two seats in Metrc, two seats in the POS, and one of your team is permanently the “Metrc person” to keep them in sync, this is for you.

The shape of the Metrc receive problem

Metrc’s job in your state’s seed-to-sale stack is to be the system of record for every package that exists, every transfer between licenses, and every lab test associated with each package. Your job at the receiving dock is to confirm what physically arrived against what the shipper declared on the manifest, and to push your decisions back into that system of record.

Three structural facts:

1. Metrc is the source of truth for packages, not your POS. When you receive a transfer, you are not creating a package — you are accepting (or rejecting) a package the shipper already created on their license. The package tag, shipped quantity, item type, lab tests, and source-supplier license already exist in Metrc. The POS does not know that.

2. The receive decision is per-package, not per-shipment. A manifest can carry 30 packages from one supplier. Twenty-eight are fine. One is short by 12 units. One arrived with a broken seal. Metrc expects three different decisions on those three buckets. The POS receive screen, by default, is one quantity field per item — which is the wrong shape.

3. The Metrc Adjust and Reject are not retroactive corrections — they are first-class outcomes. If you accept a package and then realize 12 units are missing, the right action is not to silently shrink in the POS. It is a Metrc Adjust against that package with a reason, posted within the receive transaction. Same for damaged-during-transfer packages — that is a Reject, not a fix-in-the-POS.

The receive software has to model all three. Most don’t. They treat the Metrc step as a parallel filing job after the fact, which is how variances drift between Metrc and your POS until the next reconciliation finds them.

What a Metrc-native receive should do, end-to-end

1. Onboarding: state-scoped user key, environment-aware vendor key

Connecting to Metrc is two keys, not one:

  • The User Key is scoped to your operator account in your state. You generate it inside Metrc.
  • The Vendor Key is scoped to the software vendor (us) in that state, and it is different between sandbox and production environments.

A receive surface that gets this wrong asks you for the vendor key. The correct shape: the software handles the vendor key per state and per environment; you only paste your user key and pick your state. We also persist your license number on the connection at connect time, so every State Pull from then on uses the right credential — no more “which license is this for?” popup on every manifest.

Sandbox vs production matters more than it looks. Smoke-testing against Metrc’s SBX (Oregon, Michigan, Maryland) is the right way to verify the wire-level integration before you let it touch a real receive. Vendor keys are environment-distinct; the software has to respect that split.

2. State Pull on the manifest, not data entry

The right starting point in the receive dialog is not “add line items.” It is a single field: the manifest number from the driver’s paperwork.

One paste should fetch:

  • Every package on the manifest, with package tag (label) and Metrc package ID
  • The shipped quantity, unit of measure, and item name from Metrc
  • The wholesale price and item category as registered with the state
  • The source supplier’s license number
  • The lab test references attached to each package

That data lands as a single verified compliance document of type transfer_manifest. The structured fields are queryable from then on — “show me every package received under Manifest M-99812” is one click, not a folder dig.

Lot rows in the Receive form auto-populate from the manifest’s packages. Each lot row carries the package tag, the Metrc package ID, the shipped quantity, and the lab-test references. The buyer’s only job is to confirm or reconcile.

3. Per-package Accept / Accept + Adjust / Reject

This is the part that breaks if you’re running Metrc and the POS as separate systems.

For each package row, the receive form needs three buttons of meaning, not just a quantity field:

  • Accept — physical count matches shipped quantity. The package becomes received stock on your license at the shipped quantity.
  • Accept + Adjust — physical count is short (or, rarely, over). The buyer enters the Net received quantity and a variance note. The variance posts as a Metrc Adjust against that package with the note attached as the Adjust reason.
  • Reject — package is unusable (damaged during transfer, seal broken, wrong item). The shipped quantity moves back to the shipper’s license; nothing lands on yours. The reject reason posts to Metrc.

The UI shape that makes this work is symmetric on every regulated lot — buyer-managed lots and state-pulled lots both render Shipped + Adjustment + Net received, with Adjustment disabled until Shipped is entered (and Shipped locked-read-only for state-pulled lots so you can’t accidentally edit what came from Metrc).

We deliberately do not surface Metrc’s “partial receive” checkbox. The IL_IB_0003 Transfers Best Practices bulletin is explicit that partial acceptance is not an approved method — Adjust and Reject are. Hiding the partial flag at the UI layer keeps the team on the approved path without making them remember the bulletin every time.

4. Strict Metrc acknowledgement before the local commit

This is the rule the rest of the workflow hangs off:

Every per-package decision (Accept / Accept + Adjust / Reject) is POSTed to Metrc before the local inventory write. If Metrc rejects the call, the entire local receive aborts.

The point is that your local inventory state can never get ahead of the state-of-record. If Metrc says no — invalid package, wrong receiver license, manifest already closed — the receive fails fast and nothing commits locally. The buyer sees the actual Metrc error message in the dialog and can resolve it before retrying.

The alternative — commit locally first, then file with Metrc, then reconcile drift weekly — is the failure mode the bulletin was written to prevent. Software should make that wrong path unavailable, not optional.

5. COA pull by package, attached to the lot

After the receive lands, the COA workflow shouldn’t require any new data entry. State Pull on a coa doc type queries Metrc’s lab-test endpoint by package ID (not by package label — a common wire-level confusion when integrating with v2) and saves the full lab result against the package label on file:

  • LabTestResultId
  • ResultReleased (timestamp)
  • RevokedDate (if ever revoked)
  • Pass / fail per analyte
  • The lab license that ran the test

That data is then on the lot for the life of the unit. When an inspector asks for “the heavy-metals panel for the units of lot 2026-04-22-A you sold last Tuesday,” the answer is one query against the inventory layer.

6. Audit trail in the compliance document, not on the inventory row

This is the architectural fork most receive systems get wrong: writing variance and Metrc outcomes onto the inventory_layers row.

The right place is the compliance document. Every Metrc outcome (per-package decision, post timestamp, Metrc response, reject reason, adjust note) appends to the manifest doc’s extractedFields. Non-Metrc regulated receipts with variance notes write a standalone other compliance document. The vendor license that was on file for the supplier at receipt time is snapshotted onto the order-item scope so each line carries a self-contained audit record.

Why this matters: when the inventory layer eventually drains (because the units sold), you don’t lose the compliance history. The receipt audit lives in the doc, not in the row that gets consumed.

What this looks like in LineNow

In LineNow, the Metrc-native receive flow is exactly this loop:

  1. Connect once. Compliance Reporting card on the buyer home page — paste your state-scoped User Key, pick your state, we persist the license number on the connection.
  2. Paste the manifest in the Compliance dialog. State Pull on transfer_manifest fetches every package, every shipped quantity, every lab test reference, and the source license.
  3. Receive with the manifest-driven lot rows. Lots pre-fill from the manifest. Shipped is locked on state-pulled lots; the buyer enters Net received and (if needed) a variance note in the Adjustment field. The form is symmetric on buyer-managed lots too — same Shipped + Adjustment + Net received fields.
  4. Reject a package with one click; Undo reject restores the prior quantity from the stashed prevQuantity (we don’t infer from qty == 0, which would lose the prior shipped quantity on undo).
  5. Confirm. Per-package decisions are POSTed to Metrc first. If any one fails, the entire receive aborts and surfaces the Metrc error. If all succeed, the local commit lands with full audit metadata on the compliance document.
  6. COA pulls are one click per package. Lab test results from Metrc’s /labtests/v2/results endpoint are saved against the package label, by package ID.

The non-Metrc regulated workflow is the same shape: items marked regulated still capture lot, expiration, supplier license, and per-line variance notes — they just write a standalone compliance document instead of pushing to a state system.

How this fits with the POS

LineNow does not replace your POS or your seed-to-sale system. Lightspeed (or Shopify, or Square) still handles checkout. Metrc still holds the package-of-record. LineNow lives in the middle:

  • Sales depleting through the POS update LineNow’s on-hand layers in real time.
  • Lots stay tied to their Metrc package tag, their COA, and the manifest they arrived on.
  • State filings still run through Metrc; we just post the receive ack and adjust calls from the same dialog that handles the rest of the receive.
  • The buying loop — what to reorder, from whom, at what price, with which documents required — lives in LineNow.

The migration cost is essentially zero. You don’t move your POS. You don’t move your seed-to-sale. You wire the Metrc connection on the buyer home page, mark regulated items as regulated, and the next manifest you receive uses the new flow.

A 60-second Metrc receive diagnostic

Three questions for your current receive flow:

  1. After a manifest arrives, do your team’s actions live in one form or three (POS + Metrc + spreadsheet)? Three = the cracks are where audit findings hide.
  2. When you Adjust a package, does the variance note flow into the Metrc Adjust reason — or does someone retype it inside Metrc? Retype = the Adjust reason will drift from the receive note.
  3. If Metrc rejects a per-package post, does your local inventory show the package as received or as not received? Received = your local state can get ahead of Metrc, which is exactly what the strict ack is supposed to prevent.

If any of those answers is wrong, the Metrc receive loop is open. The work you do in those gaps is the work the right software eliminates.

Related

Metrc receive softwareMetrc manifest state pullMetrc v2 API integrationMetrc strict acknowledgementMetrc COA pull by packagecannabis Metrc receivedispensary receive software MetrcMetrc transfer reconciliationMetrc package adjustment softwareMetrc sandbox vendor key
Want to see this in action?Book a Demo