# Carrier management

A carrier is an external shipping provider (for example, DHL, FedEx, UPS) responsible for transporting packages across the supply change. Each carrier offers distinct services, coverage areas, and service levels.

Carrier management allows the simultaneous connection of different shipping service providers and offers various shipping options at different facilities.

It's primarily used in combination with the order fulfillment but can also be operated headless.

{% hint style="success" %}
By default, a newly created tenant system doesn't show the available carriers within Backoffice as most of the carriers are country-specific. Carriers must be activated via API. After that, it can be configured within Backoffice.
{% endhint %}

## **Role in fulfillmenttools**

Carrier data (for example, pickup availability, cutoff times, service options) is used during routing to compute a [shipment carrier recommendation](#parcels-and-shipments) per order. If a carrier is specified at order level, that specification is used. If not, the recommended carrier is applied during shipment creation based on configured availability and operational constraints.

## **Functional capabilities**

Carrier integrations enable:

* Shipment carrier recommendation based on routing decisions. Applied during shipment creation if no carrier is specified at order level.
* Creation of shipping and return labels.
* Access to tracking information.
* Automatic update of the handover task upon parcel pickup.
* Recording and processing of delivery events, including successful delivery and delivery issues.

## **Carrier configurations**

For consideration during routing and shipment, carriers must:

* Be activated at tenant level (credentials and core settings).
* Be connected to facilities ([facility-carrier connection](#carrier-connections-to-facilities) with status, cutoff times, and optional delivery areas).
* Include [Carrier Country Service Mappings](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/carrier-features-and-requirements#country-service-mapping) (CCSMs) for source and destination requirements and allowed services.
* Define label or parcel classifications and non-delivery days (optional).
* Set carrier capacity per facility-carrier pickup slot (optional).<br>

## Available carriers

Carrier integrations facilitate data exchange with external shipping providers, enabling label creation, tracking, delivery event processing (for example, pick up, in transit, delivered), and handover updates.

Two integration models are supported that are connecting fulfillmenttools and carriers:

* Direct integration: A connection to the carrier's native technical interface. You'll find a list available in the [Standard carrier integrations section](#standard-carrier-integrations).
* Third-party integration: A connection via a multi-carrier provider that acts as an intermediary and offers access to multiple carriers through a single interface. You can find more information in either the [Custom carriers section](#custom-carriers) below and full details in the [Custom carrier article](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/carrier-management/custom-carrier).

Both models support the same functional scope and are accessed through a consistent API layer. The integration method can differ per tenant, depending on contractual and operational requirements. Direct and third-party integrations can also be combined in parallel if needed.

### Standard carrier integrations

The following carriers are currently have direct integrations with fulfillmenttools. Availability depends on the region and service coverage defined in contractual agreements.

<table><thead><tr><th>Carrier</th><th>Release state<select><option value="3KFilBMJAZZw" label="GA" color="blue"></option><option value="nwl47hCo04rW" label="BETA" color="blue"></option><option value="cnhGRNM7BPIv" label="ALPHA" color="blue"></option></select></th><th>Key</th><th>Notes</th></tr></thead><tbody><tr><td><a href="https://www.bring.no/en">Bring</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>BRING</code></td><td>Norway (domestic)</td></tr><tr><td><a href="https://www.dhl.com/de-en/home.html">DHL</a> (Germany)</td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>DHL_V2</code></td><td>Domestic shipping in Germany</td></tr><tr><td><a href="https://www.dhl.com/nl-en/home.html">DHL BeNeLux</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>DHL_BENELUX</code></td><td>Belgium, Netherlands, Luxembourg (domestic)</td></tr><tr><td><a href="https://www.dhl.de/en/geschaeftskunden/express.html">DHL Express</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>DHL_EXPRESS</code></td><td>International</td></tr><tr><td><a href="https://www.dpd.com/de/en/">DPD</a> (Germany)</td><td><span data-option="cnhGRNM7BPIv">ALPHA</span></td><td><code>DPD</code></td><td>Germany</td></tr><tr><td><a href="https://www.dpd.com/ch/en/">DPD</a> (Switzerland)</td><td><span data-option="cnhGRNM7BPIv">ALPHA</span></td><td><code>DPD_CH</code></td><td>Switzerland</td></tr><tr><td><a href="https://www.fedex.com/en-de/shipping/international/international-economy.html">FedEx International Economy</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>FEDEX_ECO</code></td><td>International</td></tr><tr><td><a href="https://www.gls-pakete.de/en">GLS</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>GLS</code></td><td>Germany (domestic)</td></tr><tr><td><a href="https://www.intex-paketdienst.de/">INTEX</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>INTEX</code></td><td>Germany (domestic)</td></tr><tr><td><a href="https://www.postnl.nl/en/">PostNL</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>POSTNL</code></td><td>Netherlands (domestic)</td></tr><tr><td><a href="https://www.postnord.se/en">postnord</a></td><td><span data-option="3KFilBMJAZZw">GA</span></td><td><code>POST_NORD</code></td><td>Scandinavia</td></tr><tr><td>UPS via Parcelbroker</td><td><span data-option="cnhGRNM7BPIv">ALPHA</span></td><td><code>UPS_PARCELBROKER</code></td><td>Germany</td></tr></tbody></table>

**Technology partners**\
Some carriers are integrated through technology partners (for example, VCE). In these cases, the type of credentials required may differ from the carrier's native API. Credentials are provided as part of the onboarding process.

{% hint style="warning" %}
While only one native carrier integration is possible per carrier type, multiple custom carriers can be configured to support diverse operational needs. Multiple custom carriers can coexist within the same tenant. Selection depends on routing, facility connections, and service availability.
{% endhint %}

### Custom carriers

If you don't want to use one of our native carrier integrations, you can create a custom carrier that's connected through an external service or operational process. This mechanism enables you to integrate:

* Local delivery partners (for example, bike couriers)
* Store operators who hand parcels to local drop-off points at flexible times
* Internal delivery fleets with independent routing systems and apps

See the [custom-carrier](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/carrier-management/custom-carrier "mention") article for more information.

## Carrier connections to facilities

Carriers must be explicitly connected to facilities to be available during shipment creation and [routing](https://docs.fulfillmenttools.com/documentation/backoffice/network-view/orders/routing). A facility-to-carrier connection defines where a carrier is operationally available and specifies the configuration parameters that influence routing and shipping logic.

### Entities in carrier integration

Carrier integration involves two categories of entities:

**Configurations entities**

Define how carriers can be set up and used.

* [Carrier](#carrier-configurations): Representation of a shipping provider, created either as a native, third-party, or custom carrier
* [Facility-to-carrier connection](#facility-to-carrier-configuration-parameters): Defines availability at a facility, including cutoff times, delivery areas, and capacity rules
* [Carrier Country Service Mapping (CCSM)](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/carrier-features-and-requirements#country-service-mapping): Template for required data and allowed services per origin–destination combination
* [Label classifications](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/carrier-features-and-requirements#label-classification): Parcel size and weight categories defined in the carrier configuration

**Operational entities**&#x20;

Represent objects created during the fulfillment process:

* Shipment: A container for one or more parcels, always linked to a carrier
* Parcel: A single physical parcel with its own label and tracking information
* Delivery events: Status updates such as pickup, in-transit, or delivered

### Facility-to-carrier configuration parameters

Each facility-to-carrier connection contains specific parameters:

* [Cut off time](https://docs.fulfillmenttools.com/documentation/getting-started/facilities/managed-facilities#fulfillment-closing-times): Time when the carrier performs parcel pickup at the facility. Affects same day delivery eligibility and must align with the facility's fulfillment schedule
* Delivery areas (optional): Postal codes and country codes defining where shipments can be delivered from this facility
* Carrier status: Only carriers that are active both at network and facility level are available for routing
* [Capacity limits](https://docs.fulfillmenttools.com/documentation/getting-started/facilities/managed-facilities#facilities-fulfillmentcapacity) and non-delivery days (optional): Rules to ensure that pickup constraints and calendar restrictions are respected
* Versioning and URL overrides: Updates require versioning (optimistic locking). Facility-specific URL overrides can be defined to differentiate between sandbox and production usage

All configuration steps related to carrier activation and facility assignment must be performed via API. Once activated, carriers can be further managed in Backoffice.

<figure><img src="https://4170739437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLrrr5jgTsDuR38gNJIrm%2Fuploads%2FLtXm1RphskgdBAP77nch%2FCarrier%20connections.png?alt=media&#x26;token=07f4e884-6bb0-430d-90ae-0ac59c30737f" alt=""><figcaption><p>Example of different facilities with individual facility–carrier connections, including standard, same day, custom, and bike carriers.</p></figcaption></figure>

{% hint style="success" %}
By default, a newly created tenant system does not show the available carriers within Backoffice since most of the carriers are country-specific. Activating a carrier has to be done via API. After that, it can be configured within Backoffice.
{% endhint %}

### Data for activating carriers

To ensure frictionless shipping operations, certain data must be available at shipment creation. Data is categorized as mandatory, recommended, or optional. While only mandatory data is required for domestic shipments, providing both mandatory and recommended data is strongly advised, especially for international use cases.

| Data type                         | Mandatory data                                   | Recommended data                                                                                                                                                                      | Overwrite rule                                                                    |
| --------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Source (facility) data            | Postal address of the shipping facility          | <ul><li>Telephone number</li><li>Email address</li></ul>                                                                                                                              | parcel.sender ▷ shipment.sourceAddress ▷ facility.address                         |
| Target (consumer) data            | Consumer postal address (including house number) | <ul><li>Telephone number</li><li>Email address</li></ul>                                                                                                                              | parcel.recipient ▷ shipment.targetAddress ▷ order.consumer.address                |
| Customs (international shipments) | None                                             | <p></p><ul><li>HS Code (8 digits)</li><li>Customs value per unit (in minor currency units, for example, cents)</li><li>Currency (ISO-4217)</li><li>Number of decimal places</li></ul> | orderLine.article.attributes ▷ listing.attributes                                 |
| Insurance values                  | None                                             | <p></p><ul><li>Insurance value per unit (minor currency units)</li><li>Currency (ISO-4217)</li><li>Number of decimal places</li></ul>                                                 | Customs and insurance data are handled separately, no fallback between categories |
| Physical dimensions and weight    | None                                             | <p>Weight per unit (grams)<br>Height, width, length (mm) (optional)</p>                                                                                                               | orderLine.article.attributes ▷ listing.attributes                                 |

**Parcel label classifications**

* Array of predefined parcel types (dimensions, weight) selectable during label creation
* Values are carrier- and contract-specific and may be omitted
* Duplicates are prohibited: Two entries are duplicates if their dimensions and services are identical

## Adding a carrier

In this section, we'll demonstrate how to configure carriers and connect them to facilities via the API.

{% stepper %}
{% step %}
**Add the carrier**

Send a request to the endpoint to create a carrier. In this example, we'll create a DHL carrier and assume the default parcel weight is 2kgs.

{% tabs %}
{% tab title="Carrier endpoint" %}

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers
```

{% endtab %}

{% tab title="Request" %}

```json
{
    "key": "UPS",
    "name": "LU.XY UPS account",
    "status": "ACTIVE",
    "credentials": {
        "key": "UPS",
        "user": "VCE_worldwide_username",
        "password": "VCE_password"
    }
}
```

The `key` property defines the specific carrier to add. If you're creating a custom carrier, this needs to start with `CUSTOM_`.

The `name` can be defined freely.

The `status` can be either `ACTIVE` or `INACTIVE`. If a carrier is created with an `ACTIVE` status, it's immediately available for use.&#x20;

Setting the `defaultParcelWeightInGram` to `2000` causes labels to be generated with that weight by default.&#x20;

The `credentials` are provided by the carrier. The `user` and `password` credentials in this example are prefixed with "VCE". VCE is a technology partner that enables fulfillmenttools to provide integrations with certain Courier, Express, and Parcel (CEP) service providers more quickly. The credentials for this technology partner are provided by a professional services representative.

{% hint style="info" %}
When creating the API key in your carrier portal, ensure it has the necessary permissions for the delivery options you need.
{% endhint %}
{% endtab %}

{% tab title="Response" %}
A successful request returns a `201 created` response containing the ID of the new carrier.

```json
// Some code
```

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

{% step %}
**Connect the carrier to a facility**

A connection is established with a `POST` request to the [endpoint for facility-carrier connections](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#post-/api/facilities/-facilityId-/carriers/-carrierRef-). ad.

{% tabs %}
{% tab title="Endpoint" %}
For a basic connection, an empty JSON object is sufficient for the payload.

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/facilities/<YOUR-FACILITY-ID>/carriers/<YOUR-CARRIER-ID>' \
```

This request requires the `id` of the previously created carrier and the `id` of the target facility.
{% endtab %}

{% tab title="Response" %}
&#x20;A successful connection returns a `200 OK` response with a payload similar to this:

```json
{
    "version": 1,
    "name": "UPS",
    "status": "INACTIVE",
    "cutoffTime": {
        "hour": 12,
        "minute": 0
    },
    "carrierRef": "77214fbf-415c-407b-a682-0fa901ed7848",
    "key": "UPS",
    "deliveryType": "DELIVERY",
    "deliveryAreas": [],
    "facilityRef": "946f17d0-2d14-48f0-a912-d358f2c70e8f",
    "id": "946f17d0-2d14-48f0-a912-d358f2c70e8f_77214fbf-415c-407b-a682-0fa901ed7848",
    "created": "2024-01-24T09:19:44.048Z",
    "lastModified": "2024-01-24T09:19:44.048Z"
}
```

{% endtab %}
{% endtabs %}

You can provide a lot more details in your request, see the example below or the [carrier endpoints article](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/custom-carrier-endpoints#post-api-carriers).

<details>

<summary>More details request for carrier creation</summary>

```json
{
    "key": "DHL_V2",
    "name": "DHL",
    "status": "ACTIVE",
    "defaultParcelWeightInGram": 1000,
    "credentials": {
        "key": "DHL_V2",
        "apiKey": "myApiKey",
        "fallback": {
            "key": "DHL_V2",
            "billingNumber": "XYZ",
            "retoureBillingNumber": "optionalXYZ",
            "dhlBusinessUsername": "Username from DHL Business customer portal (Geschäftskundenportal)",
            "dhlBusinessPassword": "Password from DHL Business customer portal (Geschäftskundenportal)"
        }
    },
    "parcelLabelClassifications": [
        {
            "nameLocalized": {
                "en_US": "Parcel 2 kg",
                "de_DE": "Paket 2 kg"
            },
            "dimensions": {
                "weight": 2000,
                "length": 60,
                "height": 15,
                "width": 30
            },
            "name": "Paket 2 kg"
        },
        {
            "nameLocalized": {
                "en_US": "Parcel 5 kg",
                "de_DE": "Paket 5 kg"
            },
            "dimensions": {
                "weight": 5000,
                "length": 120,
                "height": 60,
                "width": 60
            },
            "name": "Paket 5 kg"
        },
        {
            "nameLocalized": {
                "en_US": "Parcel 10 kg",
                "de_DE": "Paket 10 kg"
            },
            "dimensions": {
                "weight": 10000,
                "length": 120,
                "height": 60,
                "width": 60
            },
            "name": "Paket 10 kg"
        },
        {
            "nameLocalized": {
                "en_US": "Parcel 31.5 kg",
                "de_DE": "Paket 31,5 kg"
            },
            "dimensions": {
                "weight": 31500,
                "length": 120,
                "height": 60,
                "width": 60
            },
            "name": "Paket 31,5 kg"
        }
    ]
}
```

</details>
{% endstep %}

{% step %}
**Set the connection to active**

Send a `PUT` request to the same endpoint and use a request with an active status.

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

```http
PUT https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/facilities/<YOUR-FACILITY-ID>/carriers/<YOUR-CARRIER-ID>' \
```

{% endtab %}

{% tab title="Request" %}
It's crucial to include the `version` number from the object received in the previous `GET` or `POST` response.&#x20;

```json
{
    "version": 1,
    "status": "ACTIVE",
    "name": "UPS"
}
```

{% endtab %}

{% tab title="Response" %}
A successful activation returns a `200 OK` response with the updated object

```json
{
    "version": 3,
    "name": "UPS",
    "status": "ACTIVE",
    "cutoffTime": {
        "hour": 12,
        "minute": 0
    },
    "carrierRef": "77214fbf-415c-407b-a682-0fa901ed7848",
    "key": "UPS",
    "deliveryType": "DELIVERY",
    "deliveryAreas": [],
    "facilityRef": "946f17d0-2d14-48f0-a912-d358f2c70e8f",
    "id": "946f17d0-2d14-48f0-a912-d358f2c70e8f_77214fbf-415c-407b-a682-0fa901ed7848",
    "configuration": null,
    "parcelLabelClassifications": null,
    "tags": null,
    "created": "2024-01-24T09:19:44.048Z",
    "lastModified": "2024-01-24T13:47:48.324Z"
}
```

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

This process can be repeated for all required facility-carrier connections.

To get a list of the available carriers, use the below endpoint. For a more detailed view, you can use the specific carrier endpoint.

{% tabs %}
{% tab title="Get list of available carriers" %}

```http
GET https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers
```

{% endtab %}

{% tab title="Get a specific carrier" %}

```http
GET https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers/{carrierId}
```

Below is a `200 OK` response example:

```
{
    "key": "DHL_V2",
    "name": "DHL_V2",
    "status": "ACTIVE",
    "defaultParcelWeightInGram": 1000,
    "parcelLabelClassifications": [
        {
            "nameLocalized": {
                "en_US": "Parcel 2 kg",
                "de_DE": "Paket 2 kg"
            },
            "dimensions": {
                "weight": 2000,
                "length": 60,
                "height": 15,
                "width": 30
            },
            "name": "Paket 2 kg"
        },
        {
            "nameLocalized": {
                "en_US": "Parcel 5 kg",
                "de_DE": "Paket 5 kg"
        },
            "dimensions": {
                "weight": 5000,
                "length": 120,
                "height": 60,
                "width": 60
            },
            "name": "Paket 5 kg"
        },
        {
            "nameLocalized": {
                "en_US": "Parcel 10 kg",
                "de_DE": "Paket 10 kg"
            },
            "dimensions": {
                "weight": 10000,
                "length": 120,
                "height": 60,
                "width": 60
            },
            "name": "Paket 10 kg"
        },
        {
            "nameLocalized": {
                "en_US": "Parcel 31.5 kg",
                "de_DE": "Paket 31,5 kg"
            },
            "dimensions": {
                "weight": 31500,
                "length": 120,
                "height": 60,
                "width": 60
            },
            "name": "Paket 31,5 kg"
        }
    ],
    "lifecycle": "GA",
    "deliveryType": "DELIVERY",
    "id": "b20fbff2-3443-4969-9b9b-f59dff9e875e",
    "version": 2,
    "created": "2023-03-07T10:53:32.237Z",
    "lastModified": "2023-03-20T10:27:46.231Z"
}
```

{% endtab %}
{% endtabs %}

## Parcels and shipments

A parcel is the digital representation of one physical parcel that's on its way to the consumer. A shipment is the bracket around all parcels sent within a process using the same carrier.

After a parcel was created in status `OPEN`, fulfillmenttools is automatically taking care of the actual creation of the parcel label. During the time it takes fulfillmenttools and the CEPs[^1] API to negotiate and create a parcel, the status of the parcel changes from `OPEN` via `PROCESSING` to finally `DONE`. The shipment also changes its status to `CONFIRMED` as soon as all created parcels of the shipment have reached the status `DONE`.

If a special service (for example, a signature) is required, this can be configured either when creating the parcel or the order. Only services offered by the chosen carrier will be taken when creating a parcel. Providing a service for a carrier which doesn't offer that service will be ignored.

<figure><img src="https://4170739437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLrrr5jgTsDuR38gNJIrm%2Fuploads%2FiUmdeehqU1zgac16XHO4%2FMultiple%20parcel%20shipment.png?alt=media&#x26;token=2e82310f-39d7-4eec-8422-dbafc0b89bf9" alt=""><figcaption></figcaption></figure>

### **Relationship between shipments and parcels.**

Each parcel belongs to exactly one shipment. A shipment reaches `CONFIRMED` when at least one parcel is `DONE` and no parcel remains in `OPEN` or `WAITING_FOR_INPUT`.

### Process overview

After the order is captured, routing is triggered. The resulting routing plan event includes the carrier, either taken from the order or preselected as the best available carrier according to configuration (carrier shipment assignment). From this event, the shipment and pick job are created. At this moment, the carrier is set on the shipment (shipment creation).&#x20;

When using clients, picking and packing are completed so that the subsequent label request contains the actually picked/packed items. In headless scenarios, a label can be requested immediately (process-dependent), or items can be provided explicitly with the request (parcel creation). The label request is asynchronous. Parcels progress through `OPEN` to `PROCESSING` to `DONE`/`FAILED`, and the shipment follows the defined status logic.

### Shipment status flow

* `INITIAL`: Shipment created
* `REQUEST`: Parcel label requests initiated
* `CONFIRMED`: All parcel labels have been successfully created
* `COMPLETED`: Shipment processed

### Parcel status flow

Label creation is performed asynchronously via the carrier API. While communication is in progress, the parcel remains in `PROCESSING`. The status progresses as follows:

* `OPEN`: Parcel created
* `PROCESSING`: Label request submitted; awaiting carrier/CEP response
* `WAITING_FOR_INPUT`: Parcel created but required information is missing (for example, per [CCSM](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/carrier-features-and-requirements#country-service-mapping))
* `DONE`: Label creation completed
* `FAILED`: Label creation was not successful

Upon completion, the parcel result includes tracking information and label download links. On failure, the summary contains carrier error details.

### Create a shipment for a parcel

{% stepper %}
{% step %}
**Create a shipment**

Use the endpoint below with the request to create a shipment.

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

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/shipments
```

{% endtab %}

{% tab title="Request" %}

```json
{
    "facilityRef":"{your-facilityID}",
    "carrierRef": "{your-carrierID}",
    "orderDate":"2025-12-11T08:16:07.000Z",
    "targetAddress":{
        "firstName":"Phil",
        "lastName":"Bison",
        "street":"4th Street",
        "houseNumber":"1000",
        "postalCode":"90403",
        "city":"Los Angeles",
        "country":"US"
    },
    "targetTime":"2025-12-23T08:16:07.000Z"
}
```

The shipment contains references to the facility, the CEP, and the delivery address.

{% hint style="info" %}
This shipment isn't connected to an existing process. To associate it with a specific process, provide the `processId` in the request. Shipments can also be created during preceding processes, such as an order or `PickJob`, in which case data like the target address is inherited by the shipment created by fulfillmenttools.
{% endhint %}
{% endtab %}

{% tab title="Response" %}

```json
{
    "facilityRef": "{your-facilityID}",
    "carrierRef": "{your-carrierID}",
    "orderDate": "2025-12-11T08:16:07.000Z",
    "targetAddress": {
        "firstName":"Phil",
        "lastName":"Bison",
        "street":"4th Street",
        "houseNumber":"1000",
        "postalCode":"90403",
        "city":"Los Angeles",
        "country":"US"
    },
    "targetTime": "2025-12-23T08:16:07.000Z",
    "id": "3e62db41-af9e-4ce1-8c44-1ef340457057",
    "hasActiveCarrier": true,
    "status": "INITIAL",
    "_order": "0",
    "processId": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "created": "2025-12-11T08:16:07.000Z",
    "lastModified": "2025-12-11T08:16:07.000Z",
    "version": 1
}
```

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

{% step %}
**Create a parcel**

Use the endpoint below with the request to create a parcel associated with the shipment.

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

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/shipments/{your-shipment-ID}/parcels
```

{% endtab %}

{% tab title="Request" %}
You can leave the request empty, or input details as you wish.
{% endtab %}

{% tab title="Response" %}

```json
{
    "loadUnitRefs": [],
    "version": 1,
    "id": "713b9cd8-6d47-45ff-a12a-ef3acb270180",
    "status": "OPEN",
    "shipmentRef": "3e62db41-af9e-4ce1-8c44-1ef340457057",
    "processRef": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "carrierRef": "{your-carrierID}",
    "orderDate": "2025-12-11T08:16:07.000Z",
    "recipient": {
        "firstName":"Phil",
        "lastName":"Bison",
        "street":"4th Street",
        "houseNumber":"1000",
        "postalCode":"90403",
        "city":"Los Angeles",
        "country":"US"
    },
   "sender": {
        "city": "Los Angeles",
        "companyName": "Nerd Herd Clothing Ltd",
        "country": "US",
        "houseNumber": "1344",
        "postalCode": "90291",
        "street": "Abbot Kinney Blvd",
        "resolvedCoordinates": {
            "lat": 33.9906506,
            "lon": -118.4666995,
            "source": "BACKEND_GENERATED"
        },
       "resolvedTimeZone": {
            "offsetInSeconds": -18000,
            "timeZoneId": "America/New_York",
            "timeZoneName": "Eastern Standard Time",
            "source": "BACKEND_GENERATED"
        }
    },
    "returnAddress": {
        "city": "Los Angeles",
        "companyName": "Nerd Herd Clothing Ltd",
        "country": "US",
        "houseNumber": "1344",
        "postalCode": "90291",
        "street": "Abbot Kinney Blvd",
        "resolvedCoordinates": {
            "lat": 33.9906506,
            "lon": -118.4666995,
            "source": "BACKEND_GENERATED"
        },
        "resolvedTimeZone": {
            "offsetInSeconds": -18000,
            "timeZoneId": "America/New_York",
            "timeZoneName": "Eastern Standard Time",
            "source": "BACKEND_GENERATED"
        }
    },
    "dimensions": {
        "weight": 1000
    },
    "facilityRef": "{your-facilityID}",
    "items": [],
    "operativeProcessRef": "019cfc40-d8a7-756c-adff-abcc8db71584",
    "documentsRef": "019cfc41-d3f1-77a3-9821-2d81ec1afbd8",
    "lastModified": "2026-03-17T14:44:58.494Z",
    "id": "019cfc41-d3cd-71b8-b3ba-78756b4ca2a0",
    "created": "2026-03-17T14:44:58.494Z"
} 
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
This example shows the simplest way to create a parcel, where fulfillmenttools uses all necessary information from the corresponding shipment. However, it's possible to override data from the shipment for each created parcel, such as its dimensions, recipient, sender, or return address.
{% endhint %}

This creates the parcel entity with the status `OPEN`. Asynchronously, fulfillmenttools automatically advises the parcel label with the carrier. During this process, the parcel status transitions from `OPEN` to `PROCESSING`, and finally to `DONE`. The shipment status changes to `CONFIRMED` once all its associated parcels reach the `DONE` status.
{% endstep %}

{% step %}
**Get updates on the parcel status and check results**

Once the parcel status is `DONE` (successful) or `FAILED`, the `result` attribute contains the outcome.&#x20;

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

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/parcels/{your-parcel-ID}
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "loadUnitRefs": [],
    "version": 3,
    "id": "713b9cd8-6d47-45ff-a12a-ef3acb270180",
    "status": "DONE",
    "shipmentRef": "{your-shipmentID}",
    "processRef": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "carrierRef": "{your-carrierID}",
    "result": {
        "summary": "",
        "carrierTrackingNumber": "0101010101011101001",
        "trackingUrl": "https://nolp.dhl.de/nextt-online-public/set_identcodes.do?lang=de&idc=222201010030668852",
        "sendLabelUrl": "https://storage.googleapis.com/ocff-greycat-git-shipment-label-bucket/713b9cd8-6d47-45ff-a12a-ef3acb270180_send.pdf",
        "labelUrl":"https://storage.googleapis.com/ocff-greycat-git-shipment-label-bucket/713b9cd8-6d47-45ff-a12a-ef3acb270180_all.pdf"
    },
    ...
}
```

The `result` object provides details about the outcome:

* On **success** (status `DONE`), the object contains the `carrierTrackingNumber`, a `trackingUrl`, and URLs for the shipping label (`sendLabelUrl`) and any other relevant documents (`labelUrl`), such as delivery notes or return labels.
* On **failure** (status `FAILED`), the `summary` attribute contains information about the cause of the failure. This error message usually originates from the carrier, and fulfillmenttools has limited control over its content.

In this successful case, the shipping label can be downloaded with the following call:

```http
GET https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/parcels/{your-parcelID}/labels/all.pdf
```

{% hint style="info" %}
**Note:** The response has the `Content-Type: application/pdf` and contains binary data.
{% endhint %}
{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

[^1]: Courier, Express, and Parcel Services
