Skip to content
Linra Omni Developer Docs

Respond to unfulfillable line notice

Respond to an unfulfillable-line notice.

Unfulfillable Notices

PATCH/api/v1/scent/unfulfillable-notices/{id}/respond

Within the 72-hour window, choose CancelWhole (cancel the whole outstanding line, full refund) or ShipAvailable (ship what’s available, cancel + refund only the shortfall). Returns the notice with the resulting refund figures now applied (status becomes Resolved). A cross-tenant or unknown id returns 404 (no existence leak). Rejects a notice that isn’t currently AwaitingPartnerResponse with 422 BUSINESS_NOTICE_NOT_AWAITING_RESPONSE (already resolved, or already expired past its own deadline). If your response races the 72-hour expiry sweep for the same notice, the loser gets 409 CONFLICT_NOTICE_ALREADY_RESOLVED — the money already landed under whichever side won; retry with a fresh read to see the outcome.

Path parameters

idstring (uuid)Required

The notice’s own GUID.

Body parameters

choicestring (enum)Required

CancelWhole: cancel the whole outstanding line (full refund). ShipAvailable: ship what’s available, cancel + refund only the shortfall.

Response

idstring (uuid)
scentOrderIdstring (uuid)

The order this notice belongs to — the same Scent order GUID you already hold from order creation/tracking and the webhook’s own data.orderId.

reasonstring (enum)

OutOfStock: a receiving-time shortage/damage discrepancy. Lost: the shipment carrying this line was declared lost — always resolves as a full cancel.

statusstring (enum)

AwaitingPartnerResponse: the 72-hour clock is running, waiting on you. Resolved: you responded within the window (see responseChoice). ExpiredCancelledWhole/ExpiredShipAvailable: you did not respond in time, and the system applied its own default (nothing shipped vs. the shipment had already departed).

responseChoicestring (enum)

The choice you made, when you responded within the window. Null if the notice expired instead (the effective outcome is then read off status) or is still open.

notifiedAtstring (date-time)
responseDeadlineAtstring (date-time)

The 72-hour deadline — respond before this instant or the system’s own default applies.

hasShipmentDepartedboolean

Whether the shipment carrying this line had already departed toward you at the moment the notice was raised — informs which default applies on expiry.

respondedAtstring (date-time)
line.scentOrderLineIdstring (uuid)
line.variantIdstring (uuid)
line.skustring
line.orderedQuantityinteger

The originally ordered quantity for this line.

line.availableQuantityinteger

Units still shippable (outstanding minus shortfall) — what ShipAvailable would keep.

line.shortfallQuantityinteger

Units that cannot be fulfilled — what both choices cancel + refund.

impact.cancelWholeobject

Mirrors the order’s pricing{} so a refund reconciles field-for-field against the charge. Populated ONLY once the refund has genuinely landed.

impact.shipAvailableobject

Mirrors the order’s pricing{} so a refund reconciles field-for-field against the charge. Populated ONLY once the refund has genuinely landed.

Other responses

401No bearer token (UNAUTHORIZED_MISSING_TOKEN), an invalid token (UNAUTHORIZED_INVALID_TOKEN) or an expired one (UNAUTHORIZED_TOKEN_EXPIRED — mint a new token). UPSTREAM_AUTH_FAILED is different: a dependent service refused the Gateway itself. That is a server-side fault — retry later and do NOT re-mint your token. See the Errors guide.
403The route is not available to your credential (FORBIDDEN).
404Unknown notice, or a cross-tenant id (no existence leak).
409Lost a race against the 72-hour expiry sweep resolving the same notice.
415The request body is not sent as application/json (UNSUPPORTED_MEDIA_TYPE).
422The notice is no longer awaiting a response.
429Too many requests — see the Rate limits guide. Retry after the Retry-After header (seconds).
502A dependent service returned an invalid response (BAD_GATEWAY). Retry with backoff.
503The service is temporarily unavailable (SERVICE_UNAVAILABLE). Retry with backoff.
504A dependent service did not respond in time (GATEWAY_TIMEOUT). Retry with backoff.
curl --request PATCH \
--url https://api-omni.linra.net/api/v1/scent/unfulfillable-notices/5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b/respond \
--header 'Authorization: Bearer $TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"choice": "CancelWhole"
}'

Response

{
"state": "SUCCESS",
"payload": {
"id": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b",
"scentOrderId": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b",
"reason": "OutOfStock",
"status": "AwaitingPartnerResponse",
"responseChoice": "CancelWhole",
"notifiedAt": "2026-08-22T09:14:03Z",
"responseDeadlineAt": "2026-08-22T09:14:03Z",
"hasShipmentDeparted": true,
"respondedAt": "2026-08-22T09:14:03Z",
"line": {
"scentOrderLineId": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b",
"variantId": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b",
"sku": "string",
"orderedQuantity": 0,
"availableQuantity": 0,
"shortfallQuantity": 0
},
"impact": {
"cancelWhole": {
"currency": "SAR",
"goods": {
"net": 0,
"vat": 0,
"total": 0
},
"commissionClawback": 0,
"shippingFeeRefund": 0,
"total": 0
},
"shipAvailable": {
"currency": "SAR",
"goods": {
"net": 0,
"vat": 0,
"total": 0
},
"commissionClawback": 0,
"shippingFeeRefund": 0,
"total": 0
}
}
},
"details": null
}