Skip to main content

Outtake

An outtake ships vaulted units back out to an address you specify. Requesting one takes the units out of circulation immediately — they stop being sellable and cannot be outtaken again until the request completes or is cancelled.

Queries

previewOuttakeFees

Quote a selection before requesting — read-only, nothing locked or reserved. Takes the same selectors as the outtake mutation (line items, end user, or product + quantity) plus the savedAddressId it would ship to, and returns one preview per facility the selection spans, since fees are charged per facility group:

query {
previewOuttakeFees(input: { externalUserId: "user-8821", savedAddressId: "9f8e…" }) {
previews {
facilityId
itemCount
handling { totalCents isComplete }
shipping { pending carrier service totalCents parcelCount unquotableConfigurationIds }
dwell { storagePerUnitDayCents freeDays unitCount billableUnitDaysAsOf estimatedCents asOf }
totalCents
}
error { message code }
}
}

totalCents is handling + shipping + dwell as one figure, and it is null whenever any part is unresolved — never show a partial sum as the price. Shipping quotes asynchronously: on the first call shipping.pending is true and shipping.totalCents is null, so poll until it resolves. Omit savedAddressId to price handling and dwell only. dwell estimates storage beyond the free days — billableUnitDaysAsOf keeps accruing until the outtake is packed, so the estimate is stamped asOf.

getOuttakeRequests

query {
getOuttakeRequests(input: { includeProductInfo: true, pagination: { limit: 20 } }) {
facilityMovementRequests {
id
facilityId
facility { id name }
status
cancelBy
completeBy
isCancellable
items { lineItemId status releasedAt }
productSummaries { assetConfiguration { name primaryImageUrl } keyId unitCount lineItemCount }
}
pagination { totalCount hasNextPage }
error { message code }
}
}

Defaults to in-progress requests — REQUESTED, PROCESSING, IN_TRANSIT, PARTIALLY_COMPLETED. Pass statuses to reach finished ones:

getOuttakeRequests(input: { statuses: [COMPLETED, CANCELLED] })

includeProductInfo attaches per-product rollups (productSummaries) — the full catalog row plus unit and line-item counts per product, so a list screen doesn't need a follow-up read per request. Reads also carry the facility the request is at, the shipTo address as captured at request time, and the money: outtakeQuote is what you agreed to at request time, chargedTotalCents is what packing actually assessed (null until then — show the quote until it lands).

getOuttakeRequest

One request in full, including the shipping side:

query {
getOuttakeRequest(input: { facilityMovementRequestId: "9f8e…", includeProductInfo: true }) {
facilityMovementRequest { id status cancelBy completeBy items { lineItemId status releasedAt } }
transfers { id status }
shipmentGroups { id }
error { message code }
}
}

shipmentGroups is where tracking lives — shipping labels on them carry tracking codes, carrier, and status once the facility purchases labels.

Lifecycle

You don't drive the status — it follows the shipment.

StatusMeans
REQUESTEDCreated. Units are gated and can't be sold
PROCESSINGThe facility is working the request — picking, packing, purchasing labels
IN_TRANSITLabels are scanning
COMPLETEDEvery label delivered. Units have left the vault
PARTIALLY_COMPLETEDSome items released, some still pending
CANCELLEDCancelled before the window closed. Units back in the vault

On completion the units stop being vaulted: their placements move to UNVAULTED and they no longer appear in listFacilityItems as held stock. You still own them — they're just no longer with us, so they can't back a sale on the exchange until they're intaken again.

Mutations

requestFacilityLineItemOuttake

Ships vaulted units back out. Three ways to select what ships — provide exactly one:

  • lineItemIds — explicit units
  • externalUserId — everything held for one of your end users
  • assetConfigurationId + quantity (optionally narrowed by keyId) — the server picks that many vaulted units of the product, oldest first

Units ship to one of your saved addresses. Create one first with createSavedAddress, or look up an existing id with getSavedAddresses. See Address Management.

mutation {
requestFacilityLineItemOuttake(input: {
lineItemIds: ["a1b2…", "c3d4…"]
externalRef: "your-ref-0001"
savedAddressId: "9f8e…"
notes: "Leave at side door"
}) {
facilityMovementRequests {
id
facilityId
status
cancelBy
completeBy
items { lineItemId status }
}
transfers { id status }
error { message code }
}
}

To ship everything held for one of your end users, swap the selector:

requestFacilityLineItemOuttake(input: {
externalUserId: "user-8821"
externalRef: "your-ref-0002"
savedAddressId: "9f8e…"
})

Or ship a quantity of one product without naming units — the server picks the oldest vaulted units first:

requestFacilityLineItemOuttake(input: {
assetConfigurationId: "315b…"
keyId: "29ac…"
quantity: 10
externalRef: "your-ref-0003"
savedAddressId: "9f8e…"
})
FieldNotes
lineItemIdsUp to 500, no duplicates. Exclusive with the other selectors
externalUserIdShips every VAULTED unit held for that user
assetConfigurationId / keyId / quantityQuantity selector — that many vaulted units of the product, oldest first. Short supply returns INSUFFICIENT_VAULTED_QUANTITY with the available count
externalRefYour idempotency key. Required
savedAddressIdWhere it ships. Required, and must be an address on your account
notesHandling instructions for the facility. Optional
allowPalletizationConsent to palletized/repacked fulfilment and its pricing — higher handling fee, freight billed at actuals. The facility decides the actual mode at packing; without consent the request is always priced as parcels. Defaults to false
preferredCarrierPreferred carrier (UPS, FEDEX, USPS). Preference only — no label is bought at request time; it seeds the default when labels are purchased and is overridable then
preferredSpeedPreferred shipping speed. Preference only
preferredInsuranceWhether you want the shipment insured. Preference only

The address is copied onto the request when it's created. Editing that saved address afterwards does not redirect a shipment already in flight.

Units spanning facilities

If the selected units sit at more than one facility, you get one request and one transfer per facility — they ship separately. facilityMovementRequests is a list for this reason.

Retries

externalRef is an idempotency key. Retrying with the same value returns the original request rather than creating a second one, so a timeout is always safe to repeat.

Over the limit

An end-user selection with more than 500 vaulted units returns TOO_MANY_LINE_ITEMS with the real count. It does not ship the first 500 — narrow the selection with lineItemIds and send it in batches.

cancelOuttakeRequest

mutation {
cancelOuttakeRequest(input: { facilityMovementRequestId: "9f8e…" }) {
facilityMovementRequest { id status }
transfers { id status }
error { message code }
}
}

Cancelling returns the units to the sellable pool and clears the gates set when the request was made.

cancelBy is a hard cutoff — past it, cancellation fails with CANCEL_WINDOW_CLOSED whatever the status. A null cancelBy means no deadline was set, not a deadline of now. isCancellable reflects the current moment and goes stale once cancelBy passes.

Cancelling an already-cancelled request succeeds rather than erroring, so retries are safe.

Errors

CodeCause
VALIDATION_ERRORZero or multiple selectors given, or externalRef missing
NOT_FOUNDNo vaulted units for that end user, unknown request, or an address that isn't yours
TOO_MANY_LINE_ITEMSMore than 500 units selected
DUPLICATE_LINE_ITEM_IDSThe same line item appears twice
INSUFFICIENT_VAULTED_QUANTITYQuantity selector asked for more units than are vaulted — the payload carries the available count
OUTTAKE_DISABLEDA unit is gated — usually an outtake already in flight
CANCEL_WINDOW_CLOSEDcancelBy has passed