Skip to main content

Returns

All endpoints in this section take an external return portal's publicId as a path parameter. The portal must belong to the authenticated brand and its type must not be traede. Any error returned by these endpoints follows our standard error format.

Upsert a return

Endpoint: PUT /v10/external-return-portals/{publicId}/returns

Creates a new return, or updates an existing one in place. The return is identified by the (publicId, rma) pair: TRAEDE looks for an existing return on the same portal with the same rma. If none is found the call creates a new return in approved status; if one is found the call merges the incoming payload into it.

The endpoint is idempotent: replaying the same body against the same (publicId, rma) leaves the return in the same state. Because this single PUT serves both creation and updates, external portals do not need to track TRAEDE's numeric return.id to mutate a return - the external rma is enough.

caution

This endpoint rejects calls against a traede-type portal. Use an external portal (reversio, returnflows, float or custom).

Request parameters

ParameterData typeRequiredDefaultDescription
emailstringYes for a new return; optional thereafterThe customer email on the original order. Used to authenticate the return against the order. When provided on an existing return it must match the bound order's delivery email.
order_numberstringYes for a new return; optional thereafterThe order number of the original order. When provided on an existing return it must match the bound order's order_number.
returnobjectYesReturn data.

Return data

ParameterData typeRequiredDefaultDescription
rmastringYesThe RMA identifier from the external portal. Stored on the TRAEDE return and must contain at least one digit - the digits are used to derive TRAEDE's internal rma_number. Unique per portal.
notesstringFree-text notes on the return.
statusstringUpdate the return status. Valid transitions are constrained by the normal return state machine.
return_fee_incl_vatfloatThe return fee charged to the customer, including VAT. Deducted from the credit note when the return is received - see Fees.
exchange_fee_incl_vatfloatThe exchange fee charged to the customer, including VAT. Deducted from the credit note when the return is received - see Fees.
labelless_codestringA labelless / dropoff code the customer can present at the carrier. The external portal is responsible for booking the return label and reports the code here so TRAEDE can surface it to the customer.
track_tracestringThe tracking number for the return shipment booked by the external portal.
track_trace_linkstringA URL the customer can use to track the return shipment.
shopify_refund_gift_cardbooleanfalseIf true, the refund will be issued as a Shopify gift card.
shopify_refund_gift_card_bonus_typestringThe type of bonus applied to the gift card refund. Possible values: percentage, fixed.
shopify_refund_gift_card_bonus_valuefloatThe bonus value to apply, in the units implied by shopify_refund_gift_card_bonus_type.
shopify_refund_gift_card_free_shippingbooleanfalseIf true, the customer is refunded for shipping in addition to the line amounts.
lines.*YesAn array of at least one return line data. lines represents the desired full set of lines on the return; see Line merge behavior.

Fees

return_fee_incl_vat and exchange_fee_incl_vat are deducted from the credit: when the return is received, TRAEDE issues the credit note net of the fees (the fee amount is carried as a handling fee on the credit note). A returned item of 100.00 with a 25.00 return fee produces a credit note of 75.00, and the finalize call must account for 75.00.

caution

Do not also add fees reported here as line items on the (Shopify) order - the fee would then be counted twice: once as order revenue and once as a reduction of the credit note.

Return line data

Each line identifies a variant on the original order. Provide variant_id, sku or ean - whichever is most convenient.

ParameterData typeRequiredDefaultDescription
variant_idintYes, if no sku or ean is givenThe TRAEDE variant ID.
skustringYes, if no variant_id or ean is givenThe variant SKU. Must match exactly one variant on the brand.
eanstringYes, if no variant_id or sku is givenThe variant EAN. Must match exactly one variant on the brand.
quantityintYesThe quantity being returned. Must be greater than zero.
claim_typestringYesPossible values: return, claim.
claim_cause_idintYes, if portal requires claim causes and no claim_cause_code is givenID of a claim cause configured on the brand. Must belong to the authenticated brand.
claim_cause_codestringYes, if portal requires claim causes and no claim_cause_id is givenThe code of a claim cause configured on the brand. Looked up case-insensitively; if multiple claim causes share the same code the request is rejected.
unit_price_incl_vatfloatYesThe unit price including VAT that the customer paid on the original order. Used for refund math.
textstringA comment from the customer about this line, stored as the line's comments.
regulate_inventorybooleantrueIf false, inventory will not be adjusted when the return is received. Typically left at default.

