Follow a return

Returns of the order

With the session of the order:

GET /returns/history
[
  { "internalId": "44891408138533", "name": "1001-R1", "creationDate": "2026-09-16T10:12:00.000Z" }
]

internalId is the identifier to use in the detail below (it is the id of the creation response).

Detail and status

GET /returns/44891408138533?lang=en

The response has the shape of the creation response. The fields to watch:

FieldMeaning
statePending (waiting for the parcel or for the shop), PendingApproval (the shop is reviewing it), Approved (refunded or exchange released), PartiallyApproved (some units refunded, some declined), Declined, Cancelled
items[].statusPer unit: OnHold until the shop processes the parcel, PreApproved or PreDeclined while the shop is verifying the units, then Approved or Declined. The pre-validation decision is not here but in items[].validationStatus and items[].userValidationStatus
labelURLPDF label to print, once generated
qrCodeURLQR code to show at the parcel shop instead of printing, when the carrier supports it
needLabelFalse when the shop handles the shipping itself: there is nothing to print
trackingCarrier tracking once the parcel is scanned: number, url, status (InfoReceived, InTransit, Delivered, Exception...) and the history in statuses
exchangeOrderThe order created in the shop platform for the exchanged units (id, name, isDraft), or null while none exists; isDraft is true while the shopper still owes the payment
paymentURLPayment link when the balance of the return leaves an amount to pay. Read customerPaid (already paid) and canContinueWithoutCustomerPaid (the shop lets the return proceed unpaid) to know whether the shopper still has to pay
preValidationStatus / userPreValidationStatusPending, Accepted or Rejected: the decision of the shop and the answer of the shopper in shops that validate first (see Pre-validation)
value / totalPriceValue of the returned items (the second is an alias kept for compatibility). The shipping cost is shippingCost. The refund actually made is decided by the shop when it processes the return

Poll the detail when the shopper asks or on a schedule, or ask for webhooks (below). A return keeps changing after its approval: the tracking and the refund arrive later.

Webhooks

Drelife can notify your endpoint when a return of the shop is created, updated or deleted (events returns.created, returns.updated, returns.deleted). The subscription is configured by Drelife for the shop: give the merchant or Drelife an HTTPS URL and, optionally, headers to add to the calls. Each notification is a JSON POST with the event, the identifier of the return (reference), the shopper, the shop, the shipping (carrier, tracking number, label URL) and the items with their reasons, signed with an HMAC SHA-256 of the raw body using the secret of the subscription in the X-Webhook-Signature header (sha256=<hex>). Verify the signature before trusting a notification. Deliveries are attempted once with a 10 second timeout and are not retried: treat them as a hint and read the detail to get the current state.

The label

labelURL and qrCodeURL come from the detail; GET /returns/{id}/label returns just the two of them, and 404 while none exists yet. Give the shopper the QR code when there is one: it avoids printing.

Errors and retries

Every error body carries errorCode (see Getting started). The codes of the creation flow:

HTTPerrorCodeMeaningWhat to do
400ValidationFailedA field is missing or malformed; message lists themFix the request
400OutOfDateThe deadline of an item has passed, or the chosen reason is no longer valid for itRead the order again and offer only what its flags and reasons allow
400NotReturnableItemsAn item is not returnableSame
400BlacklistedItemsAn item is blacklisted by the shopSame
400MarketplaceNotActiveThe shop is inactive in DrelifeStop; contact the shop
400MaxNumberOfItemsExceededMore units than the policy allows in one returnSplit the return
400MaxNumberOfReturnsPerOrderExceeded / MaxNumberOfExchangesPerOrderExceededThe order already has the maximum number of returns or exchangesInform the shopper
400OrderAmountLowThe refund is below the minimum amount of the shopInform the shopper
400OrderAmountLowerThanShippingThe refund does not cover the shipping costOffer another method or inform the shopper
400NotEnoughStockThe exchange variant is out of stockOffer another variant
400MethodNotAvailableThe shipping method does not serve the address or the itemsList the methods again
400PickUpDateTooSoon / PickUpDateNotWorkingDay / MaxPickUpDaysExceededThe pick up date is not one of the pickUpDates of the methodAsk for one of the listed days
400Exchanges are not allowed / Returns are not allowed (errorCode BadRequest)The shop disabled exchanges or returns for this shopperDo not offer them
401Unauthorized / ApiKeyRevokedThe session expired or the key was revokedLog in again; ask the merchant for a key
404NotFoundThe order or the return does not exist for this sessionCheck the identifiers
405OrderLockedAnother operation on the order is in progressWait a few seconds and retry
405CMSNotSupportedThe shop platform cannot create the payment of an exchangeOffer a refund instead
400PhoneIsRequiredThe order has no phone and the carrier needs oneSet it with PATCH /orders/contact and create again
422PhoneMustBeValidThe carrier rejected the phone of the shipping addressUpdate the contact with PATCH /orders/contact
429TooManyRequestsRate limitSlow down; retry after a minute
502CarrierUnavailableNo method could be priced and at least one carrier failed to answerRetry later
503ServiceUnavailableMaintenance or database unavailableRetry later

Default rate limits: 600 requests per minute per API key, 20 logins per minute per IP address and email, and 20 unknown keys per minute per IP address. Drelife can configure other values. On a 429, wait for the minute to pass before retrying.


Did this page help you?