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=enThe response has the shape of the creation response. The fields to watch:
| Field | Meaning |
|---|---|
state | Pending (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[].status | Per 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 |
labelURL | PDF label to print, once generated |
qrCodeURL | QR code to show at the parcel shop instead of printing, when the carrier supports it |
needLabel | False when the shop handles the shipping itself: there is nothing to print |
tracking | Carrier tracking once the parcel is scanned: number, url, status (InfoReceived, InTransit, Delivered, Exception...) and the history in statuses |
exchangeOrder | The 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 |
paymentURL | Payment 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 / userPreValidationStatus | Pending, Accepted or Rejected: the decision of the shop and the answer of the shopper in shops that validate first (see Pre-validation) |
value / totalPrice | Value 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:
| HTTP | errorCode | Meaning | What to do |
|---|---|---|---|
| 400 | ValidationFailed | A field is missing or malformed; message lists them | Fix the request |
| 400 | OutOfDate | The deadline of an item has passed, or the chosen reason is no longer valid for it | Read the order again and offer only what its flags and reasons allow |
| 400 | NotReturnableItems | An item is not returnable | Same |
| 400 | BlacklistedItems | An item is blacklisted by the shop | Same |
| 400 | MarketplaceNotActive | The shop is inactive in Drelife | Stop; contact the shop |
| 400 | MaxNumberOfItemsExceeded | More units than the policy allows in one return | Split the return |
| 400 | MaxNumberOfReturnsPerOrderExceeded / MaxNumberOfExchangesPerOrderExceeded | The order already has the maximum number of returns or exchanges | Inform the shopper |
| 400 | OrderAmountLow | The refund is below the minimum amount of the shop | Inform the shopper |
| 400 | OrderAmountLowerThanShipping | The refund does not cover the shipping cost | Offer another method or inform the shopper |
| 400 | NotEnoughStock | The exchange variant is out of stock | Offer another variant |
| 400 | MethodNotAvailable | The shipping method does not serve the address or the items | List the methods again |
| 400 | PickUpDateTooSoon / PickUpDateNotWorkingDay / MaxPickUpDaysExceeded | The pick up date is not one of the pickUpDates of the method | Ask for one of the listed days |
| 400 | Exchanges are not allowed / Returns are not allowed (errorCode BadRequest) | The shop disabled exchanges or returns for this shopper | Do not offer them |
| 401 | Unauthorized / ApiKeyRevoked | The session expired or the key was revoked | Log in again; ask the merchant for a key |
| 404 | NotFound | The order or the return does not exist for this session | Check the identifiers |
| 405 | OrderLocked | Another operation on the order is in progress | Wait a few seconds and retry |
| 405 | CMSNotSupported | The shop platform cannot create the payment of an exchange | Offer a refund instead |
| 400 | PhoneIsRequired | The order has no phone and the carrier needs one | Set it with PATCH /orders/contact and create again |
| 422 | PhoneMustBeValid | The carrier rejected the phone of the shipping address | Update the contact with PATCH /orders/contact |
| 429 | TooManyRequests | Rate limit | Slow down; retry after a minute |
| 502 | CarrierUnavailable | No method could be priced and at least one carrier failed to answer | Retry later |
| 503 | ServiceUnavailable | Maintenance or database unavailable | Retry 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.
Updated about 2 months ago