Line merge behavior

lines always represents the full desired set of lines on the return. When the PUT targets an existing return, TRAEDE keeps existing line IDs where possible so that any data attached to a line (e.g. uploaded photos) is preserved across updates. Each incoming line is matched against the return's existing lines in this order:

  1. Exact natural key - same variant_id, claim_type, claim_cause_id, text and unit_price_incl_vat. This is the happy path: an unchanged line keeps the same id.
  2. Same variant - same variant_id, regardless of the other fields. An existing line for the variant is re-used and its fields updated in place.
  3. New line - if no existing line can be claimed, a new line is created.

After every input line has been processed, any existing lines that were not claimed by an input line are deleted from the return.

Each existing line is claimed by at most one input line. An input line picks the first unclaimed existing line that matches at the current cascade level.

Response

On success the endpoint returns HTTP 201 when a new return was created and HTTP 200 when an existing one was updated. The body is an object with two keys:

ParameterData typeDescription
returnobjectThe resulting return in TRAEDE. See Response return object.
createdbooleantrue if this PUT created a new return, false if it merged into an existing one.

Response return object

ParameterData typeDescription
idintTRAEDE's internal numeric return ID.
rmastringThe external RMA identifier you sent in.
rma_numberintThe numeric part of the RMA, derived from the digits in rma.
return_statusstringOne of approved, received, credited.
sourcestringThe portal type that owns this return (e.g. custom, reversio).
notesstring | nullFree-text notes on the return.
return_fee_incl_vatfloat | nullThe return fee including VAT, echoed back from the request.
exchange_fee_incl_vatfloat | nullThe exchange fee including VAT, echoed back from the request.
labelless_codestring | nullLabelless / dropoff code for the return shipment, as reported by the portal.
track_tracestring | nullTracking number for the return shipment, as reported by the portal.
track_trace_linkstring | nullPublic tracking URL for the return shipment, as reported by the portal.
shopify_refund_gift_cardbooleanWhether the refund is issued as a Shopify gift card.
shopify_refund_gift_card_bonus_typestring | nullpercentage, fixed or null.
shopify_refund_gift_card_bonus_valuefloat | nullThe bonus value, in the units implied by the bonus type.
shopify_refund_gift_card_free_shippingbooleanWhether the refund includes shipping.
total_price_after_vatfloat | nullTotal refunded amount including VAT.
lines[]arrayOne entry per line on the return. See Response return line.

Response return line

ParameterData typeDescription
idintTRAEDE's internal line ID. Stable across updates where possible.
variant_idintThe TRAEDE variant ID.
quantityintSame value as expected_return, for symmetry with the request shape.
expected_returnintThe quantity the customer said they would return.
returnedint | nullThe quantity the warehouse has actually received so far.
claim_typestringreturn or claim.
claim_cause_idint | nullThe resolved claim cause ID.
net_pricefloatThe unit price excluding VAT, computed from unit_price_incl_vat.
unit_price_incl_vatfloatThe unit price including VAT, echoed back from the request.
textstring | nullThe customer comment on the line.
regulate_inventorybooleanWhether inventory will be adjusted when the line is received.

Request example

PUT /v10/external-return-portals/abc123xyz/returns

{
"email": "jane@example.com",
"order_number": "1001",
"return": {
"rma": "RMA-1001",
"return_fee_incl_vat": 5.0,
"labelless_code": "LL-ABC-123",
"track_trace": "JD000123456789",
"track_trace_link": "https://tracking.example.com/JD000123456789",
"lines": [
{
"sku": "1000-Black-S",
"quantity": 1,
"claim_type": "return",
"claim_cause_code": "too-small",
"unit_price_incl_vat": 125.0,
"text": "Does not fit"
}
]
}
}

Response example

