Pre-validation
Some shops review a request before accepting it: they look at the items, the reasons and the pictures, approve or decline each unit, sometimes adjust the amount, and only then the shopper ships. This page describes that flow for returns and exchanges; second-life offers and repairs follow the same shape with their own endpoints, described in Second life (Circular) and Repairs.
Does the shop pre-validate?
GET /policies says it: needValidation true means the shop reviews first. userAcceptation true means the shop also asks the shopper to confirm the decision (typically because amounts can change); when it is false the shopper still completes the shipping, but cannot reject what the shop approved.
Read needValidation before creating: POST /returns/create on a shop that pre-validates is not blocked and skips the review entirely.
1. The request
POST /returns/request?lang=en
Content-Type: application/json
{
"items": [
{ "id": "14577068736858", "fulfillmentId": "5294120468773", "items": [ { "fulfillmentId": "5294120468773", "reasonId": "9e09f0f3-55bd-4be9-ab86-971eeb773ded", "customerInfo": "It is too small" } ] }
],
"termsAndConditionsAcceptance": true
}No address, shipping or refund method yet. The response is the return with preValidationStatus and userPreValidationStatus set to Pending, includeUserPreValidation telling whether the shopper will have a say, and needLabel true. The units are reserved: they are no longer quantityAvailable on the order. Calling this endpoint on a shop without pre-validation answers 400 Return request is not enabled. The same eligibility rules as the direct creation apply (windows, blacklist, quantities, limits per order).
2. The review
The shop decides from its dashboard. Per unit it sets validationStatus (Accepted or Rejected), a note in validationReasonInfo when it declines, and possibly a new amount (items[].price); on the return it sets preValidationStatus and an optional merchantPreValidationMessage. Nothing else changes until the shopper answers, so there is nothing to poll for except preValidationStatus.
3. The shopper is notified
The shop sends the shopper an email with a link to the portal. The link carries a signed token and the identifier of the return; from an integration, exchange them for a session with POST /auth:
POST /auth
Content-Type: application/json
{ "mode": "Returns", "token": "<token of the link>", "internalId": "44891408138533" }The session it opens is scoped to that order, like a normal login. Like the OTP login of the other modes, /auth accepts the partner API key, which identifies the caller by itself; without it the call must come from a browser on a Drelife portal of the shop (Origin or Referer header: 401 ApiKeyRequired when there is neither, 400 Domain is not allowed from any other site). It accepts twenty calls per minute per IP and return. Then read the decision:
GET /returns/44891408138533/tokenIt answers the return prepared for the decision screen: preValidationStatus, merchantPreValidationMessage, includeUserPreValidation, and the items with id (the identifier of the return unit, the one the next call expects), validationStatus, validationReasonInfo and price.
4. The shopper answers
Accept or reject the approved units and complete the shipping:
POST /returns/44891408138533/validate?lang=en
Content-Type: application/json
{
"accept": [ { "itemId": "d38fce81-37b6-419c-8fb7-ba2f55096396" } ],
"reject": [ { "itemId": "e49a0f22-...", "reasonInfo": "The new amount is too low" } ],
"methodId": "fdba82c7-abd2-441f-9498-15227cfa0514",
"shippingMethodId": "BNS_PCL",
"shippingType": "DropOff",
"paymentMethod": "CreditCard",
"contact": { "firstName": "Jane", "lastName": "Doe", "address1": "Calle Mayor 1", "city": "Madrid", "zip": "28013", "countryCode": "ES", "provinceCode": "M", "phone": "+34600000000" }
}Rules:
- Every unit the shop approved must appear in
acceptorreject; units the shop declined are not decided by the shopper. - When
includeUserPreValidationis false,rejectmust be empty and every approved unit must be accepted. - The shipping (
methodId,shippingMethodId,shippingType,desiredPickUpfor pick ups) and the refund method (paymentMethod, optional; when omitted the return keepsCreditCard, a refund to the original payment) are given here, since the request had none.contactis optional and defaults to the address of the return. When the shop handles the shipping itself (withoutLabeltrue on the return), the shipping fields are not needed. - Accepting no unit marks the return as rejected by the shopper; the reserved units go back to the order.
Or reject the whole decision, with no body:
POST /returns/44891408138533/rejectBoth calls answer the updated return. After an acceptance the label and, for exchanges with a price difference, the payment link are generated asynchronously, as in a direct creation. userPreValidationStatus becomes Accepted or Rejected and the return proceeds as any other; follow it as described in Follow a return.
Errors of the decision calls
| HTTP | errorCode | Message | Meaning |
|---|---|---|---|
| 400 | BadRequest | Return request is not enabled | The shop does not pre-validate |
| 400 | BadRequest | Return is not pre-validated | The shop has not approved the return yet, or declined it |
| 400 | BadRequest | Return already validated by user | The decision was already sent (also for returns created with /returns/create) |
| 400 | BadRequest | Return does not allow user rejection | reject sent while includeUserPreValidation is false |
| 400 | BadRequest | Trying to accept an item not approved / Trying to reject an item not approved | The unit was declined by the shop or does not exist |
| 400 | BadRequest | Duplicated item in accept list / Duplicated item in reject list / Item cannot be both accepted and rejected | Inconsistent lists |
| 400 | BadRequest | Missing decision for approved item {id} | An approved unit is in neither list |
| 400 | BadRequest | All approved items must be accepted | Partial acceptance when the shopper cannot reject |
| 400 | BadRequest | No decisions provided | Both lists empty |
| 400 | BadRequest | Shipping method not found / Address not found / Marketplace address not found | Missing shipping or address when the return needs a label; the last one is a configuration problem of the shop |
| 405 | OrderLocked | OrderLocked | Another operation on the order is in progress; retry in a few seconds |
| 404 | NotFound | Not found | Unknown return for this session |
Updated about 2 months ago
