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
}
FieldRules
contactRequired; 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, shippingTypeFrom the method chosen; desiredPickUp: { date } required for PickUp: 00:00 UTC of one of the pickUpDates the method lists
termsAndConditionsAcceptanceMust 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: accept and reject lists of { "itemId" } (reject entries may add reasonInfo), plus the shipping, always required here: methodId, shippingMethodId, shippingType, and optionally contact and desiredPickUp. The same rules as Circular apply to the lists: quoted items left out of both lists stay Pending, 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" }]
    }
  ]
}
  • id is the identifier of the repair in every other call (GET /repairs/{id}, /token, /label, /payment-url, /validate, /reject); GET /repairs/history lists the repairs of the shopper (internalId, name, creationDate).
  • Each item has reasons (a list, unlike returns) and, for ranges, offerRangeMin / offerRangeMax.
  • state, items[].status, preValidationStatus and userPreValidationStatus follow the vocabulary of Follow a return. Labels, QR codes, tracking and the payment link arrive asynchronously; poll GET /repairs/{id} with bounded retries.

Errors specific to this flow

HTTPerrorCodeMessageMeaning
400BadRequestRepair is not enabledThe shop has no repairs
400BadRequestAt least one item, category, or order must be providedEmpty request
400BadRequestRepair request is not enabled/repairs/request on a shop that does not quote first
400BadRequestItem {id} has not enough quantity to repairMore units than the order line item still has
400BadRequestVariant {id} has no price for market {country} and the reason is a percentage of itOnly /repairs/create: a percentage reason needs a price the catalog does not have for that country
400BadRequestReason {id} is assessable and needs the validation of the shopOnly /repairs/create: an assessable reason is valued by the shop, use the request flow
400BadRequestItem with id {id} does not provide any reasons / Category with id {id} does not provide any reasonsNothing to repair for that product or category
400BadRequestCategory with category ID {id} not validA parent category: pick a leaf
400BadRequestRepair 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 foundRules of the validate and reject calls
400MethodNotAvailable, PickUpDateTooSoon, PickUpDateNotWorkingDay, MaxPickUpDaysExceeded, CountryIsRequired, ProvinceIsRequiredShipping method, pick up date (not one of the pickUpDates of the method) or contact rejected
404NotFoundNot foundUnknown repair for this shopper, or no label or payment link yet
503ServiceUnavailableCatalog is not available for the current modeCatalog of a shop without repairs

Did this page help you?