Skip to main content

Releases

Releases represent scheduled material draws against a Hold-for-Release purchase order (an HFR order, also referred to as a buyout โ€” see OrderType). Each Release records when material is needed, where it should be delivered, which line items are being released and in what quantity, and the extended cost of that draw.

These queries expose the same release-level dates and dollar values shown in the Kojo Analytics Dashboard, so they can be pulled into Power BI or another reporting tool.

note

Cancelled releases are excluded by default from both queries. Pass includeCancelled: true to return them. If you are reconciling totals against the Analytics Dashboard, make sure both sides agree on whether cancelled releases are counted.

Schemaโ€‹

Releaseโ€‹

NameTypeDescriptionExample
idIDUnique Kojo internal identifier"clr8adymd000112nocbtsetzx"
orderIdIDID of the purchase order this release belongs to"clrrtqmy60007zay5y3kbb6x0"
purchaseOrderNumberString?PO number of the parent order, so bulk consumers can join without a second request"PO-2025-001"
releaseNumberStringHuman-readable release identifier. Not guaranteed unique โ€” use id to identify a release"REL-001"
needByDateDayDateTime?Day the released material is needed on site"2025-09-15T00:00:00.000Z"
needByWindowString?Delivery window within the need-by day"AM"
notesString?Release notes"Deliver to north gate"
additionalNotesString?Further notes on the release"Call site super on arrival"
cancelledAtDateTime?When the release was cancelled; null for active releases"2025-08-02T14:11:07.221Z"
cancelledReasonString?Reason recorded at cancellation"Schedule pushed"
totalCostFloatExtended cost of this release โ€” the sum of totalCost across its releaseItems. See How totalCost is derived12450.00
deliveryLocationLocation?Where the release is being delivered
releaseItemsReleaseItem[]The line items included in this release
createdAtDateTimeWhen the release was created"2025-08-01T09:14:22.031Z"
createdByIdID?ID of the user who created the release"clr6fkyru0002q3dwbwh2t6j8"
updatedAtDateTimeWhen the release was last updated"2025-08-01T09:20:44.507Z"

ReleaseItemโ€‹

NameTypeDescriptionExample
idIDUnique release item identifier"clxyz789"
releaseIdIDID of the release this item belongs to"clr8adymd000112nocbtsetzx"
lineItemIdIDID of the order line item being released"clxyzabc"
requisitionItemIdID?ID of the originating requisition item, when the release traces back to a requisition"clxyzdef"
quantityReleasedFloatQuantity of the line item released in this release10
backorderQuantityFloatQuantity on backorder for this release item; 0 when none2
totalCostFloatExtended cost of the released quantity. See How totalCost is derived12450.00
lineItemReleaseLineItemPricing detail for the released line item
createdAtDateTimeWhen the release item was created"2025-08-01T09:14:22.031Z"
updatedAtDateTimeWhen the release item was last updated"2025-08-01T09:20:44.507Z"

ReleaseLineItemโ€‹

NameTypeDescriptionExample
idIDID of the order line item"clxyzabc"
descriptionString?Line item description"Steel Beam 10ft"
unitPriceFloatUnit price of the line item, before any unit discount; 0 when unpriced1245.00
extPriceFloatExtended price for the released quantity. Equal to the release item's totalCost12450.00

ReleasesResponseโ€‹

Returned by the releases query.

NameTypeDescription
metaReleasesPaginationMetaPagination metadata
dataRelease[]The page of releases

ReleasesPaginationMetaโ€‹

NameTypeDescriptionExample
totalIntTotal releases matching the filters, before pagination342
limitIntEffective page size actually applied, after the 500 cap100
offsetIntNumber of releases skipped0

How totalCost is derivedโ€‹

totalCost is computed at request time from the parent order's line item pricing โ€” it is not a stored field. For each release item:

totalCost = round(quantityReleased ร— unitPrice ร— (1 โˆ’ unitDiscount รท 100) รท pricePerFactor, 2)
  • unitPrice and unitDiscount come from the order line item. An unpriced line item contributes 0.
  • pricePerFactor reflects the line item's unit of measure: 1000 for M, 100 for C, and 1 for everything else (including EA and blank). This matches how Kojo prices "per thousand" and "per hundred" units.

A release's totalCost is the sum of its release items' totalCost, and each lineItem.extPrice repeats the release item's totalCost for convenience.

Queriesโ€‹

orderReleasesโ€‹

Fetches every release on a single purchase order. Use this for the drill-down case, when you already have an order ID.

Parametersโ€‹

NameTypeDefaultDescriptionExample
orderIdID!โ€”The Kojo ID of the purchase order. Required"clrrtqmy60007zay5y3kbb6x0"
includeCancelledBoolean?falseInclude cancelled releases in the responsetrue

Results are ordered by createdAt descending. This query is not paginated and does not accept the standard pagination parameters โ€” it returns every release on the order.

Responseโ€‹

A list of Release objects.

