{"name":"Rhode Island METRC API observations from a production integration","description":"Dated, sourced observations of how the Rhode Island METRC track-and-trace API behaves, made by SeedLink’s production integration and read-only probe scripts against Rhode Island production and sandbox facilities: response shapes, orderings, error messages, counts on a named day. Each observation names its environment and its source.","url":"https://www.seedlink.net/guides/metrc","observed":"2026-09-07","revised":"2026-09-20","temporalCoverage":"2026-04-24/2026-09-07","methodology":"https://www.seedlink.net/methodology","publisher":"SeedLink","guides":[{"slug":"package-tags-adult-use-vs-medical","url":"https://www.seedlink.net/guides/metrc/package-tags-adult-use-vs-medical","json":"https://www.seedlink.net/guides/metrc/package-tags-adult-use-vs-medical/data.json","title":"METRC package tags in Rhode Island: adult-use and medical share one list, and medical comes first","question":"How do I avoid burning medical package tags on an adult-use order in Rhode Island?","answer":"Classify every tag by its TagTypeName and TagInventoryTypeName fields and never by its position or label prefix: Rhode Island returns the medical tags first, and the tag number is printed on the physical sticker.","environment":"Rhode Island production and sandbox","observed":"2026-09-07","revised":"2026-09-20","facts":[{"id":"adult_use_tags_available","value":305,"observed":"2026-06-04","source":"GET /tags/v2/package/available at one Rhode Island production cultivator facility (Micro class), read-only probe"},{"id":"medical_tags_available","value":60,"observed":"2026-06-04","source":"GET /tags/v2/package/available at one Rhode Island production cultivator facility (Micro class), read-only probe"},{"id":"list_order","value":"Medical tags listed first, every adult-use tag after them","observed":"2026-06-04","source":"GET /tags/v2/package/available, same facility, counted by position"},{"id":"tag_type_names","value":"TagTypeName: Cannabis Package (adult-use) and Medical Package (medical)","observed":"2026-06-04","source":"GET /tags/v2/package/available, same facility"},{"id":"tag_inventory_type_names","value":"TagInventoryTypeName: CannabisPackage and MedicalPackage","observed":"2026-06-04","source":"GET /tags/v2/package/available, same facility"},{"id":"label_prefixes","value":"Label prefixes at that facility: medical 1A42A01, adult-use 1A42A03","observed":"2026-06-04","source":"GET /tags/v2/package/available, same facility; the prefix is license-specific"},{"id":"is_used_absent","value":"No IsUsed field on the production response; the endpoint returns unused tags only","observed":"2026-06-04","source":"GET /tags/v2/package/available, Rhode Island production"},{"id":"incident_packages_on_medical_tags","value":"2 packages created on medical tags in one overnight packaging run; the manifest step then failed","observed":"2026-06-04","source":"Rhode Island production, the first wholesale order SeedLink packaged; read-only probe of the outgoing transfer afterwards"},{"id":"rebuilt_manifest_packages","value":"3 adult-use packages on the manifest the cultivator rebuilt by hand the same morning","observed":"2026-06-04","source":"GET /transfers/v2/outgoing and its deliveries, Rhode Island production, read-only probe"},{"id":"archived_package_still_readable","value":"A package deleted in METRC Connect is archived, and GET /packages/v2/{label} still returns it with its quantity intact","observed":"2026-06-04","source":"Rhode Island production, the two archived packages from the incident"},{"id":"hemp_tags_in_sandbox","value":"1,000 Hemp Package tags listed beside 843 cannabis package tags","observed":"2026-09-07","source":"GET /tags/v2/package/available, Rhode Island sandbox, packaging pre-flight"},{"id":"collision_error","value":"HTTP 400 with the message \"The Package Tag is not available.\" when a tag read as available had been consumed by another creator first","observed":"2026-07-25","source":"POST /packages/v2/, Rhode Island production and sandbox, packaging runs"},{"id":"note_and_item_name_verbatim","value":"GET /packages/v2/{label} returns Note and Item.Name verbatim on Rhode Island production","observed":"2026-07-25","source":"Two packages read at one production facility"}],"citation":"SeedLink, \"METRC package tags in Rhode Island: adult-use and medical share one list, and medical comes first\", observed 2026-09-07, revised 2026-09-20, https://www.seedlink.net/guides/metrc/package-tags-adult-use-vs-medical"},{"slug":"rhode-island-api-traps","url":"https://www.seedlink.net/guides/metrc/rhode-island-api-traps","json":"https://www.seedlink.net/guides/metrc/rhode-island-api-traps/data.json","title":"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","question":"Why does METRC return 0 packages when I query the Rhode Island API?","answer":"Because lastModifiedStart and lastModifiedEnd are required on /packages/v2/active and /items/v2/active and Rhode Island production answers HTTP 200 with an empty list when they are missing; if the filters are present, check the pageSize cap of 20, the route timeout and the credential before believing the empty list.","environment":"Rhode Island production and sandbox","observed":"2026-08-20","revised":"2026-09-20","facts":[{"id":"sweep_endpoints","value":"A read-only sweep of 49 METRC endpoints at one production cultivator facility; SeedLink calls about 25 of the 268 documented paths","observed":"2026-07-25","source":"Rhode Island production, one cultivator facility, read-only probe script"},{"id":"plural_tags_path_404","value":"GET /tags/v2/packages/available (plural) answers HTTP 404; the real path is the singular /tags/v2/package/available","observed":"2026-07-25","source":"Rhode Island production, the same read-only sweep"},{"id":"package_history_404","value":"GET /packages/v2/{id}/history answers HTTP 404: no per-package audit trail endpoint exists","observed":"2026-07-25","source":"Rhode Island production, the same read-only sweep"},{"id":"sales_patients_401","value":"Every /sales/* and /patients/* path answers HTTP 401 for a cultivator credential","observed":"2026-07-25","source":"Rhode Island production, the same read-only sweep, one cultivator license"},{"id":"rejected_transfers_empty","value":"GET /transfers/v2/rejected answers HTTP 200 with 0 rows for one cultivator","observed":"2026-07-25","source":"Rhode Island production, the same read-only sweep"},{"id":"readonly_vendor_key","value":"With a vendor key issued as read-only, every GET answered HTTP 200 and every POST and PUT answered HTTP 401; two different write endpoints both answering 401 marked the key rather than the payload, and the sync log stayed green throughout","observed":"2026-06-04","source":"Rhode Island production, one cultivator facility, the integration’s own request log"},{"id":"sandbox_adjust_echo","value":"After PUT /packages/v2/adjust, GET /packages/v2/{label} reported the last adjustment amount as Quantity: an adjustment of -9 on a 9 g package read back as -9, and a later +4.5 read back as +4.5; repeated reads returned the same value","observed":"2026-07-23","source":"Rhode Island sandbox, one test facility"},{"id":"sandbox_finish_blocked","value":"PUT /packages/v2/finish validated against that echoed Quantity, so a package could not be finished as empty; negative package quantities are real on the sandbox","observed":"2026-07-23","source":"Rhode Island sandbox, one test facility"},{"id":"sandbox_retry_after","value":"A 23-second Retry-After after two full syncs and a packaging scan inside a few minutes","observed":"2026-07-01","source":"Rhode Island sandbox, July 2026; the record gives the month only, so the first day of the month stands in for the day"},{"id":"sandbox_sync_duration","value":"A full sandbox sync of 186 packages took about 36 to 38 seconds","observed":"2026-07-23","source":"Rhode Island sandbox, one test facility, timed by the sync route"},{"id":"sync_past_timeout","value":"A sync of 258 packages finished in about 105 seconds; the route that started it had returned at a 30-second timeout reporting 0 synced","observed":"2026-08-20","source":"Rhode Island sandbox, one facility, the sync route and its log"},{"id":"pagesize_cap","value":"HTTP 400 with the body \"pageSize must be a positive number between 1 and 20.\" for any pageSize above 20, on GET /transfers/v2/deliveries/{id}/packages; the cap applies to /packages/v2/* and /transfers/v2/* alike","observed":"2026-06-01","source":"Rhode Island production, a read-only probe during a transfer reconciliation in June 2026; the record gives the month only, so the first day of the month stands in for the day"},{"id":"wrong_facility_400","value":"HTTP 400 with the body \"Item N does not exist at the current Facility.\" from PUT /items/v2/ at a facility that does not own the item, beside HTTP 401 and HTTP 404 for the same condition","observed":"2026-07-09","source":"Rhode Island sandbox, the item-update walk across /facilities/v2/"}],"citation":"SeedLink, \"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\", observed 2026-08-20, revised 2026-09-20, https://www.seedlink.net/guides/metrc/rhode-island-api-traps"},{"slug":"transfer-template-to-manifest","url":"https://www.seedlink.net/guides/metrc/transfer-template-to-manifest","json":"https://www.seedlink.net/guides/metrc/transfer-template-to-manifest/data.json","title":"A METRC transfer template becomes a manifest only when a person dispatches it in METRC Connect: Rhode Island exposes no dispatch endpoint","question":"How does a METRC transfer template become a manifest?","answer":"The API creates a transfer template with a T-prefixed manifest number, a person dispatches it in the METRC Connect web interface, and METRC then creates a separate outgoing transfer with its own Id, a plain-numeric manifest number, and an OriginatingTemplateId that points back at the template.","environment":"Rhode Island production and sandbox","observed":"2026-09-03","revised":"2026-09-20","facts":[{"id":"template_create_response","value":"POST /transfers/v2/templates/outgoing returned 200 with {Ids: [N]}; the id in that response was unreliable and a follow-up GET /transfers/v2/templates/outgoing was needed to find the template","observed":"2026-04-24","source":"Rhode Island sandbox, cultivator license, template creation probe in the SeedLink transfers module"},{"id":"template_manifest_number_shape","value":"GET /transfers/v2/templates/outgoing lists templates, each with its own Id and a T-prefixed ManifestNumber such as T-0000000001","observed":"2026-04-24","source":"Rhode Island sandbox, read-only list of outgoing templates"},{"id":"outgoing_transfer_shape","value":"GET /transfers/v2/outgoing lists dispatched transfers, each with its own Id, a plain-numeric ManifestNumber such as 0000000817, and OriginatingTemplateId set to the Id of the template it was dispatched from","observed":"2026-04-24","source":"Rhode Island sandbox, read-only list of outgoing transfers after a dispatch in METRC Connect"},{"id":"dispatch_verbs_refused_april","value":"POST /transfers/v2/outgoing returned 405; POST /transfers/v2/templates/outgoing/{id}/start, /submit and /dispatch, and POST /transfers/v2/{id}/start, returned 404","observed":"2026-04-24","source":"Rhode Island sandbox, dispatch-verb probe"},{"id":"dispatch_verbs_refused_july","value":"POST /transfers/v2/outgoing returned 405 with the message does not support http method 'POST'; /transfers/v2/, /transfers/v2/external/outgoing and /transfers/v2/deliveries returned 404; /transfers/v2/templates/{id}/dispatch, /transfers/v2/templates/{id}/transfer and /transfers/v2/templates/outgoing/{id}/create returned 404","observed":"2026-07-26","source":"Rhode Island sandbox, second dispatch-verb probe"},{"id":"lab_license_external_incoming","value":"POST /transfers/v2/external/incoming from a lab license returned 401","observed":"2026-07-26","source":"Rhode Island sandbox, lab license credential"},{"id":"staged_template_clicks","value":"About 3 clicks in METRC Connect to dispatch a transfer when the template is staged through the API first","observed":"2026-07-26","source":"Rhode Island sandbox, METRC Connect web interface, counted by hand"},{"id":"independent_id_counters_pdf_collision","value":"GET /transfers/v2/manifest/1/pdf returned a pre-seeded demo manifest for an unrelated facility in another state, with no error; template Ids and outgoing-transfer Ids are independent counters","observed":"2026-04-24","source":"Rhode Island sandbox, manifest PDF probe with a template Id passed as the transfer Id"},{"id":"pdf_requires_license_number","value":"GET /transfers/v2/manifest/{id}/pdf without ?licenseNumber= returned 404 with the body No HTTP resource was found that matches the request URI /transfers/v2/manifest/N/pdf.","observed":"2026-04-24","source":"Rhode Island sandbox, manifest PDF probe"},{"id":"pdf_response_shape","value":"The manifest PDF response is JSON: FileContents holding the PDF as base64, ContentType application/octet-stream, FileDownloadName TransferManifestReport-N.pdf","observed":"2026-04-24","source":"Rhode Island sandbox, manifest PDF probe"},{"id":"template_package_fields","value":"A transfer template carries no quantity: per package it holds PackageLabel, WholesalePrice, GrossWeight and GrossUnitOfWeightName only, and the manifest ships whatever the package holds","observed":"2026-09-03","source":"Rhode Island sandbox and production, template payload and outgoing-template reads"},{"id":"dispatched_transfer_read_only","value":"Against a dispatched outgoing transfer, POST /transfers/v2/outgoing returned 405, PUT /transfers/v2/outgoing returned 405 and PUT /transfers/v2/outgoing/packages returned 404","observed":"2026-09-03","source":"Rhode Island sandbox and production, write probes against a dispatched transfer"},{"id":"adjust_on_transfer_refused","value":"Adjusting a package that is on a transfer through the API returned 400 with Package <label> cannot be Adjusted because it is part of an existing Transfer.; the identical call on a package with no transfer returned 200","observed":"2026-09-03","source":"Rhode Island sandbox and production, package adjustment probes"},{"id":"connect_adjust_moves_shipped_quantity","value":"A package on a dispatched, in-transit manifest was adjusted in METRC Connect (dispatched 2026-09-02, adjusted 2026-09-03) and the transfer’s ShippedQuantity followed on its own, 100 to 79","observed":"2026-09-03","source":"Rhode Island production, one cultivator’s own adjustment in METRC Connect, read back through the API the same day"},{"id":"outgoing_recipient_null","value":"Rows of GET /transfers/v2/outgoing carried a null RecipientFacilityName; the recipient is on GET /transfers/v2/{id}/deliveries and the shipped packages on GET /transfers/v2/deliveries/{deliveryId}/packages","observed":"2026-06-04","source":"Rhode Island production, read-only probe of one cultivator’s outgoing transfers"},{"id":"transferred_price_after_acceptance","value":"Wholesale price per shipped package appears on /packages/v2/transferred once the recipient accepts the manifest","observed":"2026-06-04","source":"Rhode Island production, read-only probe of transferred packages"},{"id":"package_set_edited_at_dispatch","value":"On one order in June 2026 the package set on the dispatched manifest differed from the template SeedLink had built; the cultivator edited the packages in METRC Connect at dispatch","observed":"2026-06-30","source":"Rhode Island production, one cultivator’s order to a dispensary; the field guide records the month only (June 2026), so the last day of that month stands in for the unrecorded day"},{"id":"returned_state","value":"ShipmentPackageState took the value Returned, which METRC’s documentation does not show; a package refused at the door read Shipped, then Rejected at receipt, then Returned once the shipper recorded the return leg, and the delivery’s RejectedPackagesReturned flipped true","observed":"2026-07-29","source":"Rhode Island production, read-only probe of one delivery with a refused package"},{"id":"returned_delivery_counts","value":"On that delivery ReceivedQuantity was null on the returned package, DeliveryPackageCount was 5 and DeliveryReceivedPackageCount was 4","observed":"2026-07-29","source":"Rhode Island production, the same delivery"},{"id":"returned_package_active_at_shipper","value":"A returned package landed back on the shipper’s side as its own active package","observed":"2026-07-29","source":"Rhode Island production, the shipper’s active package list after the return leg"}],"citation":"SeedLink, \"A METRC transfer template becomes a manifest only when a person dispatches it in METRC Connect: Rhode Island exposes no dispatch endpoint\", observed 2026-09-03, revised 2026-09-20, https://www.seedlink.net/guides/metrc/transfer-template-to-manifest"},{"slug":"adjust-is-absolute","url":"https://www.seedlink.net/guides/metrc/adjust-is-absolute","json":"https://www.seedlink.net/guides/metrc/adjust-is-absolute/data.json","title":"METRC package adjustments in Rhode Island: Quantity is the new total, not a delta, and the adjustments log reports the difference","question":"Is the Quantity in METRC’s package adjust call a delta or the new total?","answer":"The new absolute quantity of the package: on the Rhode Island sandbox on 2026-09-03, sending Quantity -1 to a package holding 40 Each left it at -1, not 39, and GET /packages/v2/adjustments logged the delta METRC computed, -41.","environment":"Rhode Island production and sandbox","observed":"2026-09-03","revised":"2026-09-20","facts":[{"id":"adjust_request_shape","value":"PUT /packages/v2/adjust takes an array of {Label, Quantity, UnitOfMeasure, AdjustmentDate, AdjustmentReason, ReasonNote}, one element per package","observed":"2026-09-03","source":"The request bodies of the adjust calls made on one Rhode Island sandbox facility that day"},{"id":"short_by_one_left_negative","value":"Quantity: -1 sent to a package holding 40 Each returned HTTP 200, and GET /packages/v2/{label} then read Quantity = -1, not 39","observed":"2026-09-03","source":"PUT /packages/v2/adjust followed by GET /packages/v2/{label}, one Rhode Island sandbox facility"},{"id":"adjustments_log_delta","value":"GET /packages/v2/adjustments logged AdjustmentQuantity = -41 for that call, the delta METRC computed from 40 to -1","observed":"2026-09-03","source":"GET /packages/v2/adjustments, the same Rhode Island sandbox facility, read after the call"},{"id":"restore_by_absolute","value":"Quantity: 40 sent to the same package restored it: GET read 40, where a delta reading would have given 39","observed":"2026-09-03","source":"PUT /packages/v2/adjust followed by GET /packages/v2/{label}, the same Rhode Island sandbox facility"},{"id":"negative_accepted_no_clamp","value":"A negative package quantity (-1) was accepted with HTTP 200 and no warning; METRC did not clamp at 0","observed":"2026-09-03","source":"The response body and status of the Quantity: -1 call, Rhode Island sandbox"},{"id":"adjust_reasons_all_require_note","value":"9 adjustment reasons, RequiresNote true on every one: Drying, Entry Error, OCR Investigation, Processing Loss, Quality Control Sample, Scale Variance, Spoilage, Theft, Waste","observed":"2026-09-03","source":"GET /packages/v2/adjust/reasons, Rhode Island sandbox"},{"id":"unit_mismatch_400","value":"HTTP 400 with the message \"The Unit of Measure must match the existing package (Grams), cannot be changed to Each.\" when a Grams package was adjusted with UnitOfMeasure Each","observed":"2026-09-03","source":"PUT /packages/v2/adjust, Rhode Island sandbox"},{"id":"on_transfer_400","value":"HTTP 400 with the message \"Package <label> cannot be Adjusted because it is part of an existing Transfer.\" for a package on a transfer template or a dispatched transfer","observed":"2026-09-03","source":"PUT /packages/v2/adjust, Rhode Island sandbox; the label in the message is elided here"},{"id":"no_transfer_200","value":"The identical adjust call on a package with no transfer returned HTTP 200","observed":"2026-09-03","source":"PUT /packages/v2/adjust, the same Rhode Island sandbox facility, same body, a package on no transfer"},{"id":"connect_adjust_moves_shipped_quantity","value":"A METRC Connect adjustment of -21 on a package of a dispatched, in-transit manifest moved the transfer’s ShippedQuantity from 100 to 79 before the delivery was received (dispatched 2026-09-02 at 01:24 UTC, adjusted 2026-09-03 at 05:21 UTC)","observed":"2026-09-03","source":"Read-only probe of one outgoing transfer and its package, Rhode Island production"},{"id":"template_carries_no_quantity","value":"A transfer template carries no quantity: PackageLabel, WholesalePrice, GrossWeight and GrossUnitOfWeightName only","observed":"2026-09-03","source":"The fields of the transfer template body SeedLink’s integration sends, per the incident record dated 2026-09-03"},{"id":"sandbox_get_reports_last_adjustment","value":"After an adjust, the sandbox single-package GET reported the last adjustment amount as Quantity rather than the running balance","observed":"2026-07-23","source":"GET /packages/v2/{label} after PUT /packages/v2/adjust, the Rhode Island sandbox"},{"id":"denomination_split","value":"Of the 1,355 packages 3 connected cultivators shipped in the 540 days to 2026-09-03, 472 (34.8%) were mass-denominated and 883 count-denominated; every product category shipped one way only","observed":"2026-09-03","source":"GET /packages/v2/transferred across three Rhode Island production cultivator facilities, read-only; docs/METRC.md, section Manifest and order reconciliation"}],"citation":"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"},{"slug":"lab-results-follow-the-package","url":"https://www.seedlink.net/guides/metrc/lab-results-follow-the-package","json":"https://www.seedlink.net/guides/metrc/lab-results-follow-the-package/data.json","title":"METRC lab results in Rhode Island follow a package that was created before the results came back","question":"Do METRC lab results follow a package that was created before the results came back?","answer":"Yes: when a lab records a result, METRC promotes every package that shares the sample’s item at that facility and writes the results down the lot’s lineage, so a package created before the result carries it the moment the lab posts it, and nothing in the cultivator’s integration receives anything.","environment":"Rhode Island production and sandbox","observed":"2026-07-26","revised":"2026-09-20","facts":[{"id":"item_level_propagation","value":"Results recorded on 24 samples resident at the sandbox lab facility moved all 160 cultivator-side packages sharing their item to TestPassed in one pass","observed":"2026-07-01","source":"Rhode Island sandbox, POST /labtests/v2/record from the lab facility credential. The record gives July 2026 without a day; the first of that month stands in here and is not an observation."},{"id":"propagation_key","value":"Promotion to TestPassed reaches every package sharing ItemFromFacilityLicenseNumber and Item.Id with the IsTestingSample package, across facilities","observed":"2026-07-01","source":"Rhode Island sandbox, the same lab-side run; month-only in the record (July 2026), first of the month standing in."},{"id":"results_after_packaging","value":"196 active packages carried a LabTestingStateDate later than their PackagedDate: 42, 92 and 62 at the three cultivators","observed":"2026-07-24","source":"Read-only probe of active packages at the three Rhode Island production cultivator facilities connected to SeedLink."},{"id":"children_from_unpassed_parent","value":"138 child packages at one cultivator were built from a parent that had not reached TestPassed","observed":"2026-07-24","source":"Read-only probe of package lineage at one Rhode Island production cultivator facility."},{"id":"children_on_different_item","value":"59 of those 138 children carried a different Item.Id than any parent and still received a result","observed":"2026-07-24","source":"The same lineage probe, Rhode Island production."},{"id":"infused_preroll_example","value":"An infused pre-roll child packaged 2026-07-16 off a parent still NotSubmitted received its own result on 2026-07-24","observed":"2026-07-24","source":"One package at one Rhode Island production cultivator facility, read in the same probe; label withheld."},{"id":"preroll_material_seven_days","value":"Pre-roll material packages at a second cultivator received results 7 days after packaging","observed":"2026-07-24","source":"Packages at a second Rhode Island production cultivator facility, read in the same probe; labels withheld."},{"id":"untested_dispatched","value":"27 packages shipped on outgoing transfers before their result landed: 4, 22 and 1 at the three cultivators, every one bound for a processor or a lab and none for a dispensary","observed":"2026-07-24","source":"Read-only probe of outgoing transfers against lab-state dates at the three facilities."},{"id":"dispensary_manifests_tested_first","value":"Every wholesale manifest to a dispensary at the three cultivators had its results in before dispatch","observed":"2026-07-24","source":"The same ship-time probe, Rhode Island production."},{"id":"dispensary_transfer_refused","value":"HTTP 400 from POST /transfers/v2/templates/outgoing for a NotSubmitted package: \"Package <label> is marked as NotSubmitted and cannot be transferred to <license> (<facility>). The destination Facility cannot receive Packages with the NotSubmitted Lab Testing State.\"","observed":"2026-07-25","source":"Rhode Island sandbox, a transfer template bound for the sandbox dispensary facility, with SeedLink’s own manifest gate forced open by hand."},{"id":"lineage_inheritance","value":"A package cut on 2026-07-25 off a harvest dated 2026-03-05 was born TestPassed carrying all 280 results the lab recorded on the source lot on 2026-04-25","observed":"2026-07-25","source":"Rhode Island sandbox, GET /labtests/v2/results?packageId= on the package minutes after POST /packages/v2/ created it."},{"id":"production_batch_breaks_inheritance","value":"POST /packages/v2/ with a new Concentrate item, IsProductionBatch true and a TestPassed flower ingredient produced LabTestingState NotSubmitted with 0 lab results; PUT /packages/v2/item back to the flower item did not recompute the state in either direction","observed":"2026-07-25","source":"Rhode Island sandbox. The record does not date this write separately from the lineage read of 2026-07-25 it sits beside."},{"id":"lab_records_at_own_facility_only","value":"POST /labtests/v2/record from the lab license against a cultivator-held package answered \"Package … does not exist in the current Facility\"; from a cultivator license it answered HTTP 401 regardless of body, since sandbox cultivator licenses lack the Manage Lab Tests permission","observed":"2026-07-26","source":"Rhode Island sandbox, lab facility and cultivator credentials. Recorded beside the 2026-07-26 transfer-verb probe, whose date is used here; the cultivator-side 401 was first seen in the July 2026 lab-side run."},{"id":"api_cannot_dispatch","value":"POST /transfers/v2/outgoing answered HTTP 405 (the endpoint exists and is read-only); /transfers/v2/, /external/outgoing and /deliveries answered 404; POST /transfers/v2/external/incoming from the lab answered 401; a template has no dispatch verb, with /templates/{id}/dispatch, /templates/{id}/transfer and /templates/outgoing/{id}/create all answering 404","observed":"2026-07-26","source":"Rhode Island sandbox, transfer-verb probe from the cultivator and lab credentials."},{"id":"testing_sample_requires_batch","value":"POST /packages/v2/testing requires RequiredLabTestBatches: [\"Raw Plant Material\"]; without it HTTP 400 \"At least one Lab Test Batch is required for Item\"; with it the source lot moved from NotSubmitted to SubmittedForTesting in place, with no step in the UI","observed":"2026-07-26","source":"Rhode Island sandbox end-to-end run."},{"id":"end_to_end_results_written","value":"The lab posted the batch’s 35 test types, each Passed true, with OverallPassed true; METRC wrote the same 35 results onto every package in the lineage (the source lot, both samples and a child cut before any result existed) and moved them all to TestingInProgress together","observed":"2026-07-26","source":"Rhode Island sandbox end-to-end run, with a person dispatching the one Lab Transfer in METRC Connect and the lab receiving it there."},{"id":"pass_within_min_max","value":"Under LabTestResultMode PassWithinMinMax, a flat half-of-maximum quantity answered HTTP 400 on test types that carry a minimum","observed":"2026-07-26","source":"Rhode Island sandbox end-to-end run, the lab’s record call."},{"id":"sandbox_terminal_state","value":"With the required batch shown as Passed, 35 of 35 performed, every result passed and released, and the sample adjusted to 0 and finished, the family still read TestingInProgress; PUT /labtests/v2/results/release answered 401; PUT /packages/v2/labtests/required answered \"cannot be changed because it has already been Transferred\"; there is no /labtests/v2/stages","observed":"2026-07-26","source":"Rhode Island sandbox, after the end-to-end run; the record gives no later date and says that waiting changed nothing."},{"id":"finish_verb","value":"Finishing a package is PUT /packages/v2/finish (POST answered 405), and only an empty package can be finished, so it is adjusted to 0 first with reason Consumed during Testing","observed":"2026-07-26","source":"Rhode Island sandbox, sample close-out after the end-to-end run; not dated separately in the record."},{"id":"location_required","value":"POST /packages/v2 and POST /harvests/v2/packages both answered HTTP 400 \"Location was not specified.\" without a Location; with /locations/v2/active empty, an existing package’s LocationName was accepted","observed":"2026-07-26","source":"Rhode Island sandbox packaging calls; not dated separately in the record, placed with the 2026-07-26 run they sit beside."},{"id":"sandbox_lab_recipe","value":"From the sandbox lab facility, a body of [{ Label, ResultDate: YYYY-MM-DD, Results: [about 35 Raw Plant Material types, each { LabTestTypeName, Quantity, Passed: true, Notes: \"\" }], OverallPassed: true }] answered 200 and the package read TestPassed immediately, with no release call; test types filtered to Raw Plant Material, excluding Retest, R&D, Sub-Contract and Final Form variants","observed":"2026-07-01","source":"Rhode Island sandbox, lab facility credential. Month-only in the record (July 2026); the first of the month stands in."}],"citation":"SeedLink, \"METRC lab results in Rhode Island follow a package that was created before the results came back\", observed 2026-07-26, revised 2026-09-20, https://www.seedlink.net/guides/metrc/lab-results-follow-the-package"},{"slug":"free-coas","url":"https://www.seedlink.net/guides/metrc/free-coas","json":"https://www.seedlink.net/guides/metrc/free-coas/data.json","title":"METRC serves the lab COA PDF for free in Rhode Island: one GET returns the raw PDF, and whether a document exists is a per-lab fact","question":"Can I get a COA PDF from the METRC API without paying a lab portal?","answer":"Yes: every row of GET /labtests/v2/results carries a LabTestResultDocumentFileId, and GET /labtests/v2/labtestdocument/{id}?licenseNumber= returns that lab document as raw PDF bytes, but the lab populates the id, and on 2026-07-25 one Rhode Island lab had attached a document to 12 of 12 tested packages while a second had attached one to 0 of 36.","environment":"Rhode Island production and sandbox","observed":"2026-07-25","revised":"2026-09-20","facts":[{"id":"document_id_field","value":"LabTestResultDocumentFileId is present on every row GET /labtests/v2/results returns, and it is populated by the lab, not by METRC","observed":"2026-07-25","source":"GET /labtests/v2/results across the three Rhode Island production cultivators connected to SeedLink, read-only probe"},{"id":"document_content_type","value":"GET /labtests/v2/labtestdocument/{id}?licenseNumber= returns raw application/pdf bytes, not the JSON-wrapped base64 that GET /transfers/v2/manifest/{id}/pdf returns","observed":"2026-07-25","source":"One live document fetched at one Rhode Island production cultivator facility, read-only probe"},{"id":"live_document_bytes","value":"327,580 bytes, beginning with the %PDF- signature","observed":"2026-07-25","source":"The same live document, one Rhode Island production cultivator facility; the byte count is the only identifier this page keeps"},{"id":"coverage_first_lab","value":"Packages tested by the first lab carried a document on 12 of 12 (100%)","observed":"2026-07-25","source":"GET /labtests/v2/results across the three connected Rhode Island production cultivators, rows grouped by the testing lab"},{"id":"coverage_second_lab","value":"Packages tested by the second lab carried a document on 0 of 36 (0%)","observed":"2026-07-25","source":"GET /labtests/v2/results across the three connected Rhode Island production cultivators, rows grouped by the testing lab"},{"id":"coverage_by_cultivator","value":"Per cultivator, tested packages carrying a document: 10 of 10, 0 of 16 and 2 of 22","observed":"2026-07-25","source":"The same rows grouped by cultivator instead of by lab"},{"id":"labs_in_the_sample","value":"Two labs between them had tested every package in the sample, across three cultivators","observed":"2026-07-25","source":"The same rows, distinct testing labs counted"},{"id":"shared_document_id","value":"Two packages of one item both pointed at the same document id","observed":"2026-07-25","source":"GET /labtests/v2/results for two sibling packages at one Rhode Island production cultivator facility"},{"id":"discovery_cost","value":"No additional request is needed to learn a document id: the results call already runs once per tested item for potency, so the only added request is the document fetch, made only when a package lacks a document","observed":"2026-07-25","source":"SeedLink’s own COA sync path as recorded in docs/METRC.md § COAs come from METRC for free, dated by the probe in that section"},{"id":"unit_thc_percent_null","value":"Item.UnitThcPercent is null on Rhode Island, so potency exists only in GET /labtests/v2/results, fetched per item and fanned out to sibling packages","observed":"2026-07-25","source":"SeedLink sync against Rhode Island production, recorded in docs/METRC.md § Retry-After, which carries no date of its own; dated here to the 2026-07-25 probe of the same results call, the nearest dated read in the same document"},{"id":"item_level_propagation","value":"Lab results propagate at item level: when a lab records results on an IsTestingSample package, every sibling package sharing ItemFromFacilityLicenseNumber plus Item.Id moves to TestPassed together, across facilities","observed":"2026-07-01","source":"Rhode Island sandbox lab pipeline, recorded in docs/METRC.md § Lab Testing, first bullet; month-only in the record (July 2026), first of the month standing in, not an observation"},{"id":"sandbox_propagation_count","value":"Testing 24 lab-resident samples flipped all 160 cultivator-side packages in one pass","observed":"2026-07-01","source":"Rhode Island sandbox, the same lab-side run; month-only in the record (July 2026), first of the month standing in, not an observation"},{"id":"deleted_document_returns_hourly","value":"A METRC-sourced document the cultivator deleted reappears on the next hourly sync unless the integration also remembers the METRC document id","observed":"2026-07-25","source":"SeedLink’s COA remove handler against its hourly sync, as recorded in docs/METRC.md § COAs come from METRC for free (the ownership table and the migration that added the id column)"}],"citation":"SeedLink, \"METRC serves the lab COA PDF for free in Rhode Island: one GET returns the raw PDF, and whether a document exists is a per-lab fact\", observed 2026-07-25, revised 2026-09-20, https://www.seedlink.net/guides/metrc/free-coas"},{"slug":"strainname-is-an-ingredient","url":"https://www.seedlink.net/guides/metrc/strainname-is-an-ingredient","json":"https://www.seedlink.net/guides/metrc/strainname-is-an-ingredient/data.json","title":"METRC’s StrainName is an ingredient, not the product name: Rhode Island requires a strain on infused items, so the two fields diverge by design","question":"Why does METRC show a different strain name than my product name?","answer":"Item.StrainName records the strain an item was made from and Item.Name records the product; Rhode Island marks four categories RequiresStrain, so an infused product sold under a flavour name carries a strain that is not its name, and METRC is right when the two differ.","environment":"Rhode Island production and sandbox","observed":"2026-09-07","revised":"2026-09-20","facts":[{"id":"infused_item_name_vs_strain","value":"An infused pre-roll item with a Name of the form \"<flavour> Infused Preroll 1.2g\" and a StrainName naming a different strain, the material it was infused from","observed":"2026-07-24","source":"GET /items/v2/{id} at one Rhode Island production cultivator facility (Micro class), read-only"},{"id":"items_sharing_strain_id","value":"All 5 of that cultivator’s items for the product carried the same StrainId","observed":"2026-07-24","source":"GET /items/v2/{id} for each item, same facility, read-only"},{"id":"active_strains_at_facility","value":63,"observed":"2026-07-24","source":"GET /strains/v2/active at the same facility; none of the strains matched the product’s name"},{"id":"product_category_of_item","value":"ProductCategoryName: Infused Pre-Rolls","observed":"2026-07-24","source":"GET /items/v2/{id}, same facility"},{"id":"cultivator_report","value":"The cultivator reported that the integration was showing the wrong product name; METRC was right and the display was wrong","observed":"2026-07-24","source":"Rhode Island production, the same cultivator, reported the day the item was read"},{"id":"requires_strain_categories","value":"RequiresStrain: true on 4 categories: Infused Pre-Rolls, Infused Bud/Flower, Pre-Packaged Bud, Raw Pre-rolls","observed":"2026-07-24","source":"GET /items/v2/categories, Rhode Island production"},{"id":"ri_item_category_count","value":21,"observed":"2026-07-28","source":"GET /items/v2/categories at one Rhode Island production cultivator facility, the full table read live"},{"id":"ri_categories_surfaced","value":"Categories Rhode Island surfaces include Bud/Flower, Shake/Trim, Shake/Trim (by strain), Pre-Packaged Bud, Concentrate, Raw Pre-rolls and Seeds","observed":"2026-07-28","source":"SeedLink METRC field guide, section Categories. The list is undated there; it carries the date of the live category read recorded in the same section"},{"id":"display_rule","value":"The strain wins when the item name is the strain plus packaging noise; otherwise the item name wins with size and pack tokens trimmed; a branded name of the form <brand>-Preroll-1.2g-<product>-Rec is unwrapped to its product segment","observed":"2026-07-28","source":"The rule SeedLink adopted, in the one function that chooses the display name; SeedLink METRC field guide, StrainName section"},{"id":"live_regression_sync","value":"A real sync of 216 packages on the Rhode Island sandbox asserts both directions, with no METRC writes","observed":"2026-07-28","source":"A live regression test in the SeedLink repository, run against the Rhode Island sandbox"},{"id":"active_package_shape","value":"GET /packages/v2/active returns Item inline on each package, with .Name, .StrainName and .ProductCategoryName, and no top-level ItemId","observed":"2026-07-28","source":"SeedLink METRC field guide, section Sync. The shape is undated there; it carries the date of the 216-package sandbox sync that exercised it"},{"id":"item_name_arrives_by_package_sync","value":"The item name is overwritten on every sync and arrives only through the package sync, which reads /packages/v2/active; a package METRC no longer reports active never receives it, and a manifest attached to a new order supplies it from the delivery payload’s ProductName","observed":"2026-07-28","source":"SeedLink METRC field guide, StrainName section, describing the sync as shipped with the rule of that date"},{"id":"transferred_package_shape","value":"GET /packages/v2/transferred is a flat schema with ProductName and ItemStrainName at the top level and no nested Item; it returns the item name for shipped packages","observed":"2026-09-07","source":"SeedLink METRC field guide, section Transferred-package pricing. The shape is undated there; the section’s most specific date is the September 7 private audit of the endpoint’s dates (2026), used here as the observation date"},{"id":"multipack_is_distinct_item","value":"A multi-pack is a distinct METRC item from its single: same category and strain, still Each, UnitWeight equal to the pack count times the per-unit grams, and a name of the form \"<single> - N pack\"; a 3-pack of a 1.2 g single is a 3.6 g item","observed":"2026-07-28","source":"One Rhode Island production cultivator facility, per the SeedLink METRC field guide’s Tier A section. That section does not date the check; it carries the date of the naming rule it informs, the nearest dated observation among this page’s sources"}],"citation":"SeedLink, \"METRC’s StrainName is an ingredient, not the product name: Rhode Island requires a strain on infused items, so the two fields diverge by design\", observed 2026-09-07, revised 2026-09-20, https://www.seedlink.net/guides/metrc/strainname-is-an-ingredient"},{"slug":"unit-weight-requires-unit-weight","url":"https://www.seedlink.net/guides/metrc/unit-weight-requires-unit-weight","json":"https://www.seedlink.net/guides/metrc/unit-weight-requires-unit-weight/data.json","title":"METRC item UnitWeight in Rhode Island: it persists only when the category has RequiresUnitWeight true, and the PUT returns 200 either way","question":"Why does METRC accept my item UnitWeight and then drop it?","answer":"Because `PUT /items/v2/` answers HTTP 200 whether or not the item’s category carries `RequiresUnitWeight: true`, and only a category with that flag keeps the value: read the flag from `GET /items/v2/categories`, and store a per-unit weight on your own side for every other category.","environment":"Rhode Island production and sandbox","observed":"2026-08-23","revised":"2026-09-20","facts":[{"id":"requires_unit_weight_flag","value":"RequiresUnitWeight is a per-category boolean on every row of GET /items/v2/categories, and it alone decides whether an item UnitWeight is kept","observed":"2026-07-09","source":"GET /items/v2/categories read beside a PUT and POST matrix, Rhode Island sandbox, one cultivator facility"},{"id":"matrix_scope","value":"7 categories live-tested: 3 with RequiresUnitWeight true and 4 with it false","observed":"2026-07-09","source":"PUT /items/v2/ and POST /items/v2 with UnitWeight, each followed by a read-back, Rhode Island sandbox, one cultivator facility"},{"id":"flag_true_put_persists","value":"On Shake/Trim, Infused Pre-Rolls and Pre-Packaged Bud, the 3 tested categories with RequiresUnitWeight true, a UnitWeight sent on PUT /items/v2/ persisted on read-back","observed":"2026-07-09","source":"PUT /items/v2/ followed by GET, Rhode Island sandbox, one cultivator facility"},{"id":"flag_true_post_400","value":"On a RequiresUnitWeight true category, POST /items/v2 without UnitWeight returned HTTP 400","observed":"2026-07-09","source":"POST /items/v2, Rhode Island sandbox, one cultivator facility"},{"id":"flag_false_put_drops","value":"On the four RequiresUnitWeight false categories Bud/Flower, Kief, Concentrate and Concentrate (each), PUT /items/v2/ and POST /items/v2 returned HTTP 200 and UnitWeight was silently dropped","observed":"2026-07-09","source":"PUT /items/v2/ and POST /items/v2 followed by GET, Rhode Island sandbox, one cultivator facility"},{"id":"put_200_body","value":"The PUT /items/v2/ response was HTTP 200 with the body {\"Ids\":[N],\"Warnings\":null}, with no warning when UnitWeight was dropped","observed":"2026-07-09","source":"PUT /items/v2/, Rhode Island sandbox, one cultivator facility"},{"id":"put_is_live","value":"A Name change persisted on the same PUT /items/v2/ call that dropped UnitWeight","observed":"2026-07-09","source":"PUT /items/v2/ followed by GET on an item in a RequiresUnitWeight false category, Rhode Island sandbox"},{"id":"wrong_facility_refusals","value":"A facility that does not own an item answers PUT /items/v2/ with HTTP 401, HTTP 404, or HTTP 400 with the body \"Item N does not exist at the current Facility.\"; the call requires licenseNumber and only the owning facility accepts it","observed":"2026-07-09","source":"PUT /items/v2/ during a facility walk, Rhode Island sandbox; the 400 shape was live-observed on this date, the 401 and 404 shapes were already handled and are undated in the field guide"},{"id":"production_unit_weight_category","value":"The only weight-based production packages carrying a unit weight belonged to Terpenes/Non Psychoactive Derivatives, the one concentrate category with RequiresUnitWeight true, and the weight was set at item creation","observed":"2026-07-31","source":"Read-only read of active packages at Rhode Island production cultivator facilities. The sources date this to July 2026 only, so the last day of that month stands as the ISO day"},{"id":"ri_item_categories","value":21,"observed":"2026-07-28","source":"GET /items/v2/categories at one Rhode Island production cultivator facility, read live; the whole table is pinned by a mapper test in the SeedLink repository"},{"id":"preflight_writes_nothing","value":"Since 2026-08-23 the SeedLink packaging pre-flight writes nothing to METRC. Measured before the change on a replica of one production catalog, its UnitWeight write logged \"updated\" and then \"did not persist\" on every run","observed":"2026-08-23","source":"SeedLink packaging pre-flight (check_uom) code change; the replica measurement is recorded with the change and carries no separate date in the field guide"},{"id":"cascade_verified","value":"A 7 g quarter of a strain that had only 3.5 g items created a \"<strain> - 7g\" item as Each, Pre-Packaged Bud, UnitWeight 7 Grams, and a re-run reused it rather than minting a second","observed":"2026-07-31","source":"SeedLink item-creation cascade, live-verified on the Rhode Island sandbox at one cultivator facility. The sources date this to July 2026 only, so the last day of that month stands as the ISO day"},{"id":"kilogram_mismatch","value":"A Kilograms-for-Grams mismatch on UnitWeightUnitOfMeasure multiplied a unit weight by 1,000 in one live packaging test","observed":"2026-06-30","source":"Live packaging test, June 2026; the sources record the month only, and the guard it produced, so the last day of that month stands as the ISO day"}],"citation":"SeedLink, \"METRC item UnitWeight in Rhode Island: it persists only when the category has RequiresUnitWeight true, and the PUT returns 200 either way\", observed 2026-08-23, revised 2026-09-20, https://www.seedlink.net/guides/metrc/unit-weight-requires-unit-weight"},{"slug":"remediation-transfers","url":"https://www.seedlink.net/guides/metrc/remediation-transfers","json":"https://www.seedlink.net/guides/metrc/remediation-transfers/data.json","title":"METRC remediation transfers in Rhode Island: the outgoing delivery’s ShipmentTypeName is the only sign a package is out, and the incoming transfer is the proof it came back","question":"How do I tell that a METRC package is out for remediation, and when it comes back?","answer":"Read the outgoing transfer’s deliveries and test ShipmentTypeName for Remediated Transfer, because every package-level and transfer-level remediation flag reads false while the package is away; then watch GET /transfers/v2/incoming for the same label, and GET /packages/v2/inactive for the case where it came home and was consumed before any list showed it.","environment":"Rhode Island production","observed":"2026-07-25","revised":"2026-09-20","facts":[{"id":"round_trip","value":"Flower transferred out to a remediation partner and transferred back about a day later, usually under a new package tag; the round trip is routine at that facility","observed":"2026-07-16","source":"Rhode Island production, one cultivator facility, live round trip in July 2026; the record dates the month, and 2026-07-16 is its one dated observation (the same-tag return)"},{"id":"shipment_type_name_signal","value":"ShipmentTypeName of Remediated Transfer on the outgoing transfer’s deliveries is the only reliable signal that a package is out for remediation","observed":"2026-07-16","source":"GET /transfers/v2/outgoing, then GET /transfers/v2/{id}/deliveries, Rhode Island production, one cultivator facility, July 2026 (day as in round_trip)"},{"id":"package_flags_false","value":"ProductRequiresRemediation, ContainsRemediatedProduct and IsOnHold all read false on the package while it sat on the remediation transfer","observed":"2026-07-16","source":"Package reads at the same facility during the trip, July 2026 (day as in round_trip)"},{"id":"onhold_empty","value":"GET /packages/v2/onhold returned an empty list while the package was out","observed":"2026-07-16","source":"GET /packages/v2/onhold at the same facility during the trip, July 2026 (day as in round_trip)"},{"id":"transfer_flags_false","value":"ContainsRemediatedProductPackage and ContainsProductRequiresRemediation read false on the outgoing transfer","observed":"2026-07-16","source":"GET /transfers/v2/outgoing at the same facility during the trip, July 2026 (day as in round_trip)"},{"id":"transferred_lags","value":"A just-dispatched package is absent from GET /packages/v2/transferred until the recipient accepts the manifest; GET /transfers/v2/outgoing lists the transfer immediately","observed":"2026-07-16","source":"GET /packages/v2/transferred and GET /transfers/v2/outgoing at the same facility after a dispatch, July 2026 (day as in round_trip)"},{"id":"transfer_types_by_intent","value":"Wholesale sales ship as Unaffiliated Transfer or Affiliated Transfer, lab samples as Lab Transfer, remediation as Remediated Transfer","observed":"2026-07-16","source":"GET /transfers/v2/types at Rhode Island production cultivator licenses, restated by the July 2026 remediation record (day as in round_trip)"},{"id":"new_tag_return_fields","value":"The returned package surfaces in GET /packages/v2/active with ReceivedFromFacilityName naming the facility it was shipped to and ReceivedFromManifestNumber set","observed":"2026-07-16","source":"GET /packages/v2/active at the same facility after a return, July 2026 (day as in round_trip)"},{"id":"retag_at_home_lineage","value":"One package re-tagged at home after its return: the new package’s SourcePackageLabels named the tag that had left (…754 became …757)","observed":"2026-07-16","source":"GET /packages/v2/active at the same facility, July 2026 (day as in round_trip)"},{"id":"same_tag_return_consumed","value":"Came home under the same tag at 11:28 UTC on 2026-07-16, was ground in full into a different product in a different category by 11:40 UTC, and was finished at 0 g between 2 hourly syncs; it never reappeared in GET /packages/v2/active, no same-strain flower child ever existed, and the record waiting for it sat for 6 days","observed":"2026-07-16","source":"Hourly sync records and package reads at the same facility, Rhode Island production"},{"id":"single_package_get_semantics","value":"GET /packages/v2/{label} answers HTTP 401 for a transferred-out package; HTTP 200 with a finished or zero-quantity package proves it came back and was consumed; HTTP 200 with a live quantity proves only a past return","observed":"2026-07-16","source":"Direct verification pass written after the same-tag return, same facility, Rhode Island production, July 2026 (day as in round_trip)"},{"id":"incoming_pairing_first_cultivator","value":"43 of 43 packages shipped on an outgoing Remediated Transfer reappeared by label on a later incoming transfer","observed":"2026-07-25","source":"GET /transfers/v2/incoming paired with GET /transfers/v2/outgoing by label, one Rhode Island production cultivator, read-only sweep"},{"id":"incoming_pairing_second_cultivator","value":"An incoming manifest carried exactly the 3 labels its outgoing leg had shipped","observed":"2026-07-25","source":"The same pairing at a second Rhode Island production cultivator, read-only sweep"},{"id":"incoming_manifest_names_package","value":"The incoming manifest received on 2026-07-16 at 11:28:31 UTC named the same-tag package directly","observed":"2026-07-25","source":"GET /transfers/v2/incoming at the first cultivator, read-only sweep"},{"id":"inactive_shows_finished_package","value":"That package is in GET /packages/v2/inactive with quantity 0, IsFinished true and FinishedDate 2026-07-16","observed":"2026-07-25","source":"GET /packages/v2/inactive at the first cultivator, read-only sweep"},{"id":"inactive_is_finished_count","value":"153 of the facility’s 169 inactive packages carry IsFinished","observed":"2026-07-25","source":"GET /packages/v2/inactive at the first cultivator, read-only sweep"},{"id":"intransit_exists","value":"GET /packages/v2/intransit exists on Rhode Island production and is the authoritative signal that a package is out again on a second trip; SeedLink does not read it yet","observed":"2026-07-25","source":"Read-only sweep of both Rhode Island production cultivators"},{"id":"sweep_size","value":"49 endpoints read in one read-only sweep","observed":"2026-07-25","source":"Rhode Island production, two cultivator facilities"}],"citation":"SeedLink, \"METRC remediation transfers in Rhode Island: the outgoing delivery’s ShipmentTypeName is the only sign a package is out, and the incoming transfer is the proof it came back\", observed 2026-07-25, revised 2026-09-20, https://www.seedlink.net/guides/metrc/remediation-transfers"},{"slug":"combining-packages","url":"https://www.seedlink.net/guides/metrc/combining-packages","json":"https://www.seedlink.net/guides/metrc/combining-packages/data.json","title":"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","question":"How do I combine two METRC packages of the same item into one?","answer":"Send one POST /packages/v2/ whose Ingredients array names every source package with its full live quantity, on one adult-use tag and with a Location, then finish the emptied sources with PUT /packages/v2/finish, because METRC leaves them active at zero.","environment":"Rhode Island production and sandbox","observed":"2026-07-28","revised":"2026-09-20","facts":[{"id":"endpoint_takes_ingredients_array","value":"POST /packages/v2/ is documented as creating packages from other packages and takes an Ingredients array; every package SeedLink had created through it before 2026-07-27 passed exactly 1 ingredient","observed":"2026-07-27","source":"METRC API reference for POST /packages/v2/, and the SeedLink packaging code path as it stood before the combine shipped"},{"id":"sandbox_combine_two_ingredients","value":"One POST /packages/v2/ carrying 2 ingredients, 3 Each and 3 Each of one pre-roll item, created a single new package holding 6 Each","observed":"2026-07-27","source":"Rhode Island sandbox, one sandbox cultivator facility; SeedLink’s combine run on a test order, and GET /packages/v2/{label} on the new package afterwards"},{"id":"sandbox_combine_lab_state","value":"The combined package read LabTestingState TestPassed, the state both sources carried","observed":"2026-07-27","source":"Rhode Island sandbox, the same combine run; the single-package GET on the new package"},{"id":"sandbox_combine_tag","value":"1 adult-use package tag consumed per combine group; the new sandbox package landed on an adult-use tag","observed":"2026-07-27","source":"Rhode Island sandbox, the same combine run; the tag was chosen from GET /tags/v2/package/available through the deny-list the package-tags guide describes"},{"id":"sandbox_sources_read_zero","value":"The next sync read both source packages back at 0","observed":"2026-07-27","source":"Rhode Island sandbox, the package sync that ran after the combine"},{"id":"zeroed_package_stays_active","value":"A package drawn to 0 by the combine stayed listed in GET /packages/v2/active until it was finished; METRC did not close it on its own","observed":"2026-07-27","source":"Rhode Island sandbox, GET /packages/v2/active after the combine and before any finish call"},{"id":"production_hand_combine","value":"Two packages of one pre-roll item, holding 664 and 265 units, went inactive at 20:33 UTC, and a new package of the same item appeared in the same minute holding 929","observed":"2026-07-27","source":"Rhode Island production, one cultivator facility; the cultivator combined by hand in METRC Connect and SeedLink’s package sync read the result; read-only"},{"id":"finish_verb_and_precondition","value":"PUT /packages/v2/finish takes a body of [{Label, ActualDate}]; a POST to the same path returns HTTP 405; a package can be finished only when it is empty","observed":"2026-07-26","source":"Rhode Island sandbox, the lab-testing recipe notes in docs/METRC.md; the note itself carries no date, and the dated probes beside it in the same recipe are 2026-07-25 and 2026-07-26, so the later of those is used here"},{"id":"unfinish_is_a_full_undo","value":"PUT /packages/v2/unfinish returned a finished package to GET /packages/v2/active; the finish had left the child package’s SourcePackageLabels untouched","observed":"2026-07-28","source":"Rhode Island sandbox, finish and unfinish exercised by hand on a drained source with a child package, with /packages/v2/active read before and after"},{"id":"active_read_needs_forward_padding","value":"A just-modified package fell outside a GET /packages/v2/active read whose lastModifiedEnd carried no forward padding, and looked as if it had never come back; with 1 day of forward padding it was listed again","observed":"2026-07-28","source":"Rhode Island sandbox, the same finish and unfinish check, read by hand"},{"id":"first_cultivator_finish_rate","value":"One cultivator finished 93% of its single-draw full drains the same day (p90 0 days) and 255 of 256 eventually","observed":"2026-07-28","source":"Rhode Island production, read-only probe of one cultivator facility’s package history"},{"id":"second_cultivator_finish_rate","value":"A second cultivator finished 81% of its single-draw full drains the same day and 109 of 109 eventually","observed":"2026-07-28","source":"Rhode Island production, read-only probe of a second cultivator facility’s package history"},{"id":"never_unfinished","value":"Across 533 inactive packages at the two facilities, no package had ever been un-finished","observed":"2026-07-28","source":"Rhode Island production, the same read-only probe, both facilities"},{"id":"sources_finished_by_cultivator","value":"Of the 4 source packages SeedLink’s own packaging had drawn from, 3 had been finished by the cultivator by hand, not by the integration","observed":"2026-07-28","source":"Rhode Island production, the same read-only probe, one facility"},{"id":"location_required","value":"POST /packages/v2/ and POST /harvests/v2/packages return HTTP 400 with the message \"Location was not specified.\" when the body carries no Location; when GET /locations/v2/active is empty, an existing package’s LocationName is accepted","observed":"2026-07-26","source":"Rhode Island sandbox, the lab-testing recipe notes in docs/METRC.md; the note itself carries no date, and the dated probes beside it in the same recipe are 2026-07-25 and 2026-07-26, so the later of those is used here"},{"id":"lineage_field_shape","value":"SourcePackageLabels on a package is a comma-separated list of the tags it was built from","observed":"2026-07-28","source":"Rhode Island sandbox, the child package read during the finish and unfinish check"}],"citation":"SeedLink, \"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\", observed 2026-07-28, revised 2026-09-20, https://www.seedlink.net/guides/metrc/combining-packages"}]}