Purchase

Upsert a purchase order

Upsert a single purchase order. To update an existing purchase order, pass in an existing purchase order ID in the id field. Updates are sparse: any field you omit is left unchanged, and sending an explicit null clears that field. The items and charges collections are optional on update — omit either to leave the existing line items or charges untouched. When you DO send items or charges, that array is the complete set for the order, so any existing entry whose id you do not include is deleted; send an empty charges array to clear all charges. Entries you do send are patched, not required in full: a charge or line item sent with an existing id is merged onto the stored row, so you can change one field and omit the rest. A line item WITHOUT an id is a new line and must declare its product via batch_id, package_id, or product_id. Charges are full-replace on update — see the charges field for how existing charges, presets, and deletions are handled; on create, charge presets whose auto-apply tags match the purchase's products are added automatically. The order's line items must be either all package-tracked or all not package-tracked — a mix of the two is rejected.

See the status field on the purchase response for what each value means. Allowed transitions: PENDING, PROCESSING, and DELIVERING may move freely between one another and forward to PARTIALLY_RECEIVED or COMPLETED. Once a purchase reaches PARTIALLY_RECEIVED or COMPLETED it has received inventory and can no longer move back to PENDING, PROCESSING, or DELIVERING (it may still move between PARTIALLY_RECEIVED and COMPLETED). PARTIALLY_RECEIVED is not allowed for purchases that contain package-tracked items.

For a PARTIALLY_RECEIVED purchase, set each line's received_quantity to the amount received so far. In a subsequent call you may decrease a line's received_quantity, or delete a line that has a positive received_quantity, as long as the previously-received quantity has not yet been consumed elsewhere in Distru (e.g. sold, transferred, or adjusted); otherwise the change is rejected.

To match the purchase with an incoming compliance transfer, pass a top-level metrc_transfer_id or biotrack_id. This is only valid with status = COMPLETED, and requires the purchase's location_id to be on the license that received the transfer; the referenced incoming transfer must exist or the request is rejected. On each line item, identify the package it maps to with metrc_package_id (Metrc) or biotrack_id (BioTrack) and give its compliance_quantity. Once matched, a purchase is locked at COMPLETED and its transfer association cannot be changed.

Required permission: purchases_permissions_create to create a new purchase order, purchases_permissions_edit (and access to the purchase under team restrictions) to update an existing purchase order.

post/public/v1/purchases

Request body

idstring

ID for this purchase order. Omit it to create a new purchase order — Distru assigns the ID. Provide an existing purchase order's ID to update it; an ID that doesn't exist returns a not-found error.

descriptionstring

A free-text description of the purchase order. Optional; send null to clear it.

status'COMPLETED' | 'DELIVERING' | 'PENDING' | 'PARTIALLY_RECEIVED' | 'PROCESSING'

Where this purchase order sits in its lifecycle, which also governs when inventory is received. See the endpoint description for the allowed transitions and the status field on the purchase response for what each value means. Defaults to PENDING on create; on update, omit to leave it unchanged.

metrc_transfer_idinteger

The ID of the incoming Metrc transfer to match this purchase with. When provided, status must be COMPLETED and each line item must identify its package via metrc_package_id and compliance_quantity. A purchase can match only one compliance transfer, so this cannot be sent together with biotrack_id. Once a purchase is matched, its status is locked at COMPLETED and the transfer association cannot be changed on a later update.

biotrack_idstring

The ID of the incoming BioTrack transfer to match this purchase with. When provided, status must be COMPLETED and each line item must identify its package via biotrack_id and compliance_quantity. A purchase can match only one compliance transfer, so this cannot be sent together with metrc_transfer_id. Once a purchase is matched, its status is locked at COMPLETED and the transfer association cannot be changed on a later update.

location_idstring

The ID of the location the purchased inventory is received into once the purchase reaches a received status (PARTIALLY_RECEIVED or COMPLETED). Also the default location_id for each line item that omits its own. Required on create; cannot be changed once it has been set, so on update omit it to leave it unchanged.

billing_location_idstring

The ID of the location used as the billing address for this purchase order. Required on create; on update, omit to leave it unchanged.

supplier_location_idstring

The ID of the supplier's location the purchased items ship from. Optional; omit to leave an existing value unchanged, or send null to clear it.

company_idstring

The ID of the supplier (vendor) this purchase order is bought from. Required on create; cannot be changed once it has been set, so on update omit it to leave it unchanged.

order_datetimestring

The datetime the purchase order was placed, as a full ISO8601 datetime in UTC (e.g. 2026-08-18T00:00:00Z). Also the field the list endpoint sorts by. Required on create; on update, omit to leave it unchanged.

due_datetimestring

The datetime by which the purchase order should be paid, as a full ISO8601 datetime in UTC (e.g. 2026-08-25T00:00:00Z). Required on create; on update, omit to leave it unchanged.

owner_idstring

The ID of the Distru user that owns this purchase order. Optional; send null to leave it unassigned.

custom_dataobject

A map of custom field IDs to their values. Use GET /public/v1/custom-fields?parent_object=purchase to retrieve available custom fields, their IDs, and their types. The value format depends on the field's type: a text field takes a string, a date field takes a full ISO8601 datetime, and a checkbox field takes an array of its selected options.

Response

A single purchase orders

Changes

No recorded changes to this endpoint across all 1 revision of this API.