Requesting an order that does not exist, has been deleted, or belongs to another organization returns an Order not found error. Kojo does not distinguish these cases, so a valid order ID from a different organization is reported as not found rather than as a permissions error.

Example Queryโ€‹

query {
orderReleases(orderId: "clrrtqmy60007zay5y3kbb6x0") {
id
releaseNumber
needByDateDay
needByWindow
notes
cancelledAt
cancelledReason
totalCost
deliveryLocation {
id
name
}
releaseItems {
id
quantityReleased
backorderQuantity
totalCost
lineItem {
id
description
unitPrice
extPrice
}
}
}
}

Example Responseโ€‹

{
"data": {
"orderReleases": [
{
"id": "clr8adymd000112nocbtsetzx",
"releaseNumber": "REL-001",
"needByDateDay": "2025-09-15T00:00:00.000Z",
"needByWindow": "AM",
"notes": "Deliver to north gate",
"cancelledAt": null,
"cancelledReason": null,
"totalCost": 12450.0,
"deliveryLocation": {
"id": "clxyz456",
"name": "Main Warehouse"
},
"releaseItems": [
{
"id": "clxyz789",
"quantityReleased": 10,
"backorderQuantity": 0,
"totalCost": 12450.0,
"lineItem": {
"id": "clxyzabc",
"description": "Steel Beam 10ft",
"unitPrice": 1245.0,
"extPrice": 12450.0
}
}
]
}
]
}
}

releasesโ€‹

Fetches releases across your whole organization, with date and order filters and pagination. This is the query to use for scheduled bulk pulls into a BI tool.

Parametersโ€‹

NameTypeDefaultDescriptionExample
orderIdID?โ€”Return only releases on this purchase order"clrrtqmy60007zay5y3kbb6x0"
needByDateFromDateTime?โ€”Return releases with needByDateDay on or after this instant (ISO 8601)"2025-09-01T00:00:00.000Z"
needByDateToDateTime?โ€”Return releases with needByDateDay on or before this instant (ISO 8601)"2025-09-30T00:00:00.000Z"
includeCancelledBoolean?falseInclude cancelled releases in the responsetrue
limitInt?100Maximum number of releases to return. Values above 500 are capped at 500250
offsetInt?0Number of releases to skip100

Results are ordered by createdAt descending.

note

This query does not accept filter or orderBy arguments โ€” the parameters above are the full set. Its pagination also differs from the standard defaults: limit defaults to 100 (not 500) and is capped at 500.

Notes on filter behavior:

  • Date filters are independent. Supplying only needByDateFrom leaves the upper bound open; supplying only needByDateTo leaves the lower bound open.
  • Releases with no need-by date are excluded when you filter by date. A release whose needByDateDay is null cannot satisfy a range bound, so it drops out of the result set as soon as either date filter is supplied. Omit both filters to include undated releases.
  • limit above the cap does not error. Requesting limit: 1000 returns at most 500 records and reports meta.limit: 500, so read your effective page size from meta.limit rather than assuming it echoes your request.
  • Releases on deleted orders are excluded.

Responseโ€‹

A ReleasesResponse.

An offset past the end of the result set returns an empty data array with an accurate meta.total, so you can page until offset + data.length >= meta.total.

Errors:

  • A negative limit or offset returns limit must be a non-negative integer or offset must be a non-negative integer.
  • An orderId that does not resolve to an order in your organization returns Order not found. An empty-string orderId is treated as a lookup for an order with a blank ID and also returns Order not found; omit the argument entirely to query all releases.

Example Queryโ€‹

query {
releases(
needByDateFrom: "2025-09-01T00:00:00.000Z"
needByDateTo: "2025-09-30T00:00:00.000Z"
limit: 100
offset: 0
) {
meta {
total
limit
offset
}
data {
id
orderId
purchaseOrderNumber
releaseNumber
needByDateDay
needByWindow
cancelledAt
totalCost
deliveryLocation {
id
name
}
releaseItems {
id
quantityReleased
backorderQuantity
totalCost
lineItem {
id
description
unitPrice
extPrice
}
}
}
}
}

Example Responseโ€‹

{
"data": {
"releases": {
"meta": {
"total": 342,
"limit": 100,
"offset": 0
},
"data": [
{
"id": "clr8adymd000112nocbtsetzx",
"orderId": "clrrtqmy60007zay5y3kbb6x0",
"purchaseOrderNumber": "PO-2025-001",
"releaseNumber": "REL-001",
"needByDateDay": "2025-09-15T00:00:00.000Z",
"needByWindow": "AM",
"cancelledAt": null,
"totalCost": 12450.0,
"deliveryLocation": {
"id": "clxyz456",
"name": "Main Warehouse"
},
"releaseItems": [
{
"id": "clxyz789",
"quantityReleased": 10,
"backorderQuantity": 0,
"totalCost": 12450.0,
"lineItem": {
"id": "clxyzabc",
"description": "Steel Beam 10ft",
"unitPrice": 1245.0,
"extPrice": 12450.0
}
}
]
}
]
}
}
}