Requests
Returns, second-life offers and repairs each have their own list, but the day-to-day work of a shop is one queue: what needs a decision now, by whom, and what is blocked. GET /requests is that queue. It merges the three kinds of request into one row shape, tells the stage each one is at, the actions the caller can take on it, and why it cannot move; and it is the only list with a page size and a total.
The list
GET /requests?types=return,purchase&stages=validation,approval&actionableOnly=true&page=0&pageSize=25&sort=createdAt:desc{
"data": [
{
"requestId": "return:1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"requestType": "return",
"entityId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"reference": "1029-R1",
"orderName": "#1029",
"mode": "Returns",
"requestStage": "approval",
"requestStatus": "pending",
"availableActions": ["approve_process"],
"blockingReasons": [],
"isActionable": true,
"isClosed": false,
"customer": { "id": "...", "firstName": "Jane", "lastName": "Doe", "email": "[email protected]" },
"marketplace": { "id": "...", "name": "Your Shop", "currency": "EUR" },
"createdAt": "2026-09-15T09:12:00.000Z",
"updatedAt": "2026-09-16T08:00:00.000Z",
"total": 29.90,
"currency": "EUR",
"originCountry": "ES",
"shippingType": "DropOff",
"carrierName": "GLS",
"trackingNumber": "12345678",
"trackingStatus": "Delivered",
"paymentMethod": "CreditCard",
"customerPaid": true,
"returnTypes": ["Return"],
"policyContext": { "allowPreValidation": false, "allowPreApprovals": true, "mustPreProcess": false, "requiresCustomerPayment": false },
"workflowSnapshot": { "state": "Pending", "preValidationStatus": "Accepted", "userPreValidationStatus": "Accepted", "preprocessedState": "Approved", "customerPaid": true }
}
],
"pagination": { "page": 0, "pageSize": 25, "returned": 1, "total": 1, "totalPages": 1, "hasNextPage": false, "hasPreviousPage": false },
"filtersApplied": { "types": ["return", "purchase"], "stages": ["validation", "approval"], "actionableOnly": true, "sort": "createdAt:desc" },
"summary": { "total": 1, "shippingStatuses": { "Delivered": 1 }, "withoutTracking": 0 }
}Roles: every role of the shop except Publisher. Each row carries:
| Field | Meaning |
|---|---|
requestType, entityId, requestId | return, purchase or repair; entityId is the identifier to use with /returns/{id}, /purchases/{id} or /repairs/{id}; requestId is <type>:<entityId> |
requestStage | validation (waiting for the appraisal or pre-validation, or for the shopper), verification (parcel to check), approval (to process), publication (processed offer with units to publish), closed |
requestStatus | pending, in_progress, blocked, approved, declined, partially_approved, cancelled, rejected_prevalidation_merchant, rejected_prevalidation_customer |
availableActions | What the caller can do now: validate_accept, validate_reject, verify, approve_process, publish, prepare, set_paid |
blockingReasons | Why it cannot move: PREVALIDATION_REQUIRED, CUSTOMER_VALIDATION_REQUIRED, PREPROCESS_REQUIRED, CUSTOMER_PAYMENT_REQUIRED, INVALID_STATE, MISSING_PERMISSION |
isActionable, isClosed | Shortcuts on the two above |
reference, orderName, internalId, externalId, mode, returnTypes, total, currency, originCountry | Identification and amounts; mode is Returns, Circular or Repair |
shippingType, shippingMethod, carrierName, trackingNumber, trackingStatus, paymentMethod, customerPaid | Shipping and payment |
policyContext, workflowSnapshot | The policy flags that shape the flow and the raw statuses of the underlying request |
Filters: types, stages, statuses (comma-separated or repeated), actionableOnly, closedOnly, search (reference, order name, customer name or email), reference, customer, email, originCountry, returnType, trackingStatus, shippingMethod, carrier (__none__ for requests without tracking), trackingNumber, paymentMethod, payments (Paid, NoPaid), dateFrom, dateTo. sort is createdAt or updatedAt with :asc or :desc; pageSize goes up to 100.
Two behaviours to keep in mind:
- The default window is the last thirty days (
dateFromanddateTo), against two months on the per-type lists. - Rows the caller cannot act on are hidden, unless the role can see history or the row is in a stage that concerns it. Owners and managers see everything; a
PreValidatorsees what needs an appraisal, aPreApproveror aShopwhat needs verification or preparation, anApproverwhat needs processing plus the closed requests, the publications and the requests waiting for the shopper's payment.
summary.shippingStatuses counts the rows of the current filter by tracking status, withoutTracking those with no parcel yet.
Act from the queue
POST /requests/return/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d/actions/approve_process
Content-Type: application/json
{ "items": [ { "returnItemId": "d38fce81-...", "status": "Approved", "amount": 29.90, "restock": true } ] }The body is the one of the underlying endpoint (/pre-validate for validate_accept and validate_reject, /pre-process for verify, /process for approve_process), validated with the same rules. For returns, validate_accept and validate_reject set the decision themselves on every unit still Pending and the body may be empty (message optional; on a rejection it becomes the note of each unit); for offers and repairs the body carries the per-unit validationStatus and the action name only checks the permission and the state. It answers 201 with { "request": <the row, re-evaluated> }; the response of the underlying endpoint is not returned, read the detail if you need it.
Errors: 403 Action ... is not available for this user, 409 Action ... is not available for the current request state, 404 Request return:... not found, 400 Workflow action set_paid is not supported yet, 400 Workflow action publish must be performed from the request detail (publish and prepare use the endpoints of Second life and repairs).
Exports
GET /requests/export answers the URL of a CSV with every row of the filter (no pagination): reference, customer, marketplace, country, stage, status, creation date, type (when returns are included), shipping method, carrier, tracking number and status, total, currency, payment method and paid flag (returns and repairs). GET /requests/export/products does the same with one row per returned unit, for returns only. Both need StoreOwner, Manager or Approver.
Updated about 2 months ago