{
"return": {
"id": 987,
"rma": "RMA-1001",
"rma_number": 1001,
"return_status": "approved",
"source": "custom",
"notes": null,
"return_fee_incl_vat": 5.0,
"exchange_fee_incl_vat": 0.0,
"labelless_code": "LL-ABC-123",
"track_trace": "JD000123456789",
"track_trace_link": "https://tracking.example.com/JD000123456789",
"shopify_refund_gift_card": false,
"shopify_refund_gift_card_bonus_type": null,
"shopify_refund_gift_card_bonus_value": null,
"shopify_refund_gift_card_free_shipping": false,
"total_price_after_vat": 125.0,
"lines": [
{
"id": 4321,
"variant_id": 5555,
"quantity": 1,
"expected_return": 1,
"returned": null,
"claim_type": "return",
"claim_cause_id": 42,
"net_price": 100.0,
"unit_price_incl_vat": 125.0,
"text": "Does not fit",
"regulate_inventory": true
}
]
},
"created": true
}

Finalize a return

Endpoint: POST /v10/external-return-portals/{publicId}/returns/finalize

Books all OPEN credit notes on the return, which transitions the return to credited. Call this once the external portal has settled the return with the customer - by issuing a refund in the customer's payment provider, by giving replacement goods in an exchange, or a combination of both. The return is identified by its external rma in the request body.

caution

Preconditions:

  • The return must be in received or credited status. Otherwise the request is rejected with a validation error.
  • The return must have at least one credit note.
  • The sum of refund_total_price_after_vat and exchange_total_price_after_vat must match the total credited amount across the return's credit notes, with a tolerance of ±0.01. Otherwise the request is rejected with a validation error showing the amounts.

Both amounts are reported as positive numbers. A return of 120.00 that was fully refunded is finalized with "refund_total_price_after_vat": 120.0.

The credit note total is net of fees reported on the upsert (see Fees): a returned item of 100.00 with a 25.00 return fee produces a credit note of 75.00, so the finalize amounts must sum to 75.00.

ParameterData typeRequiredDefaultDescription
rmastringYesThe external RMA identifier of the return to finalize. Must match the rma used when upserting.
refund_total_price_after_vatfloatYesThe refunded amount the portal has issued to the customer, as a positive number. Compared against TRAEDE's credit notes together with exchange_total_price_after_vat.
exchange_total_price_after_vatfloat0The part of the credit that was settled in replacement goods instead of a refund, as a positive number. Cannot exceed the credit note total.

Finalizing exchanges

When the customer exchanges an item, the portal adds the replacement goods to the (Shopify) order itself and little or no money is refunded - yet TRAEDE still issues a credit note for the full value of the returned item. In that case the portal must account for the full credit note across both channels:

refund_total_price_after_vat (refunded) + exchange_total_price_after_vat (settled in replacement goods) = credit note total

Examples for a returned item bought at 100.00:

ScenarioCredit note totalrefund_total_price_after_vatexchange_total_price_after_vat
Pure return, full refund100.0100.00 (or omitted)
Pure return with a 25.00 return fee withheld75.075.00 (or omitted)
Even exchange (replacement worth 100.00)100.00100.0
Even exchange with a 50.00 exchange fee (customer pays the fee in the shop)50.0050.0
Exchange to a cheaper item (80.00), 20.00 refunded100.020.080.0
Exchange to a pricier item (customer pays the difference in the shop)100.00100.0

Data of response

ParameterData typeRequiredDefaultDescription
successbooleanYesAlways true when the request succeeds.
return_idintYesThe TRAEDE ID of the return that was booked.
rmastringYesThe RMA string as stored on the return.

Request example

POST /v10/external-return-portals/abc123xyz/returns/finalize

{
"rma": "RMA-1001",
"refund_total_price_after_vat": 120.0
}

Request example (even exchange, no refund)

POST /v10/external-return-portals/abc123xyz/returns/finalize

{
"rma": "RMA-1002",
"refund_total_price_after_vat": 0,
"exchange_total_price_after_vat": 120.0
}

Response example

{
"success": true,
"return_id": 987,
"rma": "RMA-1001"
}