Adding & connecting carriers to facilities

Carrier

Get a list of available carriers
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
{
    "total": 5,
    "carriers": [
        {
            "id": "5s6fF85BaTnQ9f5uT6uaSC",
            "name": "GLS",
            "key": "GLS",
            "deliveryType": "DELIVERY",
            "status": "INACTIVE",
            "version": 2
        },
        {
            "id": "9GvnfJQxdzBcQThaawZjgm",
            "name": "ANGEL",
            "key": "ANGEL",
            "deliveryType": "SAMEDAY",
            "status": "ACTIVE",
            "version": 1
        },
        {
            "id": "b20fbff2-3443-4969-9b9b-f59dff9e875e",
            "name": "DHL_V2",
            "key": "DHL_V2",
            "deliveryType": "DELIVERY",
            "status": "ACTIVE",
            "version": 2
        },
        {
            "id": "b1d65915-6fac-43a5-ac73-695b9f99dfef",
            "name": "Local Delivery Partner in Cologne",
            "key": "CUSTOM",
            "deliveryType": "DELIVERY",
            "status": "ACTIVE",
            "version": 1
        },
        {
            "id": "703f43cb-b15e-44ca-bbb4-56e403e59740",
            "name": "FEDEX",
            "key": "FEDEX",
            "deliveryType": "DELIVERY",
            "status": "ACTIVE",
            "version": 3
        }
    ]
}

The response provides a list of configured carriers, along with general information and their key. The key identifies the implementation fulfillmenttools uses when this carrier is employed to, for example, issue a label request or set up a track and trace connection for a parcel.

A more detailed view of a configured carrier can be obtained by requesting a specific carrier instance.

Get a specific carrier
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers/b20fbff2-3443-4969-9b9b-f59dff9e875e' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
{
    "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"
}

A Carrier instance is a singleton within the fulfillmenttools platform. It can exist only once per tenant.

As shown in the response, configurations can be applied to each carrier instance. For details, refer to the Add Carrier API reference.

Creation of a carrier

Create a carrier
curl -sSL -X POST 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "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"
        }
    ]
}'

As shown in the request, some configurations for this carrier are provided upon creation. Some of the notable attributes include:

Attribute
Description

defaultParcelWeightInGram

This value depicts, no surprise here, the default value (1000 gram) to a parcel advised using this carrier. However, the actual weight might be overwritten by the actual call for the creation of a parcel (see add Parcel in our API Specification).

parcelLabelClassifications

This array of values describes which parcel dimensions should be selectable by a client when issuing a parcel. Please see, that these values are dependent on the carrier and your contract with it. It also maybe not be a mandatory value and could possibly be omitted. Duplicates are prohibited. An entry is considered as an duplicate, if the dimensions and the services are equal.

credentials

The credentials that are used to connect to the carriers' API. Which kind of credentials is needed depends on the carrier (selected by the attribute key. In this case the DHL API in Version 2 is selected. Thus we need to provide an API Key. Also there is (especially for DHL) the possibility to provide Fallback Credentials using the legacy DHL API ("DHL Geschäftskunden API" in this case.)

logoUrl

This optional attribute can be used to set a specific logo to a custom carrier or to overwrite the fallback logos for standard carriers provided by fulfillmenttools if needed.

Carrier-specific configuration

Depending on the carrier implementation (identified by the key), additional configuration may be required to operate the carrier.

Get carrier configuration
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers/488bd1a6-6c76-4407-8dab-ece716dac14d/configuration' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
{
    "id": "DHL_V2",
    "version": 9,
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "created": "2022-10-19T10:02:03.545Z",
    "lastModified": "2023-04-03T11:07:21.169Z",
    "returnLabel": false,
    "mustBeWeighed": false
}

The returnLabel attribute is a key configuration. It instructs fulfillmenttools whether to create a return label with every shipping label requested from the carrier.

Please refer to Get Carrier Configuration from API and Change Configuration via API in our documentation to understand which kind of configuration is necessary / advised.

Connection between a facility and a carrier

