Returns coordinate authorization, merchandise, and buyer value without treating a refund as proof that goods came back. A Return contains frozen order-line identity, policy evaluation, line-level quantities, handoff requirements, progress summaries, completion blockers, and links to its operational and financial effects.
Use an eligibility check to discover returnable fulfilled allocations, then create a requested Return or use the composite processing command for an in-store flow. The instance processing command applies the same facts to an existing Return. Use the child collections when you need detailed receipt, inspection, disposition, or resolution history.
New to this surface? The Returns guide explains the model and points at the right integration; Your first return walks one item from a paid order to a settled refund.
The four statuses#
A Return carries four status fields because the things they describe genuinely come apart. Read the one that answers your question rather than inferring from a neighbour.
| Field | Question it answers | Values |
|---|---|---|
decision_status | Did we say yes? | pending, approved, partially_approved, declined |
merchandise_status | Did the goods come back? | not_required, awaiting_handoff, in_transit, partially_received, received, inspection_required, partially_inspected, inspection_review_required, disposition_required, resolved, exception |
resolution_status | Did the buyer get their value? | not_selected, pending, partially_fulfilled, requires_action, fulfilled, failed |
status | Is the whole thing finished? | requested, open, declined, canceled, completed |
pending appears in three of these and fulfilled in two, so a bare status value is ambiguous without its field name. merchandise_status is not_required for a returnless refund, where the buyer keeps the goods, and exception when merchandise arrived that Flint cannot attribute to a line.
A Return moves requested to open on decision and open to completed when the last obligation clears. completed is not terminal: /reopen returns it to open so late compensating facts can be recorded.
Completion blockers#
completion_blockers is the authoritative list of what is still owed. Each entry names the Return line it belongs to and, where one exists, the receipt, inspection, disposition, or resolution holding it up. An empty array means nothing is outstanding.
| Code | Cleared by |
|---|---|
decision_pending | Deciding the line |
handoff_pending | The buyer handing merchandise to a carrier |
receipt_pending | The warehouse recording arrival |
inspection_pending | An inspection observation |
inspection_review_required | An acceptance decision on an inspection line |
disposition_pending | A successful disposition |
resolution_not_selected | Choosing what the buyer gets |
resolution_pending | The resolution's effects settling |
resolution_requires_action | Whatever the resolution is waiting on, usually a buyer payment |
resolution_failed | Retrying or replacing the failed resolution |
merchandise_exception | Verifying or dispositioning merchandise that arrived unidentified or in excess |
Under completion_mode: "automatic" Flint completes the Return when the final blocker clears. Under manual you call /complete, and the call fails while any blocker remains.
Gate downstream work on return.completed or on an empty blocker list, never on a refund succeeding. A resolution can reach a terminal state while merchandise work is still open.
Line quantities#
A Return line carries twelve counters. Three of them answer questions you will actually ask; the rest are telemetry that explains how they got there.
| Question | Read |
|---|---|
| How much can I still approve? | requested_quantity minus approved_quantity, declined_quantity, and canceled_quantity |
| How much is still expected back? | return_required_quantity minus received_quantity |
| How much can I still put on a resolution? | available_resolution_quantity |
available_resolution_quantity is derived, and its subtlety is worth stating: proposed, pending, action-required, failed, and fulfilled resolutions all reserve capacity. A failed resolution does not release its quantity until it is canceled or corrected, which is what stops a retry and a replacement from both paying out.
return_required_quantity is the returnless-refund control. Set it to 0 while approving quantity and the buyer keeps the merchandise; the Return still settles the money and still records why.
The remaining counters (handed_off_quantity, inspected_quantity, accepted_quantity, rejected_quantity, dispositioned_quantity, resolved_quantity, review_required_quantity) track progress through the physical steps. Disposition capacity is received_quantity when no inspection is required, and accepted_quantity plus rejected_quantity when one is.
Writes#
Return PATCH routes preserve omitted fields. Send null to clear a nullable scalar that the route exposes, including external_reference_id, buyer_note, and requested_resolution_type.
Child mutations on /line-items return the parent Return rather than the mutated line, because a line change can move the Return's aggregate statuses and blockers. GET on the same path returns the line itself.
Writes that change meaning take expected_return_revision from the resource you last read. On a conflict, 409 RETURN_REVISION_CONFLICT carries the current revision in its error detail, so you can re-read and retry rather than searching for what changed.
Idempotency-Key is required on both processing commands and optional elsewhere. Because the create form mints an ID you have not seen, recover a lost response with GET /v1/returns?idempotency_key=... rather than creating a second Return.
Buyer portal sessions#
A Return read with a portal session is narrower than the same Return read with a merchant key. supported_actions is trimmed to at most ["cancel"], completion_blockers is filtered to the four a buyer can personally clear (handoff_pending, resolution_not_selected, resolution_requires_action, resolution_failed), and merchant-private fields are removed. The difference is deliberate, not a permissions error.
