> 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/packing.md).

# Packing

A `packJob` is the main entity in the packing process. It contains all the information needed to complete a packing task. A pack job is created automatically after a `pickJob` is finished, but it can also be created via the API.

Pack jobs are designed to pack already picked items (source container) into boxes or bags (target container). The `packingSourceContainers` is listed in the pack job and the pack job action can be used to move the items to the `packingTargetContainers`. These containers can be physical or virtual. If items have been picked via a pick job before the packing process, the container into which the items were picked becomes a packing source container.

You can also print documents and add them to the parcel. This is especially relevant for ship-from-store orders, as you usually print shipping labels and other documents and add them to the parcels here.

Once orders are packed, they're typically stored for handover.

## API operations

Two main endpoints support pack jobs.

### Packjobs

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

The `GET` operation retrieves the current state of a pack job and is useful for reading the line item IDs before patching them.

The `PATCH` operation updates the pack job using one or more actions in the request body. It accepts a `version` field for optimistic locking to prevent conflicting concurrent updates, plus an `actions` array. Multiple actions are available, including setting the overall pack job status via the `ModifyPackJob` action.

See the [Packing endpoints article](/documentation/by-pillar/store-operations/packing/pack-job-endpoints.md) for more details.

### Packjob actions

```http
POST https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/packjobs/{YOUR_PACK_JOB_ID}/actions
```

The `POST` operation triggers specific actions on the pack job, for example, replacing assigned users or adding a target time.

See the [Packing endpoints article](/documentation/by-pillar/store-operations/packing/pack-job-endpoints.md) for more details.

### Example flow

Below is an example of the flow after a [pick job](/documentation/by-pillar/store-operations/picking.md) has been completed.&#x20;

A pack job starts in `OPEN`, moves to `IN_PROGRESS` when packing starts, and finally reaches `CLOSED` when all items are packed.

{% hint style="info" %}
If you're packing in our [Store Operations app](/documentation/apps/store-operations-app.md), the following happens automatically as a user moves through the packing process.
{% endhint %}

{% stepper %}
{% step %}
**Fetch the pack job**

Use the endpoint below to get the pack job version number, line items, and the IDs of its packing source containers.

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

{% endstep %}

{% step %}
**Fetch each packing source container and their contents**

Use the endpoint below to list all source containers and get their version, the `globalLineItemId`, and the quantity of each item. These are needed for the from array of the move action.

```http
GET https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/packingSourceContainers?packJobRef={packJobId}&facilityRef={facilityRef}
```

{% endstep %}

{% step %}
**Update the status**

To start packing, use the endpoint and example request below to change the status to in progress. You'll need the version number from step 1.

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

```http
PATCH https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/packjobs/{YOUR_PACK_JOB_ID}
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "actions": [
    {
      "action": "ModifyPackJob",
      "status": "IN_PROGRESS"
    }
  ],
  "version": 42
}
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}
**Move the items from the source to the target**

Use the endpoint below to move the picked eaches from the packing source container(s) into a packing target container. Use the values you collected in step 2.

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

```http
POST https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/packjobs/{YOUR_PACK_JOB_ID}/actions
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "name": "MOVE_EACHES_TO_PACKING_TARGET_CONTAINER",
  "move": {
    "from": [
      {
        "containerId": "{YOUR_PACKING_SOURCE_CONTAINER_ID}",
        "containerVersion": 1,
        "globalLineItemId": "{YOUR_GLOBAL_LINE_ITEM_ID}",
        "quantity": 1
      }
    ],
    "to": {
      "containerId": "{YOUR_PACKING_TARGET_CONTAINER_ID}",
      "containerVersion": 1
    }
  }
}
```

{% endtab %}
{% endtabs %}

Repeat until all source containers are empty and all items are in target container(s).
{% endstep %}

{% step %}
**Create the parcel**

Use the endpoint below to create the parcel. Create one `parcel` for each `packingTargetContainer`. Add `items` and `parentRef` to the payload. `parentRef` is the ID of the container used as a source (in this case, the `packingTargetContainer`).

{% hint style="info" %}
To get the `shipmentId`, replace `{operativeProcessId}` with the `pickJobId` in the `GET /api/operativeprocesses/{operativeProcessId}` endpoint. The `entityType` will be `SHIPMENT`.
{% endhint %}

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

```http
POST https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/shipments/{YOUR_SHIPMENT_ID}/parcels
```

{% endtab %}
{% endtabs %}

The `POST` call creates the parcel in status `OPEN` and asynchronously triggers label generation with the carrier. The parcel then progresses to  `PROCESSING`, then to `DONE` (or `FAILED`). You must wait for the parcel status to be `DONE`.

{% hint style="info" %}
Poll the parcel with `GET /api/parcels/{parcelId}`. On success, the `result` object contains `sendLabelUrl`, `carrierTrackingNumber`, and `trackingUrl`.
{% endhint %}
{% endstep %}

{% step %}
**Close the pack job**

To close the pack job, use the endpoint below and the example request to change the status to closed. You'll need the version number from step 3.

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

```http
PATCH https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/packjobs/{YOUR_PACK_JOB_ID}
```

{% endtab %}

{% tab title="Request" %}

```json
{
  "actions": [
    {
      "action": "ModifyPackJob",
      "status": "CLOSED"
    }
  ],
  "version": 43
}
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