Drawing
Diagram showing the relationship between a tenant, multiple carriers, and multiple facilities. A carrier can be connected to one or more facilities.

In the context of carrier services, a facility is a location where courier, express, and parcel (CEP) services pick up parcels or where inter-facility transfers begin or end. Carriers can be assigned to one or more facilities. This information enables a fencing strategy, which allows routing orders to a facility where the required carrier is active.

Carriers enabled at the tenant level must also be enabled for the specific facilities where they are available. The facility-to-carrier connection includes configurations that allow for frictionless carrier services.

Attribute
Description

cutoffTime

The cut-off time (hour and minute) describes the time when the carrier usually arrives to collect parcels. This information is especially useful when configuring same-day deliveries, as it is crucial to finish any fulfillment process before the carrier's arrival.

deliveryAreas

This optional value is particularly relevant for custom and same-day carriers. It shows which target addresses (identified by an array of ISO 3166-1 alpha-2 country codes and their respective postal codes) are valid for a parcel sent via this carrier from the facility.

Connect an existing carrier to a facility

In this example, a [carrier] (https://docs.fulfillmenttools.com/documentation/developer-docs/more-integration-guides/carriers/introduction-to-carrier-configuration) and a [facility] (https://docs.fulfillmenttools.com/documentation/developer-docs/integration-guides/facilities) were already created:

Get the carrier
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers/488bd1a6-6c76-4407-8dab-ece716dac14d' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
{
    "id": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "key": "DHL_V2",
    "name": "DHL",
    "status": "ACTIVE",
    "lifecycle": "GA",
    "deliveryType": "DELIVERY",
    "version": 11,
    "created": "2022-10-19T10:02:03.150Z",
    "lastModified": "2023-03-29T08:44:51.484Z",
    "credentials": {
        "key": "DHL_V2"
    }
    ...
}
Get the facility
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/facilities/a81a1c85-cfe5-49d3-81d3-675154ef323e' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
{
    "id": "a81a1c85-cfe5-49d3-81d3-675154ef323e",
    "name": "Darkstore Cologne",
    "address": {
        "street": "Schanzenstr.",
        "houseNumber": "8-20",
        "postalCode": "51063",
        "city": "Cologne",
        "country": "DE",
        "companyName": "fulfillmenttools",
        "resolvedCoordinates": {
            "lon": 7.013988,
            "lat": 50.964969
        },
        "resolvedTimeZone": {
            "offsetInSeconds": 3600,
            "timeZoneId": "Europe/Berlin",
            "timeZoneName": "W. Europe Standard Time"
        },
        ...
    },
    "locationType": "WAREHOUSE",
    "services": [
        {
            "type": "PICKUP"
        },
        {
            "type": "SHIP_FROM_STORE"
        }
    ],
    "status": "ONLINE",
    "created": "2022-12-20T10:00:48.419Z",
    "lastModified": "2023-03-27T14:13:51.213Z",
    "version": 6,
    ...
}

Note the id of the facility (a81a1c85-cfe5-49d3-81d3-675154ef323e) and the id of the carrier (488bd1a6-6c76-4407-8dab-ece716dac14d). Both values are required to create a connection between the two entities.

Create the connection

Using both IDs in the target URL, the following call connects the carrier to the facility.

Connect carrier to facility
curl -sSL -X POST 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/facilities/a81a1c85-cfe5-49d3-81d3-675154ef323e/carriers/488bd1a6-6c76-4407-8dab-ece716dac14d' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "status": "ACTIVE",
    "cutoffTime": {
        "hour": 16,
        "minute": 30
    }
}'

200 OK
{
    "version": 1,
    "name": "DHL_V2",
    "status": "ACTIVE",
    "cutoffTime": {
        "hour": 16,
        "minute": 30
    },
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "key": "DHL_V2",
    "deliveryType": "DELIVERY",
    "deliveryAreas": [],
    "facilityRef": "a81a1c85-cfe5-49d3-81d3-675154ef323e",
    "id": "a81a1c85-cfe5-49d3-81d3-675154ef323e_488bd1a6-6c76-4407-8dab-ece716dac14d",
    "created": "2023-04-13T12:57:46.254Z",
    "lastModified": "2023-04-13T12:57:46.254Z"
}

