Adding & connecting carriers to facilities

Carrier

GET list of available carriers
curl -sSL 'https://your.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 gives you a list of configured carriers, along with some general information and their key, which describes which kind of implementation is chosen by fulfillmenttools whenever this carrier is used to, for example, issue a label request or setup track and trace connection for a parcel. You can get a more detailed look at a configured carrier by requesting one identified carrier instance, for example:

Response
curl -sSL 'https://your.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 in any given fulfillmenttools platform. That means in general it can exist exactly once per tenant.

As you can see in the above response there are some configurations made to this exact carrier (DHL in this case). These configurations can be done on every carrier instance (check Add Carrier for details or continue reading.

Creation of a carrier

POST Create a carrier
curl -sSL -X POST 'https://your.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 you can see there are already some configurations to this carrier provided upon creation. Some of the interesting data is

Carrier specific configuration

Depending on the used Carrier implementation (depicted by the tag key) some additional configuration can be used to successfully operate a carrier:

Carrier specific configuration
curl -sSL 'https://your.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
} 

One of the most important configurations is the attribute returnLabel in a given configuration. It tells fulfillmenttools whether a return label should be created with every label requested from the given carrier.

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

Connection between a Facility and a Carrier

In the carrier services related use case a facility is a place where CEP services pick up parcels or interfacility transfers are started / finished.

Users can assign different carriers to one facility. With this information a fencing can be implemented where orders which need to be shipped by a chosen carrier are routed to a facility where this carrier is active. Carrier that are enabled on tenant level must also be enabled for the facilities in which this carrier is available.

The Facility-To-Carrier-Connection covers configurations that allow for frictionless carrier services. The connection covers, amongst others:

Connect an existing carrier to a facility

Let's assume that we have a facility (see Add and Manage Facilities) and a carrier (see Creation of a carrier) already created. Lets receive the correspondent entities first (omitting some of the attributes):

The Carrier
curl -sSL 'https://your.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"
    }
    ...
}
The Facility
curl -sSL 'https://your.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,
    ...
}

Please take note of two important parameters we are going to use in the following: The id of the facility (a81a1c85-cfe5-49d3-81d3-675154ef323e in this case) and the id of the carrier (488bd1a6-6c76-4407-8dab-ece716dac14d). We need both values in order to create a connection between those two entities.

The Connection

By using both values in our target URL the following call we configure the carrier to said facility:

Create connection
curl -sSL -X POST 'https://your.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"
}

The empty array of the attribute deliveryAreas indicates, that there are no restrictions regarding delivery targets.

We also set the cutoff time to 16:30, because in our fictive case this is the time when the DHL driver typically arrives at the Darkstore to pick up the parcels.

As long as the Carrier and the FacilityCarrierConnection stays in status "ACTIVE", it should be possible to create shipments and in the end also parcels using DHL as a CEP (see Create a shipment with parcels to track) originating from this facility.

Create a shipment with parcels to track

Before we dive into the process of sending a parcel we need to clarify two more entities: Shipment and Parcel.

Let's assume we already connected a Facility with a Carrier using a FacilityCarrierConnection (see Connect an existing carrier to a facility). In this use case we are going to create a standalone shipment and two parcels - without having a Pickjob or any other leading entity. This is a perfect example on how flexible fulfillmenttools is: There might be standard processes, but you are also able to use parts of the system to suit your operational needs - like for example the need of dynamically create a Shipment Label for further use in other systems.

Create Shipment for pickup in a facility and by a carrier

With the following call we create a shipment to be picked up in facility with ID 4fd70a59-9efe-40fd-808b-08ae86ca558f using the DHL Carrier with ID 488bd1a6-6c76-4407-8dab-ece716dac14d:

Create shipment
curl -sSL -X POST 'https://your.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
}

As you can see: The shipment has knowledge about the facility, the CEP and the address where to deliver.

As mentioned above: This shipment is not connected to any existing process! If you want to create a shipment to a specific process you need to provide the attribute processId within the request. Also shipments can be created during preceding processes. In that case data like the target address is provided via the order or the pickjob to the shipment which is created by fulfillmenttools.

Having the Shipment in place we are now ready to create a parcel via this shipment by issuing the following request:

Create a parcel via the shipment
curl -sSL -X POST 'https://your.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"
}

Please take note that we are issuing a parcel the most simple way in which fulfillmenttools will use all necessary information from the corresponding shipment. However, you are also able to overwrite certain data from the shipment for each created parcel, such as the dimensions, the recipient, the sender or return address.

We just created the entity that represents the parcel in status OPEN. Now, in an async matter, fulfillmenttools is automatically taking care of the actual advising of the parcel label. During the time it takes fulfillmenttools and the CEPs API to negotiate and create a parcel, the status of the parcel changes from OPEN via PROCESSING to finally DONE. The shipment also transparently changes its status to CONFIRMED as soon as all created parcels of the shipment reached the status DONE.

Interpreting the result of a parcel request

Once the parcel reached one of the status DONE (happy case) or FAILED it is time to take a look at the result attribute of the parcel:

Parcel results
curl -sSL 'https://your.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 in general shows details about the outcome of the request:

  • In case of a successful termination of the request towards this specific CEP API (see above) we can find the trackingNumber, a tracking URL, a label to download the sendLabel and also with the attribute labelUrl a document that consists of all the documents that are of importance to this parcel (such as for example deliveryNotes, return labels, etc.).

  • In case of a unsuccessful termination of the request the summary attribute carries information about the root cause of the failure. The contents of this error message usually originates from the carrier - fulfillmenttools has limited control about the data.

In this case we are ready to download the avised label using the following call:

Download label
curl -sSL 'https://your.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>

Be aware that the response has the Content-Type application/pdf and contains binary data.

Requesting a special service from the carrier

If a special is required, this can be requested either when creating a parcel by passing the service object with the desired service set to true:

Create a parcel with special service
// curl -sSL -X POST 'https://your.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 pass the information directly when creating an order. In the order the services can be directly listed for each preferredCarrierWithProducts:

Create an order with 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": "ulf.steinke@ocff.de",
        "addresses": [
            {
                "salutation": "Dhr.",
                "firstName": "Jean",
                "lastName": "Peeters",
                "street": "Breidelstraat",
                "houseNumber": "2",
                "postalCode": "8000",
                "city": "Brugge",
                "country": "BE",
                "emailAddress": "Jean.Peeters@yahoo.com",
                "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 will be taken when creating a parcel. Providing a service for a carrier which does not offer that service will be ignored.

Setting Carrier URLs

Whether you want to operate against sandbox URLs or against real URLs provided by CEPs can be configured on different levels.

You can set carrier specific URLs tenant-wide, so they are being used in every facility or you can decide to set URLs for specific facilities separately. In order to achieve this, set the URLs as shown in the following by setting the carrier configuration and/or the facility carrier configuration.

Carrier Level URLs

Setting the carrier URLs on carrier level will result in these URLs being used whenever this carrier is used in a facility. Use the following endpoint to set the URL.

The following example demonstrates how to set the service url and track and trace url for a DHL carrier.

Set the service url and track and trace url
curl -sSL -X PUT 'https://your.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 the carrier URLs on facility level will overwrite any URL that has been set on carrier level for the respective carrier. The URLs on facility carrier level can be set by updating the configuration in the facility carrier connection. The following endpoint can be used for this purpose.

This example shows how to set the urls for a GLS carrier.

Set the urls for a GLS carrier
curl -sSL -X PUT 'https://your.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

It is possible to set up “non-delivery-days” in the respective carrier configurations. The stored information is then taken into account when calculating delivery times and possible delivery days.

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