## Packing container types

Packing containers represent physical containers in which picked items are packed for handover. For example, packages for shipping orders or bags that are handed over to a customer in a store. When creating a packing container, one of the preconfigured types must be chosen.

However, a packing container can also be virtual. That means it only exists in fulfillmenttools and not in the real world.

* Packing container types handle:
  * Name, description, and icon
  * Dimensions (optional)
  * Maximum weight a packing container can carry (optional)

See the [Containers section](/documentation/by-pillar/store-operations.md#containers) or the [Operative container types article](/documentation/by-pillar/store-operations/packing/operative-container-types.md) for more information.

## Packing configuration

The packing configuration allows users to define rules for the packing process, such as scanning requirements, container handling, and document inheritance. The packing configuration is available at `/api/configurations/packing` (see the [packing configuration endpoint section](#packing-configuration-endpoints) for more information) and affects the whole system regardless of the user role or the facility.

In the packing configuration, you can define:

* [The scanning type for pack line items](#scanning-type-configuration)
* [If packing containers are required](#packing-container-required-configuration)
* [If pack line items need a confirmation](#packing-item-confirmation-needed-configuration)
* [If packing source containers are used](#packing-source-container-configuration)
* [How documents should be handled](#document-handling-configuration)

### Scanning type configuration

The scanning type configuration defines whether a physical scan of all pack line items' codes is required to complete a pack job.

This field can be set to one of the following values:

* `MUST_SCAN_EACH`: Each item must be scanned before it can be packed.
* `SCAN_NOT_REQUIRED`: Scanning isn't required. Items can be confirmed manually without scanning.

{% hint style="info" %}
This configuration has no backend logic and is solely used by the client.
{% endhint %}

### Packing container required configuration

The packing container required configuration determines whether the packer must select a target container (for example, a box or a parcel) during the packing process.

This field can be set to one of the following values:

* `true`: The packer must select a container to be packed. Search is enabled for containers.
* `false`: Selecting a container isn't required. Items can be packed without adding a container. Search isn't enabled for containers.

{% hint style="info" %}
This configuration has no backend logic and is solely used by the client.
{% endhint %}

### Packing item confirmation needed configuration

The packing item confirmation needed configuration determines whether the packer must explicitly confirm each item (for example, by tapping or scanning) before it counts as packed.

This field can be set to one of the following values:

* `true`: The packer must check off each pick line item to be packed.
* `false`: Checking off each pack line item isn't required. Items can be packed without explicitly confirming each item.

{% hint style="warning" %}
This configuration has no effect when the scanning type is set to `MUST_SCAN_EACH`. In this case, scanning each pack line item is mandatory to complete a pack job.
{% endhint %}

{% hint style="info" %}
This configuration has no backend logic and is solely used by the client.
{% endhint %}

### Packing source container configuration

The packing source container configuration enables the concept of a source container during packing. A source container represents the container (for example, a tote bag or a bin from the picking process) from which items are packed.

This field can be set to one of the following values:

* `true`: Packing source containers are automatically created when a pack job is generated from a pick job.
* `false`: A packing source container isn't created.

{% hint style="info" %}
To be able to search for pack jobs via the scanned code of a load unit packing, both `packingContainerRequiredConfiguration` and `packingSourceContainerConfiguration` have to be set to `true`.
{% endhint %}

### Document handling configuration

The document handling configuration controls the inheritance of external documents into the process for a pack job.

When a document is added to the `documentSets` of a pack job, it can be inherited to its related process as an external document. Once added to the process, any related entity (order, pick job, pack job, handover job, and so on) can inherit the external document provided the corresponding configuration on that entity is active.

{% hint style="info" %}
See the [External documents article](/documentation/by-pillar/store-operations/external-documents.md) for more information.
{% endhint %}

The `inheritedDocumentConfigurations` array in the packing configuration defines which `section` the inherited document belongs to. This field can be set to one of the following values:

* `ORDER`: The external document(s) are inherited to the order.
* `PACKJOB`: The external document(s) are inherited to the pack job.
* `PICKJOB`: The external document(s) are inherited to the pick job.
* `HANDOVERJOB`: The external document(s) are inherited to the handover job.
* `HANDOVER_CONTAINER`: The external document(s) are inherited to the handover container.
* `PARCEL`: The external document(s) are inherited to the parcel.
* `PACKING_TARGET_CONTAINER`: The external document(s) are inherited to the packing target container.

{% hint style="warning" %}
Although `inheritedDocumentConfigurations` is an array, only the first entry is currently evaluated. Only one section is supported at this time.
{% endhint %}

### Packing configuration endpoints

To access the current packing configuration, use the endpoint below:

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

To update the current packing configuration, use the endpoint below:

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

```http
PATCH https://{YOUR_TENANT_NAME}.api.fulfillmenttools.com/api/configurations/packing
```

{% endtab %}

{% tab title="Request body" %}

```json
{
    "version": 2,
    "packingContainerRequiredConfiguration": {
        "active": true
    },
    "packingItemConfirmationNeededConfiguration": {
        "active": true
    },
    "packingSourceContainerConfiguration": {
        "active": false
    },
    "scanningConfiguration": {
        "scanningType": "MUST_SCAN_EACH"
    },
    "documentHandlingConfiguration": {
        "inheritedDocumentConfigurations": [
           {
            "section": "PICKJOB"
           }
        ]
    }
}
```

{% endtab %}

{% tab title="Response body" %}

```json
{
    "version": 3,
    "packingContainerRequiredConfiguration": {
        "active": true
    },
    "packingItemConfirmationNeededConfiguration": {
        "active": true
    },
    "packingSourceContainerConfiguration": {
        "active": false
    },
    "scanningConfiguration": {
        "scanningType": "MUST_SCAN_EACH"
    },
    "lastModified": "2026-03-05T08:51:43.379Z",
    "id": "packing-configurations",
    "created": "2026-01-09T15:46:48.686Z",
    "documentHandlingConfiguration": {
        "inheritedDocumentConfigurations": [
            {
                "section": "PICKJOB"
            }
        ]
    }
}
```

{% endtab %}
{% endtabs %}

## PATCH /api/configurations/packing

> Update packing config

```json
{"openapi":"3.0.1","info":{"title":"fulfillmenttools","version":"VERSIONLESS"},"tags":[{"description":"Endpoints to create, update, and read packing configuration.","name":"Packing configuration"}],"servers":[{"url":"https://{tenant}.api.fulfillmenttools.com","variables":{"tenant":{"default":"your-tenant-name"}}}],"security":[{"BearerToken":[]}],"components":{"securitySchemes":{"BearerToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"PackingConfigurations":{"allOf":[{"$ref":"#/components/schemas/VersionedResource"},{"properties":{"documentHandlingConfiguration":{"$ref":"#/components/schemas/DocumentHandlingConfiguration"},"packingContainerRequiredConfiguration":{"$ref":"#/components/schemas/PackingContainerRequiredConfiguration"},"packingItemConfirmationNeededConfiguration":{"$ref":"#/components/schemas/PackingItemConfirmationNeededConfiguration"},"packingSourceContainerConfiguration":{"$ref":"#/components/schemas/PackingSourceContainerConfiguration"},"scanningConfiguration":{"$ref":"#/components/schemas/PackingScanningConfiguration"}}}],"type":"object","title":"PackingConfigurations","description":"PackingConfigurations"},"VersionedResource":{"properties":{"created":{"description":"The date this entity was created at the platform. This value is generated by the service.","format":"date-time","type":"string"},"lastModified":{"description":"The date this entity was modified last. This value is generated by the service.","format":"date-time","type":"string"},"version":{"description":"The version of the document to be used in optimistic locking mechanisms.","format":"int64","type":"integer"}},"required":["version"],"type":"object","title":"VersionedResource","description":"VersionedResource"},"DocumentHandlingConfiguration":{"description":"The configuration allows documents that have been added to the document set of a pack job to be added to the process. The configuration sets the section names of the entities to which external documents will be added to. If the configuration set is empty, no external documents will be added to the process.","properties":{"inheritedDocumentConfigurations":{"items":{"$ref":"#/components/schemas/InheritedDocumentConfiguration"},"type":"array"}},"required":["inheritedDocumentConfigurations"],"title":"DocumentHandlingConfiguration","type":"object"},"InheritedDocumentConfiguration":{"properties":{"section":{"$ref":"#/components/schemas/Section"}},"required":["section"],"title":"InheritedDocumentConfiguration","description":"InheritedDocumentConfiguration"},"Section":{"enum":["ORDER","PACKJOB","PICKJOB","HANDOVERJOB","PARCEL","PACKING_TARGET_CONTAINER","HANDOVER_CONTAINER"],"type":"string","title":"Section","description":"Section"},"PackingContainerRequiredConfiguration":{"additionalProperties":false,"description":"Packing Container Required Configuration.","properties":{"active":{"default":false,"type":"boolean"}},"required":["active"],"title":"PackingContainerRequiredConfiguration","type":"object"},"PackingItemConfirmationNeededConfiguration":{"additionalProperties":false,"description":"Do the customer need to validate which items are part of a pack job","properties":{"active":{"default":true,"type":"boolean"}},"required":["active"],"title":"PackingItemConfirmationNeededConfiguration","type":"object"},"PackingSourceContainerConfiguration":{"description":"Can this tenant use the packing source container","properties":{"active":{"default":false,"type":"boolean"}},"required":["active"],"title":"PackingSourceContainerConfiguration","type":"object"},"PackingScanningConfiguration":{"description":"Packing Scanning Configuration.","properties":{"scanningType":{"$ref":"#/components/schemas/PackingScanningConfigurationEnum"}},"title":"PackingScanningConfiguration","type":"object"},"PackingScanningConfigurationEnum":{"enum":["MUST_SCAN_EACH","SCAN_NOT_REQUIRED"],"type":"string","title":"PackingScanningConfigurationEnum","description":"PackingScanningConfigurationEnum"},"ApiError":{"items":{"$ref":"#/components/schemas/ErrorInner"},"type":"array","xml":{"name":"ApiError"},"title":"ApiError","description":"ApiError"},"ErrorInner":{"properties":{"description":{"type":"string"},"requestVersion":{"description":"The version provided within an invalid request.","format":"int64","type":"integer"},"summary":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["summary"],"type":"object","title":"ErrorInner","description":"ErrorInner"}}},"paths":{"/api/configurations/packing":{"patch":{"description":"","operationId":"upsertPackingConfigurations","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackingConfigurations"}}},"description":"create/update packing central configuration","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackingConfigurations"}}},"description":"The packing central configuration was successfully updated."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackingConfigurations"}}},"description":"The packing central configuration was successfully created."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Invalid input. See response for details"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Your user is not allowed to operate against this API instance"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Your user, although recognized, is not authorized to use this endpoint"}},"summary":"Update packing config","tags":["Packing configuration"]}}}}
```


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