An empty deliveryAreas array indicates that there are no delivery target restrictions.

The cut-off time is set to 4:30 PM. In this example, this is the time the DHL driver typically arrives at the dark store to collect parcels.

As long as the Carrier and the FacilityCarrierConnection have the status ACTIVE, it is possible to create shipments and parcels with DHL as the CEP originating from this facility. See Create a shipment with parcels to track.

Create a shipment with parcels to track

Drawing
Diagram showing that a single Shipment can contain one or more Parcels.

Before creating a parcel, it is important to understand two key entities: Shipment and Parcel.

Entity
Description

Parcel

A digital representation of a physical parcel that is advised or on its way to the consumer.

Shipment

A container for all parcels sent within a single process using the same carrier. Note: Certain data, such as dimensions or targetAddress, can be overridden at the parcel level.

Assuming a Facility has been connected to a Carrier, this use case demonstrates how to create a standalone shipment with two parcels, without a preceding PickJob or other leading entity. This demonstrates the flexibility of fulfillmenttools, where parts of the system, such as shipment creation, can be used independently to suit specific operational needs, like dynamically creating a shipment label for use in other systems.

Create a shipment for pickup

The following call creates a shipment to be picked up from facility 4fd70a59-9efe-40fd-808b-08ae86ca558f using the DHL carrier with ID 488bd1a6-6c76-4407-8dab-ece716dac14d.

Create shipment
curl -sSL -X POST 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/shipments' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "facilityRef":"4fd70a59-9efe-40fd-808b-08ae86ca558f",
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "orderDate":"2023-04-13T13:58:46.254Z",
    "targetAddress":{
        "firstName":"Luke",
        "lastName":"Skywalker",
        "street":"Planetenstraße",
        "houseNumber":"13",
        "postalCode":"40223",
        "city":"Düsseldorf",
        "country":"DE"
    },
    "targetTime":"2023-04-13T13:58:46.254Z"
}
'

201 Created
{
    "facilityRef": "4fd70a59-9efe-40fd-808b-08ae86ca558f",
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "orderDate": "2023-04-13T13:58:46.254Z",
    "targetAddress": {
        "firstName": "Luke",
        "lastName": "Skywalker",
        "street": "Planetenstraße",
        "houseNumber": "13",
        "postalCode": "40223",
        "city": "Düsseldorf",
        "country": "DE"
    },
    "targetTime": "2023-04-13T13:58:46.254Z",
    "id": "3e62db41-af9e-4ce1-8c44-1ef340457057",
    "hasActiveCarrier": true,
    "status": "INITIAL",
    "_order": "0",
    "processId": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "created": "2023-04-13T13:20:27.282Z",
    "lastModified": "2023-04-13T13:20:27.282Z",
    "version": 1
}

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

This shipment is not 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.

With the shipment in place, a parcel can be created by issuing the following request.

Create a parcel for the shipment
curl -sSL -X POST 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/shipments/3e62db41-af9e-4ce1-8c44-1ef340457057/parcels' \
  --header 'Authorization: Bearer <TOKEN>'

201 Created
{
    "loadUnitRefs": [],
    "version": 1,
    "id": "713b9cd8-6d47-45ff-a12a-ef3acb270180",
    "status": "OPEN",
    "shipmentRef": "3e62db41-af9e-4ce1-8c44-1ef340457057",
    "processRef": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "recipient": {
        "firstName": "Luke",
        "lastName": "Skywalker",
        "street": "Planetenstraße",
        "houseNumber": "13",
        "postalCode": "40223",
        "city": "Düsseldorf",
        "country": "DE"
    },
    "sender": {
        "street": "Carlsplatz",
        "houseNumber": "3",
        "postalCode": "40213",
        "city": "Düsseldorf",
        "country": "DE",
        "companyName": "ptdus",
        "resolvedCoordinates": {
            "lon": 6.77285093516085,
            "lat": 51.2263665950437
        },
        "emailAddresses": null,
        "additionalAddressInfo": null,
        "phoneNumbers": null,
        "resolvedTimeZone": {
            "offsetInSeconds": 3600,
            "timeZoneId": "Europe/Berlin",
            "timeZoneName": "W. Europe Standard Time"
        }
    },
    "dimensions": {
        "weight": 2000
    },
    "created": "2023-04-14T15:03:07.982Z",
    "lastModified": "2023-04-14T15:03:07.982Z"
}

