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
| Parameter | Data type | Required | Default | Description |
|---|---|---|---|---|
email | string | Yes for a new return; optional thereafter | The 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_number | string | Yes for a new return; optional thereafter | The order number of the original order. When provided on an existing return it must match the bound order's order_number. | |
return | object | Yes | Return data. |
Return data
| Parameter | Data type | Required | Default | Description |
|---|---|---|---|---|
rma | string | Yes | The 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. | |
notes | string | Free-text notes on the return. | ||
status | string | Update the return status. Valid transitions are constrained by the normal return state machine. | ||
return_fee | float | The return fee to charge the customer. Applied to the resulting credit note. | ||
exchange_fee | float | The fee to charge on the exchange order, if any. | ||
labelless_code | string | A 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_trace | string | The tracking number for the return shipment booked by the external portal. | ||
track_trace_link | string | A URL the customer can use to track the return shipment. | ||
shopify_refund_gift_card | boolean | false | If true, the refund will be issued as a Shopify gift card. | |
shopify_refund_gift_card_bonus_type | string | The type of bonus applied to the gift card refund. Possible values: percentage, fixed. | ||
shopify_refund_gift_card_bonus_value | float | The bonus value to apply, in the units implied by shopify_refund_gift_card_bonus_type. | ||
shopify_refund_gift_card_free_shipping | boolean | false | If true, the customer is refunded for shipping in addition to the line amounts. | |
lines.* | Yes | An array of at least one return line data. lines represents the desired full set of lines on the return; see Line merge behavior. |
Return line data
Each line identifies a variant on the original order. Provide variant_id, sku or ean - whichever is most convenient.
| Parameter | Data type | Required | Default | Description |
|---|---|---|---|---|
variant_id | int | Yes, if no sku or ean is given | The TRAEDE variant ID. | |
sku | string | Yes, if no variant_id or ean is given | The variant SKU. Must match exactly one variant on the brand. | |
ean | string | Yes, if no variant_id or sku is given | The variant EAN. Must match exactly one variant on the brand. | |
quantity | int | Yes | The quantity being returned. Must be greater than zero. | |
claim_type | string | Yes | Possible values: return, claim. | |
claim_cause_id | int | Yes, if portal requires claim causes and no claim_cause_code is given | ID of a claim cause configured on the brand. Must belong to the authenticated brand. | |
claim_cause_code | string | Yes, if portal requires claim causes and no claim_cause_id is given | The 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_vat | float | Yes | The unit price including VAT that the customer paid on the original order. Used for refund math. | |
text | string | A comment from the customer about this line, stored as the line's comments. | ||
regulate_inventory | boolean | true | If 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:
- Exact natural key - same
variant_id,claim_type,claim_cause_id,textandunit_price_incl_vat. This is the happy path: an unchanged line keeps the sameid. - 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. - 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:
| Parameter | Data type | Description |
|---|---|---|
return | object | The resulting return in TRAEDE. See Response return object. |
created | boolean | true if this PUT created a new return, false if it merged into an existing one. |
Response return object
| Parameter | Data type | Description |
|---|---|---|
id | int | TRAEDE's internal numeric return ID. |
rma | string | The external RMA identifier you sent in. |
rma_number | int | The numeric part of the RMA, derived from the digits in rma. |
return_status | string | One of approved, received, credited. |
source | string | The portal type that owns this return (e.g. custom, reversio). |
notes | string | null | Free-text notes on the return. |
return_fee | float | null | The fee charged to the customer on the credit note. |
exchange_order_fee | float | null | The fee charged on the exchange order, if any. |
labelless_code | string | null | Labelless / dropoff code for the return shipment, as reported by the portal. |
track_trace | string | null | Tracking number for the return shipment, as reported by the portal. |
track_trace_link | string | null | Public tracking URL for the return shipment, as reported by the portal. |
shopify_refund_gift_card | boolean | Whether the refund is issued as a Shopify gift card. |
shopify_refund_gift_card_bonus_type | string | null | percentage, fixed or null. |
shopify_refund_gift_card_bonus_value | float | null | The bonus value, in the units implied by the bonus type. |
shopify_refund_gift_card_free_shipping | boolean | Whether the refund includes shipping. |
total_price_after_vat | float | null | Total refunded amount including VAT. |
lines[] | array | One entry per line on the return. See Response return line. |
Response return line
| Parameter | Data type | Description |
|---|---|---|
id | int | TRAEDE's internal line ID. Stable across updates where possible. |
variant_id | int | The TRAEDE variant ID. |
quantity | int | Same value as expected_return, for symmetry with the request shape. |
expected_return | int | The quantity the customer said they would return. |
returned | int | null | The quantity the warehouse has actually received so far. |
claim_type | string | return or claim. |
claim_cause_id | int | null | The resolved claim cause ID. |
net_price | float | The unit price excluding VAT, computed from unit_price_incl_vat. |
unit_price_incl_vat | float | The unit price including VAT, echoed back from the request. |
text | string | null | The customer comment on the line. |
regulate_inventory | boolean | Whether 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": 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": 5.0,
"exchange_order_fee": 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 issued the refund in the customer's payment provider. The return is identified by its external rma in the request body.
caution
Preconditions:
- The return must be in
receivedorcreditedstatus. Otherwise the request is rejected with a validation error. - The return must have at least one credit note.
- The provided
total_price_after_vatmust match the sum oftotal_price_after_vatacross the return's credit notes, with a tolerance of±0.01. Otherwise the request is rejected with a validation error showing both amounts.
| Parameter | Data type | Required | Default | Description |
|---|---|---|---|---|
rma | string | Yes | The external RMA identifier of the return to finalize. Must match the rma used when upserting. | |
total_price_after_vat | float | Yes | The refunded amount the portal has issued to the customer. Compared against TRAEDE's credit notes. |
Data of response
| Parameter | Data type | Required | Default | Description |
|---|---|---|---|---|
success | boolean | Yes | Always true when the request succeeds. | |
return_id | int | Yes | The TRAEDE ID of the return that was booked. | |
rma | string | Yes | The RMA string as stored on the return. |
Request example
POST /v10/external-return-portals/abc123xyz/returns/finalize
{
"rma": "RMA-1001",
"total_price_after_vat": 120.0
}
Response example
{
"success": true,
"return_id": 987,
"rma": "RMA-1001"
}