> For the complete documentation index, see [llms.txt](https://docs.fulfillmenttools.com/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/returns.md).

# Returns

{% hint style="info" %}
This article focuses on the returns process for developers. For information on the returns in the store operations process, see the [Returns app](/documentation/apps/returns-app.md) section.
{% endhint %}

A return is when a consumer sends a purchased product back to the retailer for a refund, exchange, or store credit. The return process typically involves either the consumer physically bringing the items to the store or initiating an online return.

There are two types of return:

* Announced returns (the consumer notifies the retailer in advance about the return)
* Unannounced returns (the consumer returns an item without prior notification)

For both types, there needs to be an item return job with the potential items to be returned from the original order.

## Item return job

An `itemReturnJob` is the main entity in the returns process. It contains all potential `itemReturns` associated with a placed order. It encompasses all items eligible for return (and those not eligible) and tracks the items actually returned. During interactions with the `itemReturnJob`, validations ensure that only items handed over in the given order can be returned in the handed-over quantities.

An `itemReturnJob` is automatically created after the [handover](/documentation/by-pillar/store-operations/handover.md) process. fulfillmenttools then sends a notification with the `ITEM_RETURN_JOB_CREATED` event. If the handover feature isn't used, the `itemReturnJob` can be created via the [item return jobs REST API](/documentation/apis/api-reference/returns-operations.md).

The initial status of the `itemReturnJob` is `OPEN`. The `returnableLineItems` list contains all items from the handover that are eligible for return. The `itemReturnJob` includes all items from all handovers related to the original order, even if the order was split into multiple pick jobs.

Use the endpoint below to get all item return jobs:

```http
GET https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/itemreturnjobs
```

## Item return

An `itemReturn` represents all items actually returned within the associated `itemReturnJob`. It's imperative to have a valid `itemReturnJob` before creating an `itemReturn`.

While adding or updating an `itemReturn` within an existing `itemReturnJob`, item validations ensure that the returned quantity doesn't exceed the delivered and previously returned amounts.

Line items are returned by creating a new `itemReturn` entity within an existing `itemReturnJob`. This is done using the following API call:

{% tabs %}
{% tab title="Endpoint" %}

```http
POST https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/itemreturnjobs/{YOUR_ITEM_RETURN_JOB_ID}/itemreturns
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "itemReturnForCreation": {
    "status": "ANNOUNCED",
    "returnFacilityRef": "{YOUR_FACILITY_ID_WHERE_ITEMS_ARE_RETURNED_TO}",
    "tenantOrderId": "{YOUR_TENANT_ORDER_ID}",
    "returnedLineItems": [
      {
        "itemConditionComment": "Logo print is coming off t-shirt",
        "tenantArticleId": "TSHIRT-NERDHERD-LOGO",
        "status": "OPEN"
      }
    ]
  },
  "itemReturnJobVersion": 1
}
```

{% endtab %}
{% endtabs %}

This call creates a preannounced `itemReturn` with an initial status `OPEN`, which can be updated later as required. Each returned item must be part of the `returnableLineItems` array of the parent `itemReturnJob`. The request must also include the current `itemReturnJobVersion` to prevent concurrent modifications.

The `status` of an `itemReturnJob` doesn't automatically change to `FINISHED`, even if all of its `returnedLineItems` are `ACCEPTED`. The `itemReturnJob` status must be updated explicitly via an API call. This action triggers an `ITEM_RETURN_JOB_UPDATED` event.

### Triggering a refund

A refund is triggered when the `refund` and `status` fields of a specific `returnedLineItem` are updated. This is accomplished using the following `PATCH` request, which requires the current `itemReturnJobVersion`. For more details, refer to the [update returned line item endpoint documentation](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#patch-/api/itemreturnjobs/-itemReturnJobId-/itemreturns/-itemReturnId-/returnedlineitems/-returnedLineItemId-).

{% tabs %}
{% tab title="Endpoint" %}

```http
PATCH https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/itemreturnjobs/{YOUR_ITEM_RETURN_JOB_ID}/itemreturns/{YOUR_ITEM_RETURN_ID}/returnedlineitems/{YOUR_RETURNED_LINE_ITEM_ID}
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "status": "OPEN",
  "refund": {
    "status": "OPEN",
    "price": {
      "value": 19.95,
      "currency": "EUR"
    }
  },
  "itemReturnJobVersion": 2
}
```

{% endtab %}
{% endtabs %}

You can also trigger the refund event via [Backoffice](/documentation/backoffice/network-view/orders/returns.md). You'll need to have the `allowTriggerRefund` setting in the [return configuration](#return-configuration) set to `true` to do this.

## Returnable and non-returnable items

As some items can't be returned for various reasons (customized items, special offers, and so on), an `itemReturnJob` has two arrays of items: `returnableItems` and `notReturnableItems`. These items represent those that are returnable and those that are not.

In the case of an `itemReturnJob` being created automatically in the designated workflow, both arrays are filled automatically as well.

An item will be placed in the `notReturnableItems` array if it was part of a related service job that with the `itemsReturnable` flag set to `false`. Otherwise, it will be placed in the `returnableItems` array.

If, during the [handover](/documentation/by-pillar/store-operations/handover.md) process, items are marked as handed over by setting the `handedOverQuantity` value to at least `1`, then those items will populate one of those arrays. The `handedOverQuantity` sets the `returnable` field.

If there is no [handover job](/documentation/by-pillar/store-operations/handover.md), or none of the handover job's items have a `handedOverQuantity` set to at least `1`, the arrays will be populated with the items from the related [pick job](/documentation/by-pillar/store-operations/picking.md). In this case, the `returnable` attribute is set by the `picked` quantity of the items in the pick job.

You can move items from one array to another by using the corresponding [actions](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#post-/api/itemreturnjobs/-itemReturnJobId-/actions).\
Line items can only be moved if the `itemReturns` array of the corresponding `ItemReturnJob` is empty and if the `returned` item's value to move is 0.

## Return configuration

The [return configuration endpoint](/documentation/apis/api-reference/returns-configuration-operations.md) lets you provide default inputs for your returns. These inputs are then displayed in the Returns app and Backoffice. These can be for:

* [Return reasons](#return-reasons)
* [Return item conditions](#returned-item-conditions)
* [Decision reasons](#decision-reasons)

The example below shows the endpoint you need to use to update the configuration, as well as an example request including all three options.

{% tabs %}
{% tab title="Endpoint" %}

```http
PUT https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/configurations/return
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "version": 1,
  "active": true,
  "availableItemConditions": [
    { "conditionLocalized": { "en_US": "Damaged" } },
    { "conditionLocalized": { "en_US": "Used" } },
    { "conditionLocalized": { "en_US": "Perfect" } } 
  ],
  "availableReturnReasons": [
    { "reasonLocalized": { "en_US": "Item doesn't fit" } },
    { "reasonLocalized": { "en_US": "Item didn't match description" } },
    { "reasonLocalized": { "en_US": "Item is damaged" } }    
  ],
  "availableDecisionReasons": [
   { "reasonLocalized": { "en_US": "Return accepted" } },    
   { "reasonLocalized": { "en_US": "Return rejected" } }, 
   { "reasonLocalized": { "en_US": "Return on hold" } }       
  ],
  "returnTypeConfiguration": {
    "type": "ITEM_RETURN"
  },
  "allowTriggerRefund": true
}
```

{% endtab %}
{% endtabs %}

### Return reasons

Return reasons help you specify why a consumer has returned certain items as you process the return.&#x20;

For example, you could add the reasons below to the [return configuration](/documentation/apis/api-reference/returns-configuration-operations.md):

* Item doesn't fit
* Item didn't match description
* Item damaged

The reasons can be passed while creating an `itemReturn` through the API. Having default reasons is optional for passing reasons into an `itemReturn`.

#### Default values for return reasons in the backend

Default values for return reasons in the backend aren't provided. However, it's possible to manage return reasons on the client side. For example, in the [Returns app](/documentation/apps/returns-app.md), the default value return reason is "no reason". If no additional reasons are specified in the backend, the return reasons will not be displayed.

API users can use the predefined return reasons or provide their own when creating or updating the `itemReturnLineItem` of an `itemReturn`.

### Returned item conditions

Upon receiving the returned item, the item's condition is assessed, eligibility is verified under the return policy, and a suitable resolution is provided (for example, a refund or store credit). This requires the ability to create a return manually.

When accepting returned items, the condition of the items can be defined. In the [Returns app](/documentation/apps/returns-app.md), the default value for conditions is set to "not damaged". However, there is no default value defined in the backend.

Localized `itemConditions` can be added to the `returnConfiguration` via [return configuration REST API](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#put-/api/configurations/return).

The translation depends on the locale of the user using this endpoint and the `tenantLocaleConfiguration`.

### Decision reasons

Decision reasons allow staff to specify why a returned item was accepted, rejected, or put on hold when setting the status of a returned line item.&#x20;

The reasons can be passed while updating a returned line item through the API. Having predefined reasons for decisions is optional, when setting the status of a returned line item.

#### **Default values for decision reasons in the backend**

Default values for decision reasons in the backend aren't provided. However, it's possible to manage decision reasons on the client side. If no decision reasons are configured in the backend, none will be displayed.

API users can use the predefined decision reasons or provide their own when updating the status of a `returnedLineItem`.

## Announced returns

Announced returns are return requests that a consumer has registered before the physical package arrives at the `facility`. Announced returns include the items and details provided by the consumer, such as return reason and item condition.

The return announcement is transferred from the shop and an `itemReturn` is created in the associated `itemReturnJob` with the status `ANNOUNCED`. This job can be updated until it is confirmed.

These details are made available in [Backoffice](/documentation/backoffice/network-view/orders/returns.md) and the [Returns app](/documentation/apps/returns-app.md), where announced returns can be searched for, optionally using a barcode from the return label if provided. Furthermore, the user is able to check and, if necessary, edit those details and confirm the return.

When confirming the return, the status changes from `ANNOUNCED` to `COMPLETED`, and no further changes are possible after confirmation.

### Create an announced return

To create an announced return and complete it, follow the steps below.

{% hint style="info" %}
This example only contains returnable items.
{% endhint %}

{% stepper %}
{% step %}
**Find** **the `itemReturnJobId` for the order**

Query the `GET` endpoint using the `tenantOrderId` and `facilityId`

{% tabs %}
{% tab title="Endpoint" %}

```http
GET https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/itemreturnjobs?searchTerm={YOUR_TENANT_ORDER_ID}&facilityId={YOUR_FACILITY_ID}
```

{% endtab %}

{% tab title="Response" %}
{% code title="Response example (excerpt):" %}

```json
[
  {
    "id": "job_98765",
    "status": "OPEN",
    "tenantOrderId": "ORDER_456",
    "returnableLineItems": [
      {
        "article": {
          "tenantArticleId": "SNEAK-W-4891",
          "title": "White sneakers"
        },
        "delivered": 1,
        "returned": 0,
        "returnable": 1
      }
    ],
    "notReturnableLineItems": [],
    "itemReturns": []
  }
]
```

{% endcode %}
{% endtab %}
{% endtabs %}

From the response, take the `id` for the matching the `tenantOrderId` as the `itemReturnJobId`.
{% endstep %}

{% step %}
**Create the announced return**

Create an announced return using the below endpoint. An announced return must have the status of `ANNOUNCED`.

You need to include the reference of the facility the item(s) are being returned to in the `returnFacilityRef`, as well as at least one entry in `returnedLineItems`.

Each returned line item must include the `tenantArticleId` and a line item status (for example, `OPEN`).

`itemConditionLocalized` and `reasons` are optional.

{% tabs %}
{% tab title="Endpoint" %}

```http
POST https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/itemreturnjobs/{YOUR_ITEM_RETURN_JOB_ID}/itemreturns
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "itemReturnForCreation": {
    "status": "ANNOUNCED",
    "returnFacilityRef": "FACILITY_123",
    "tenantOrderId": "ORDER_456",
    "scannableCodes": ["RETURN_LABEL_789"],
    "returnedLineItems": [
      {
        "tenantArticleId": "SNEAK-W-4891",
        "status": "OPEN",
        "scannedCodes": ["SNEAK-W-4891"],
        "itemConditionLocalized": {
          "de_DE": "Perfekt",
          "en_US": "Perfect"
        },
        "itemConditionComment": "Item doesn't fit",
        "reasons": [
          {
            "reason": "SIZE_TOO_SMALL",
            "reasonLocalized": {
              "de_DE": "Zu klein",
              "en_US": "Too small"
            },
            "comment": "Item doesn't fit"
          }
        ]
      }
    ]
  },
  "itemReturnJobVersion": 0
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "id": "ret_12345",
  "created": "2025-08-11T08:30:00.000Z",
  "status": "ANNOUNCED",
  "returnFacilityRef": "FACILITY_123",
  "tenantOrderId": "ORDER_456",
  "returnedLineItems": [
    {
      "tenantArticleId": "a69006ba-7100-4b4d-a610-1ca28016a4eb",
      "status": "OPEN",
      "itemConditionLocalized": {
        "de_DE": "Wert",
        "en_US": "Value"
      },
      "reasons": [
        {
          "reason": "SIZE_TOO_SMALL",
          "reasonLocalized": {
            "de_DE": "Zu klein",
            "en_US": "Too small"
          },
          "comment": "Upper corner damaged"
        }
      ],
      "recordableAttributes": [
        {
          "group": "general",
          "keyLocalized": {
            "de_DE": "Land",
            "en_US": "Country"
          },
          "recordingRule": "MANDATORY",
          "value": "Germany"
        }
      ]
    }
  ],
  "itemReturnJobId": "job_98765"
}
```

{% endtab %}
{% endtabs %}

You can check the return in Backoffice. Open the **Network view**, and select **Returns** in the sidebar. Then, filter by **Announced** in the **Return status**. You should see your newly created return job in the table.
{% endstep %}

{% step %}
**Edit any information prior to confirmation (optional)**

Edits can be made in the Returns app. You can:

* Adjust quantities
* Replace or correct items within the same order
* Update reasons or conditions (if applicable)
* Add missing items from the same order, if necessary
  {% endstep %}

{% step %}
**Confirm the return using the Returns app**

* Review the summary of items and details
* Confirm the return
* When confirming the return, the status changes from `ANNOUNCED` to `COMPLETED` and no further changes are possible after confirmation
  {% endstep %}
  {% endstepper %}

## Unannounced returns

An unannounced return is when a consumer returns an item without prior notification. This usually happens in a store. You can use the Returns app to manage the return process. See the [Returns app article](/documentation/apps/returns-app.md) for more information.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/returns.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