This example shows the simplest way to create a parcel, where fulfillmenttools uses all necessary information from the corresponding shipment. However, it is possible to override data from the shipment for each created parcel, such as its dimensions, recipient, sender, or return address.

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.

Interpreting the result of a parcel request

Once the parcel status is DONE (successful) or FAILED, the result attribute contains the outcome.

Get parcel result
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/parcels/713b9cd8-6d47-45ff-a12a-ef3acb270180' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
{
    "loadUnitRefs": [],
    "version": 3,
    "id": "713b9cd8-6d47-45ff-a12a-ef3acb270180",
    "status": "DONE",
    "shipmentRef": "3e62db41-af9e-4ce1-8c44-1ef340457057",
    "processRef": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "result": {
        "summary": "",
        "carrierTrackingNumber": "222201010030668852",
        "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.

Download label
curl -sSL 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/parcels/713b9cd8-6d47-45ff-a12a-ef3acb270180/labels/all.pdf' \
  --header 'Authorization: Bearer <TOKEN>'

200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename=all.pdf

<binary data>

Note: The response has the Content-Type: application/pdf and contains binary data.

Requesting a special service from the carrier

If a special service is required, it can be requested when creating a parcel by passing the services object with the desired service set to true.

Create a parcel with a special service
curl -sSL -X POST 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/shipments/3e62db41-af9e-4ce1-8c44-1ef340457057/parcels' \
  --header 'Authorization: Bearer <TOKEN>'

201 Created
{
    "services": {
        "signature": true
        "bulkyGoods": true
    },
    "loadUnitRefs": [],
    "version": 1,
    "id": "713b9cd8-6d47-45ff-a12a-ef3acb270180",
    "status": "OPEN",
    "shipmentRef": "3e62db41-af9e-4ce1-8c44-1ef340457057",
    "processRef": "3af2e1a7-d104-4ef9-a43b-13890ae318cf",
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "recipient": {
        "firstName": "Luke",
        "lastName": "Skywalker",
        "street": "Planetenstraße",
        "houseNumber": "13",
        "postalCode": "40223",
        "city": "Düsseldorf",
        "country": "DE"
    },
    "sender": {
        "street": "Carlsplatz",
        "houseNumber": "3",
        "postalCode": "40213",
        "city": "Düsseldorf",
        "country": "DE",
        "companyName": "ptdus",
        "resolvedCoordinates": {
            "lon": 6.77285093516085,
            "lat": 51.2263665950437
        },
        "emailAddresses": null,
        "additionalAddressInfo": null,
        "phoneNumbers": null,
        "resolvedTimeZone": {
            "offsetInSeconds": 3600,
            "timeZoneId": "Europe/Berlin",
            "timeZoneName": "W. Europe Standard Time"
        }
    },
    "dimensions": {
        "weight": 2000
    },
    "created": "2023-04-14T15:03:07.982Z",
    "lastModified": "2023-04-14T15:03:07.982Z"
}

It is also possible to request services when creating an order. In the order payload, services can be listed for each entry in preferredCarriersWithProduct.

Create an order with a special service
curl --location --globoff '{{host}}/api/orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {authToken}' \
--data-raw '{
    "orderDate": "2023-03-11T08:16:07.000Z",
    "deliveryPreferences": {
        "shipping": {
            "preferredCarriersWithProduct": [
                {
                    "carrierKey": "BPOST",
                    "carrierServices": [
                        "SIGNATURE"
                    ]
                }
            ]
        }
    },
    "consumer": {
        "email": "[email protected]",
        "addresses": [
            {
                "salutation": "Dhr.",
                "firstName": "Jean",
                "lastName": "Peeters",
                "street": "Breidelstraat",
                "houseNumber": "2",
                "postalCode": "8000",
                "city": "Brugge",
                "country": "BE",
                "emailAddress": "[email protected]",
                "additionalAddressInfo": "637148",
                "phoneNumber": "526-640-7512",
                "addressType": "POSTAL_ADDRESS"
            }
        ]
    },
    "tenantOrderId": "FC-4711-2361",
    "status": "OPEN",
    "orderLineItems": [
        {
            "article": {
                "tenantArticleId": "2020249",
                "title": "T-Shirt \"Am Sonnenhut\"",
                "imageUrl": "https://d358g9injarr4u.cloudfront.net/res/product_1000/240eadd8-8f50-479d-b0d8-74412bd4a9f9.jpg",
                "attributes": [
                    {
                        "category": "miscellaneous",
                        "key": "BRAND",
                        "value": "Adidas"
                    },
                    {
                        "category": "descriptive",
                        "priority": 100,
                        "key": "%%subtitle%%",
                        "value": "Neu!"
                    },
                    {
                        "category": "descriptive",
                        "priority": 200,
                        "key": "Mitgliederpreis",
                        "value": "17,96 EUR"
                    },
                    {
                        "category": "descriptive",
                        "priority": 300,
                        "key": "Schnitt",
                        "value": "Frauen"
                    },
                    {
                        "category": "descriptive",
                        "priority": 400,
                        "key": "Material",
                        "value": "100% Baumwolle"
                    },
                    {
                        "category": "descriptive",
                        "priority": 500,
                        "key": "Artikelnummer",
                        "value": "2020249"
                    },
                    {
                        "category": "descriptive",
                        "priority": 600,
                        "key": "Größe",
                        "value": "S"
                    },
                    {
                        "category": "descriptive",
                        "priority": 700,
                        "key": "Beschreibung",
                        "value": "Rotes T-Shirt mit weißen Streifen an den Ärmeln, Blockdruck mit Schriftzug auf der Brust"
                    }
                ]
            },
            "quantity": 1,
            "scannableCodes": [
                "2020249"
            ]
        },
        {
            "article": {
                "tenantArticleId": "2010681",
                "title": "Steppjacke \"Mühlenbach\"",
                "imageUrl": "https://d358g9injarr4u.cloudfront.net/res/product_1000/9fcb7e42-7c84-4ab0-999a-869efe077e0a.jpg",
                "attributes": [
                    {
                        "category": "descriptive",
                        "priority": 100,
                        "key": "%%subtitle%%",
                        "value": "Neu!"
                    },
                    {
                        "category": "descriptive",
                        "priority": 200,
                        "key": "Größe",
                        "value": "L"
                    },
                    {
                        "category": "descriptive",
                        "priority": 300,
                        "key": "Oberstoff",
                        "value": "100% Polyester"
                    },
                    {
                        "category": "descriptive",
                        "priority": 400,
                        "key": "Futter",
                        "value": "100% Polyester"
                    },
                    {
                        "category": "descriptive",
                        "priority": 500,
                        "key": "Füllung",
                        "value": "100% Polyester"
                    },
                    {
                        "category": "descriptive",
                        "priority": 600,
                        "key": "Beschreibung",
                        "value": "Dreifarbige Steppjacke mit verstaubarer Kapuze, Zwei Eingriffstaschen, Gesticktes Logo auf der Brust"
                    },
                    {
                        "category": "descriptive",
                        "priority": 700,
                        "key": "Artikelnummer",
                        "value": "2010681"
                    }
                ]
            },
            "quantity": 1,
            "scannableCodes": [
                "2010681"
            ]
        },
        {
            "article": {
                "tenantArticleId": "5020064",
                "title": "Wandtattoo Stadion",
                "imageUrl": "https://d358g9injarr4u.cloudfront.net/res/product_1000/343f4569-66bb-4b0c-aa2b-20011a51b620.jpg",
                "attributes": [
                    {
                        "category": "descriptive",
                        "priority": 100,
                        "key": "Maße",
                        "value": "70 x 50 cm"
                    },
                    {
                        "category": "descriptive",
                        "priority": 200,
                        "key": "Beschreibung",
                        "value": "Wandtattoo in Ziegelwand-Optik, Mit tollem Blick aufs Stadion"
                    },
                    {
                        "category": "descriptive",
                        "priority": 300,
                        "key": "Anwendung",
                        "value": "Für die Beklebung sollte die Fläche staub- und fetfrei sein. Bringen Sie den Aufkleber in Position und reiben Sie diese gleichmäßig mit der flachen Hand an den Untergrund, um sie zu fixieren. Jede Stelle nochmals gest andrücken. Fertig! Für auftretende Schäden nach der Verklebung auf dem Untergrund etc. ist eine Haftung ausgeschlossen."
                    },
                    {
                        "category": "descriptive",
                        "priority": 400,
                        "key": "Artikelnummer",
                        "value": "5020064"
                    }
                ]
            },
            "quantity": 2,
            "scannableCodes": [
                "5020064"
            ]
        }
    ],
    "paymentInfo": {
        "currency": "EUR"
    }
}'

Only services offered by the chosen carrier are applied when creating a parcel. A request for a service that the carrier does not offer will be ignored.

Setting carrier URLs

The URLs for carrier APIs (e.g., sandbox or production endpoints) can be configured at different levels. Carrier-specific URLs can be set tenant-wide to apply to all facilities, or they can be overridden for specific facilities. Set the URLs by configuring either the carrier or the facility-carrier connection, as shown in the following sections.

Carrier-level URLs

Setting URLs at the carrier level applies them to every facility where that carrier is used. Use the following endpoint to set the configuration. The following example demonstrates how to set the serviceUrl and trackAndTraceUrl for a DHL carrier.

Set carrier-level URLs
curl -sSL -X PUT 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/carriers/<DHL-CARRIER-ID>/configuration' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "carrierRef": "488bd1a6-6c76-4407-8dab-ece716dac14d",
    "returnLabel": true,
    "version": 1,
    "serviceUrl": "https://api-sandbox.dhl.com/parcel/de/shipping",
    "trackAndTraceUrl": "https://api-eu.dhl.com/track/shipments"
}
'

