Repairs
In the Repair mode the shopper sends a product to be repaired and, unless the shop repairs for free, pays for it. The API mirrors the second-life flow described in Second life (Circular): same login, same discovery of products, same two ways to create a request, same validation step. This page lists what changes for repairs.
The mode is enabled per shop: 400 Repair is not enabled when the code is requested (POST /otp; the other login calls answer 400 Marketplace not found), 503 Catalog is not available for the current mode on the catalog.
Authentication
Identical to Circular with mode=Repair: POST /otp?mode=Repair&lang=en with email and marketplaceName, then POST /otp/verify with the code and "mode": "Repair". The email link of an existing repair reopens it through POST /auth with { "mode": "Repair", "token": "...", "internalId": "<id of the repair>" }.
What can be repaired
GET /orders (Repair mode) merges the same three sources the shop enables: the catalog, the category tree or the real orders of the shopper. The public catalog is GET /products/catalog/{marketplaceUrlName}?mode=Repair, the category tree alone is GET /categories/{marketplaceUrlName}?mode=Repair (public too), and GET /orders/list renders the orders of the shopper as catalog products.
Reasons are the repair services offered: their amount (or the range amount to amountMax; a percentage of the catalog price when isAmountPercentage is true) is the cost of the repair, and requireCustomerInfo, requireCustomerImage, minPicsRequired and minVideosRequired say what the shopper must describe or show (see Attachments).
On GET /policies (Repair mode) read needValidation (the shop quotes before accepting: use /repairs/request), userAcceptation (the shopper confirms the quote), maxNumberOfItems, termsAndConditions, explicitTermsAndConditions and shopListUrl.
Shipping methods
As in Circular, price by weight and address: POST /carriers/methods with weight (grams, 20 to 80000) and addressParam; the origin is the repair address of the shop. Keep the id, shippingMethodId and shippingMethodType of the chosen method.
Create the repair
Shops that accept requests directly
POST /repairs/create opens the repair with its shipping in one call and, when the repair has a cost and the shop uses online payment, issues the payment link; otherwise the label is generated directly.
POST /repairs/create?lang=en
Content-Type: application/json
{
"contact": { "firstName": "Jane", "lastName": "Doe", "address1": "Calle Mayor 1", "city": "Madrid", "zip": "28013", "countryCode": "ES", "provinceCode": "M", "phone": "+34600000000" },
"products": [
{
"id": "8253231888",
"items": [
{ "variantId": "47046763118885", "reasonId": "b1c2d3e4-1111-4a4a-9c9c-aaaaaaaaaaaa", "customerInfo": "Broken zipper", "customerImageNames": ["c0ffee00-1111-4a4a-9c9c-bbbbbbbbbbbb"] }
]
}
],
"methodId": "fdba82c7-abd2-441f-9498-15227cfa0514",
"shippingMethodId": "BNS_PCL",
"shippingType": "DropOff",
"termsAndConditionsAcceptance": true
}| Field | Rules |
|---|---|
contact | Required; the email defaults to the one of the session |
products[] / items[] (equivalent), categories[], orders[] | At least one. products, items and categories take { id, items[] } with one element per unit (reasonId required; variantId, customerInfo, customerImageNames, answers optional); orders takes the order line items directly ({ id, reasonId, ... }) |
methodId, shippingMethodId, shippingType | From the method chosen; desiredPickUp: { date } required for PickUp: 00:00 UTC of one of the pickUpDates the method lists |
termsAndConditionsAcceptance | Must be true |
There is no paymentMethod in the repair creation: the shopper pays through the link the shop configures (see below).
Shops that quote first
When needValidation is true, use POST /repairs/request with only products (or its alias items), categories or orders and the acceptance of the terms. Otherwise the call answers 400 Repair request is not enabled. The shop then quotes each item. The shopper reopens the repair from the email link (POST /auth), reads the quote with GET /repairs/{internalId}/token (items keyed by their repair item id, with validationStatus, price and validationReasonInfo) and closes it with:
POST /repairs/{internalId}/validate:acceptandrejectlists of{ "itemId" }(rejectentries may addreasonInfo), plus the shipping, always required here:methodId,shippingMethodId,shippingType, and optionallycontactanddesiredPickUp. The same rules as Circular apply to the lists: quoted items left out of both lists stayPending, so decide on all of them; no rejections when the shop does not allow them (then every quoted item must be accepted); no duplicates.POST /repairs/{internalId}/reject: no body; declines the whole quote and every item.
Calling /repairs/create on a shop that quotes first is not blocked and skips the quote: read needValidation before choosing.
Paying for the repair
Repair items carry their cost as a negative amount: items[].price is -25.00 for a repair that costs 25, value is the total, and customerPaid is false until the shopper pays. When the shop uses online payment, a paymentURL is issued after the creation or after the validation, also available at GET /repairs/{internalId}/payment-url (404 while there is none); canContinueWithoutCustomerPaid tells whether the shop lets the repair proceed before the payment. The label is generated once the payment is not blocking.
The response and the follow-up
{
"id": "1789734400456",
"name": "F-1789734400456",
"state": "Pending",
"creationDate": "2026-09-16T10:12:00.000Z",
"currency": "EUR",
"value": -25.0,
"shippingCost": 3.95,
"customerPaid": false,
"canContinueWithoutCustomerPaid": false,
"paymentURL": null,
"shippingType": "DropOff",
"needLabel": true,
"items": [
{
"id": "47046763118885",
"name": "Essentials slim T-shirt",
"price": -25.0,
"status": "OnHold",
"reasons": [{ "id": "b1c2d3e4-1111-4a4a-9c9c-aaaaaaaaaaaa" }]
}
]
}idis the identifier of the repair in every other call (GET /repairs/{id},/token,/label,/payment-url,/validate,/reject);GET /repairs/historylists the repairs of the shopper (internalId,name,creationDate).- Each item has
reasons(a list, unlike returns) and, for ranges,offerRangeMin/offerRangeMax. state,items[].status,preValidationStatusanduserPreValidationStatusfollow the vocabulary of Follow a return. Labels, QR codes, tracking and the payment link arrive asynchronously; pollGET /repairs/{id}with bounded retries.
Errors specific to this flow
| HTTP | errorCode | Message | Meaning |
|---|---|---|---|
| 400 | BadRequest | Repair is not enabled | The shop has no repairs |
| 400 | BadRequest | At least one item, category, or order must be provided | Empty request |
| 400 | BadRequest | Repair request is not enabled | /repairs/request on a shop that does not quote first |
| 400 | BadRequest | Item {id} has not enough quantity to repair | More units than the order line item still has |
| 400 | BadRequest | Variant {id} has no price for market {country} and the reason is a percentage of it | Only /repairs/create: a percentage reason needs a price the catalog does not have for that country |
| 400 | BadRequest | Reason {id} is assessable and needs the validation of the shop | Only /repairs/create: an assessable reason is valued by the shop, use the request flow |
| 400 | BadRequest | Item with id {id} does not provide any reasons / Category with id {id} does not provide any reasons | Nothing to repair for that product or category |
| 400 | BadRequest | Category with category ID {id} not valid | A parent category: pick a leaf |
| 400 | BadRequest | Repair is not pre-validated, Repair already validated by user, Repair does not allow user rejection, All approved items must be accepted, Trying to accept an item not approved, No decisions provided, Shipping method not found, Address not found | Rules of the validate and reject calls |
| 400 | MethodNotAvailable, PickUpDateTooSoon, PickUpDateNotWorkingDay, MaxPickUpDaysExceeded, CountryIsRequired, ProvinceIsRequired | Shipping method, pick up date (not one of the pickUpDates of the method) or contact rejected | |
| 404 | NotFound | Not found | Unknown repair for this shopper, or no label or payment link yet |
| 503 | ServiceUnavailable | Catalog is not available for the current mode | Catalog of a shop without repairs |
Updated about 1 month ago