Facility-carrier-level URLs

Setting URLs at the facility-carrier level overrides any URLs set at the carrier level for that specific facility. Update the configuration in the facility-carrier connection using the following endpoint. This example shows how to set the URLs for a GLS carrier.

Set facility-carrier-level URLs
curl -sSL -X PUT 'https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/facilities/<FACILITY-ID>/carriers/<CARRIER-REF>' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "status": "ACTIVE",
    "name": "GLS",
    "version": 1,
    "configuration": {
        "key": "GLS",
        "serviceUrl": "https://shipit-wbm-test01.gls-group.eu:443/backend/rs/shipments",
        "trackAndTraceUrl": "https://gls-group.eu/GROUP/en/parcel-tracking?match=",
        "trackAndTraceWsdlUrl": "http://www.gls-group.eu/276-I-PORTAL-WEBSERVICE/services/Tracking/wsdl/Tracking.wsdl"
    }
}
'

Non-delivery days

Non-delivery days can be configured for each carrier. This information is then used to calculate estimated delivery times and available delivery days. Non-delivery days can be specific calendar dates (e.g., 01/01/2025) or recurring weekdays (e.g., SUNDAY).

Non delivery days can be either specific calender dates (i.e. 01.01.2025) or weekdays (i.e. SUNDAY). While weekdays are always recurring (recurringNonDeliveryWeekdays), a specific calendar date can be set up as RECURRING or SINGLE by using the nonDeliveryType.

Last updated