Implementing the Cargo Controller Import API

In this article we provide advice on how the Cargo Controller Import API can be implemented for your own system. This is explained step by step using use cases. Each use case provides insight into the logistical impact of sharing data via Cargo Controller Import. Do not miss any added value by implementing all data points in your own system.

This article is relevant for the project team delivering the implementation.

Tracking cargo

Cargo Controller Import (CCI) works with a RESTful API and Webhook (HTTPS calls). You can find the specifications here.

In the webhook updates we send the latest known status (state) of your cargo; the full B/L is shared. It is up to the recipient to compare the updates with our previous update to see which data has changed.

To track cargo successfully, a track request must contain at least 2 values: the master B/L number and at least 1 container number.

The master B/L number must include the SCAC code of the shipping line. If multiple containers are manifested under the B/L, we will automatically include these in our updates for all known containers.

Cargo tracking scenarios

There are 3 starting points for tracking cargo within CC, which trigger updates to be sent to the webhook. The date on which a track request is created is the month in which the paid transaction is invoiced.

The developer specifications are available on a separate website. In these blocks we refer to specific specifications related to a topic.

  1. A track request via a software package. In the image below, an elaboration of the happy flowTrack request via CC API in a happy flow, data is available.
  2. A web user tracks cargo manually in the CC web screen. In this situation, a unique trackid is sent to the webhook for which no track request has been sent. This scenario must be followed up:

    Track request via CC web, generates an unknown webhook update.

  3. A commercial release is linked to your organisation by third parties.
    This is almost identical to scenario 2. An external party links your organisation to the Secure Chain for a container whose B/L you are not yet tracking yourself.
    Secure Chain generates an unexpected CCI webhook update.
  4. Add the IMO number or CRN to your track request.
    For terminals that provide Premium Terminal Data, it can be useful to receive vessel data as early as possible. By including this data, it can be checked whether the vessel data is available earlier than the import manifest.
    Track cargo in CC with a CRN or IMO number, then webhook updates will already follow without a manifest.

Why am I not receiving cargo information yet?

The scenarios below assume an Extended tracking situation. If you would like to know more about this, please read this release note.

If cargo is being tracked, it may be that the cargo information is not yet known within Portbase. At that moment we register your request and automatically send an update back.

  1. Tracked BL: Cargo is tracked and cargo information is available within the PCS. Schematically, this looks as follows:

    Tracked BL status in CC API means that the manifest is available within PCS.

  2. Not tracked BL: Cargo is tracked and (as yet) no cargo information is available within the PCS. Schematically, this looks as follows:

    Not Tracked BL status in CC API means that the manifest is not (yet) available within PCS.

  3. Deleted BL: The cargo was subsequently removed from the manifest. Schematically, this looks as follows:

    Deleted BL status in CCI API means that the manifest has been modified and the cargo has been removed from the manifest.

Why do I receive a time-out email on behalf of the Cargo Controller Import API?

When tracking a B/L via CC, you receive a unique TrackId in the confirmation that links your organisation to this specific B/L. This way, you can easily link all our updates together in your own system.

When Cargo Controller Import shares an update, it is delivered to the webhook(s) registered under your organisation in the PCS. If Portbase does not receive a response within 30 seconds, we will make a second attempt and, if necessary, a third attempt.

If, after the third attempt, there is still no response to our update, we will send a time-out error message to the email address registered for the webhook (entered when you request the service): the webhook is not available and you may be missing important update(s) about your cargo.

Time-out errors: Tracking updates from the Cargo Controller Import API are offered up to a maximum of 3 times.

Implementation advice prevents time-out error messages

Experience shows that many organisations, after the first update, first activate their entire processing flow internally. Only after this process has been completed is a response sent to Portbase confirming receive of the webhook update.

Tracking update from the Cargo Controller Import API is answered immediately upon receipt after the first attempt.

Adjust email address for API error messages?

Requesting a change to the email address can be done via our Integration Services department.

Processing Premium Terminal Data via the API

To receive Premium Terminal Data, some terminals set additional requirements. For this additional data, always track using a CRN or IMO number of the vessel.

How do I receive Premium Terminal Data?

Read here all about which terminals offer this and the additional conditions they apply.

If the conditions are met, all new B/Ls are automatically provided with additional data. B/Ls from before that time are not updated.

Premium Terminal Data is part of our webhook updates. Read here more about our track requests.

Vessel voyage information (Vessel ETA/ETD)

Track the expected ETA and ETD of vessels as early as possible by tracking all your cargo with an IMO or CRN number.

The terminal ETA and ETD are shared in the object: billOfLading/visitDeclaration/portVisit/berthVisits

Example:

"vesselVisit": {
    "crn": "NLRTM21123456",
    "portOfCall": {},
    "vessel": {},
    "visitDeclaration": {
        "portVisit": {
            "berthVisits": [
                {
                  "berth": {},
                   "eta": "string",
                    "ata": "string",
                    "etd": "string",
                    "atd": "string",
                    "etaTerminal": "string",
                    "etdTerminal": "string"
                }
            ],
            "etaPort": "2021-02-28T05:45:00Z",
            "etdPort": "2021-02-30T07:30:00Z",
            "ataPort": "2021-02-28T05:45:00Z",
            "atdPort": "2021-02-30T07:30:00Z"
        }
    },
    "cancelled": false,
    "visitStatus": "DEPARTED"
},

Expected discharge time (Container EDT)

To receive an expected discharge time, it is necessary that an inland operator has been nominated. By your organisation or someone in the Secure Chain. Read here more about nominating via API.

The EDT is shared per container in the object: billOfLading/hinterlandTerminalData/expectedDischargeTime
Example:

"hinterlandTerminalData": [
    {
       "equipmentNumber": "CONT9434134",
       "expectedDischargeTime": "2021-02-28T07:45:00Z",
       "gateOut": "2021-02-28T07:45:00Z"
    }
],

Tracking customs inspections with the Cargo Controller Import API

Within the service Inspection Portal, notifications of inspections by Dutch Customs and covenant parties (ILT, NVWA, etc.) are passed on. The type of notification is shared in Cargo Controller Import per container in the object: billOfLading/inspectionItems

Example:

"inspectionItems": [
    {
        "equipmentNumber": "CONT9434134",
        "inspectionType": "PHYSICAL_OUTLET",
        "status": "NOTIFIED",
        "dateUpdated": "2021-02-26T07:45:00Z"
    }
],

If a notification is created, it is followed by a release (status released).

If no notification has been registered by Dutch Customs, no message will follow.

Receiving a commercial release

Above in the article, under the heading Tracking cargo, we describe in scenario 3 the tracking of cargo that is initiated by the Secure Chain.

Would you like to know more about the Secure Chain? Watch the introduction video.

There are 2 ways to be connected to the Secure Chain:

  1. The shipping line releases the cargo to your organisation.
    1. You now have the Release-to Party role. The Release-to Party role is unique; all other roles within the Secure Chain can occur multiple times.
    2. You now also have the Cargo Director role. Cargo directors are shown per container; per container this can be a different party.
  2. A chain partner releases the cargo to your organisation.
    1. You now have the Cargo Director role

The Secure Chain is part of our webhook updates. Read here more about our track requests.

Implementing Release-to Party

The Release-to Party role follows a commercial release per container; this is shared per container in the object: billOfLading/commercialReleases.

Example:

"commercialReleases": [
    {
      "equipmentNumber": "CONT9434134",
      "releaseToParty": {
        "name": "string",
        "scacCode": "string"
       },
       "releaseValidUntilDateTime": "2021-02-28T07:45:00Z"
    }
],

Implementing Cargo Director

The Cargo Director role follows a commercial release per container; this is shared per container in the object: billOfLading/cargoDirectors.

Example:

"cargoDirectors": [
  {
    "equipmentNumber": "CONT9434134",
    "name": "Cargo Director B.V.",
    "scacCode": "CD12"
  }
],

Withdrawing a commercial release

If the commercial release is withdrawn, you will receive a webhook update about this. Portbase shares this update by blanking the previously sent values (blank value).

That value will have to be reviewed per container. At that moment, contact must be made with the withdrawing party: the shipping line or the chain partner.

Implementation advice: review the release deadline

Commercial releases are often shared with a validity period. Perform a review in your own system to ensure that all planned actions still take place within this period.

  • Scenario 1: The commercial release is valid until 31-01-2026 23:59. The inland operator receives a transport order for 01-02-2026 12:00.
  • Scenario 2: Review every day at 08:00 which commercial releases have expired.

Passing on commercial releases

After receiving the commercial release, there are 2 possible choices:

  1. Your organisation appoints an inland operator (nominating Inland Operator)
  2. Your organisation appoints an (other) forwarder (appointing Cargo Director)

Implementation - nominating Inland Operator

An inland operator is nominated based on a unique EAN number. Your organisation must collect and manage that register itself for all your inland operators. Read here our CC API specifications for the technical information.

Read here the API specifications for nominating via a PUT request.

The Inland Operator role can be passed on per container, or for multiple containers. Confirmation follows only via the webhook updates; this is shared per container in the object: billOfLading/nominatedInlandOperators.

Example:

"nominatedInlandOperators": [
  {
    "equipmentNumber": "CONT9434134",
    "inlandOperatorFullName": "Transport B.V."
  }
]

Adjusting the Inland Operator role to another inland operator is easy to implement by performing the action again with a different EAN number.

Implementation advice: Nominating without an import manifest

Nominating is possible without an import manifest; in that situation you will have to supply all required (mandatory) information yourself to populate the nomination call.

Read here the API specifications for nominating via a PUT request.

Implementation - passing on the Cargo Director role

A Cargo Director is appointed based on a unique iAM Connected ID number or a Chamber of Commerce (KvK) number. Your organisation must collect and manage that register itself for all your chain partners.

The iAM Connected ID number of your chain partners can be requested via our Sales department. Please also state the reason for the request.

Read here the API specifications to appoint a Cargo Director via a PUT request.

The Cargo Director role can be passed on per container, or for multiple containers. Confirmation follows only via the webhook updates; this is shared per container in the object: billOfLading/cargoDirectors.

Example:

"cargoDirectors": [
  {
    "equipmentNumber": "CONT9434134",
    "name": "Cargo Director B.V.",
    "scacCode": "CD12"
  }
],

Adjusting the Cargo Director role to another chain partner is easy to implement by performing the action again with the other iAM Connected ID number or KvK number.

Withdrawing a commercial release

If the commercial release needs to be withdrawn, you can use 2 working methods:

  1. Withdrawing Cargo Director:
    1. Repeat the action but enter a blank value for the iAM Connected ID number or KvK number.
    2. Repeat the action (appointing or nominating) but enter the iAM Connected ID number or KvK number of your own organisation.
  2. Withdrawing Inland Operator:
    1. Repeat the action but enter a blank value for the EAN number.
    2. Repeat the action but directly enter a new value for the EAN number of an inland operator.

The outcome of these actions is confirmed via a webhook update. Read here more about our track requests.

Implementation advice: Nominating without an import manifest

Nominating is possible without an import manifest; in that situation you will have to supply all required (mandatory) information yourself to populate the nomination call.

Implementation advice: Release not passed on after x hours

Commercial releases that are not passed on delay the pickup process unnecessarily. Perform a review to check whether the commercial release has already been nominated or authorised within the chain.

Validate whether a Cargo Director or an Inland Operator has already been linked to your cargo.

Scenario: Your organisation received the Cargo Director role on 31-01-2026 23:59. Which cargo has not yet been passed on to an Inland Operator by 01-02-2026 08.00?

Monitoring Notification Import Documentation

Customers link the service Notification Import Documentation (NID) to the statuses they obtain via the service Cargo Controller Import. Read the implementation advice below to link these services optimally.

The added value of the Cargo Controller Import API is fully reading all available data. Read here more about our track requests and the available data fields.

The timely presence of a correct import document for the cargo is 1 of the 4 review points of a terminal. Without an import document, the cargo is not released. Submitting an import document is described as a NID notification.

Import Documentation status

The NID notification is returned per container in Cargo Controller Import. Confirmation follows via the webhook updates; this is shared per container in the object: billOfLading/transportEquipmentDeclarations.

Please note! 14 days after vessel arrival (ATA vessel) a NID notification can no longer be linked with CCI.

Example:

"transportEquipmentDeclarations": [
  {
    "equipmentNumber": "CONT9434134",
    "declarations": [
       "DIN"
    ]
  }
],

Implementation advice: ATA Container triggers NID notification (EDI)

Within the NID service there is no link with the manifest or gate out. Create a trigger in your own system that submits the NID notification at the moment that CC receives the discharge confirmation for the cargo.

The discharge confirmation is shared per container in the object: billOfLading/dischargeReports.

Example:

"dischargeReports": [
  {
    "equipmentNumber": "CONT9434134",
    "actualDischargeDateTime": "2021-02-28T07:45:00Z",
    "dischargeTerminal": {
        "code": 4810,
        "name": "AMALIAH APMT DSQ",
        "ownerFullName": "APM Terminals Maasvlakte II B.V.",
        "ownerShortName": "APMII"
     }
   }
],

Implementation advice: Warning 6 hours after ATA Container

Ensure a review mechanism within your own systems. Portbase offers an option via its web screens to send an email alert. If no NID notification has been submitted 6 hours after the discharge confirmation, then we send a warning by email.

You can set up this notification manually as a user in the web screen of Cargo Controller Import. For this, read the article Setting up email notifications in Cargo Controller Import You can also integrate this warning into your own systems.

Handling vessel diversions

When vessels are diverted, the discharge terminal is updated so that the vessel call (and manifest) has been updated by the shipping agent. If the POD changes because the vessel diverts at the last minute, it is necessary to catch this behaviour immediately. In your own systems, things such as the NID notification or transport orders may already have been sent.

Create a warning that reviews whether the POD changes after you have tracked it.

The POD is shared in the object: billOfLading/vesselVisit/dischargeTerminal.

Example:

"dischargeTerminal": {
    "code": 4810,
    "name": "AMALIAH APMT DSQ",
    "ownerFullName": "APM Terminals Maasvlakte II B.V.",
    "ownerShortName": "APMII"
},

Implementation advice: POD changes after NID notification

If the POD changes because the vessel diverts, it is necessary for the NID notification to be submitted at the new POD terminal. The existing NID notification at the previous POD must be withdrawn. Want to know more? Read the article Request to withdraw import document in Notification Import Documentation.

Create a warning in your system that reviews whether the POD changes while an import document was known. The POD is shared in the object: billOfLading/vesselVisit/dischargeTerminal.

Example:

"dischargeTerminal": {
    "code": 4810,
    "name": "AMALIAH APMT DSQ",
    "ownerFullName": "APM Terminals Maasvlakte II B.V.",
    "ownerShortName": "APMII"
},

Terminal pickup data

Within the Secure Chain, the pickup status has become available around the inland operator’s pre-notification at the terminal. From the moment that an Inland Operator has been nominated, a status request is requested from the terminal. This status reviews 4 values:

  1. Container present?
  2. Customs status?
  3. Import documentation status?
  4. Terminal status?

These 4 values are updated regularly when the inland operator updates the planning or the commercial release is adjusted.

The added value of the Cargo Controller Import API is fully reading all available data. Read here more about our track requests and the available data fields.

The pickup status is shared per container in the object: billOfLading/hinterlandPreNotifications.

This also shares what the last update moment was and the modality with which the cargo will be picked up.

Example:

"hinterlandPreNotifications": [
  {
    "equipmentNumber": "string",
    "dateUpdated": "string",
    "status": "DECLARED",
    "modality": "road",
    "plannedVisit": {
        "eta": "2021-02-28T09:45:00Z",
        "ata": "2021-02-28T08:45:00Z"
      },
    "equipmentStatus": {
        "acceptStatuses": [],
        "rejectReasons": []
      }
   }
],

Implementation advice: Identifying terminal reject reasons

Terminals provide the status of the 4 review points with every update. If a review point does not yet have the correct status, the terminal returns this specifically with a 'reject reason'. It may be valuable to monitor these values and trigger warnings within your own systems. Read here how this is shown within the web screens; this will provide context for the webhook updates.

Multiple reject reasons can be shared per review point. These are all shown in the web screens and in the webhook updates of CCI.

The reject reason is shared per container in the object: billOfLading/hinterlandPreNotifications/.../equipmentStatus/rejectReasons.

Examples of reject reasons:

  • If the container has not yet been discharged, the container will give a reject reason 'Container not present'. No action required.
  • If the NID notification has not been submitted, then the reject reason will be: 'Import document missing in Portbase, contact forwarder'. Action required.

Example:

"hinterlandPreNotifications": [
  {
    "equipmentNumber": "string",
    "dateUpdated": "string",
    "status": "DECLARED",
    "modality": "road",
    "plannedVisit": {
        "eta": "2021-02-28T09:45:00Z",
        "ata": "2021-02-28T08:45:00Z"
    },
    "equipmentStatus": {
        "acceptStatuses": [
            {
              "type": "AVAILABLE",
              "code": "string",
              "remark": "string"
             }
        ],
        "rejectReasons": [
            {
              "code": "string",
              "terminalDescription": "string",
              "parsedReason": "string"
            }
        ]
      } 
   }
],

Implementation advice: Terminal time slot

Not all terminals require a time slot or share a gate out. Within the container status, the time is also shared when an inland operator has a time slot at the terminal.

The pickup status is shared per container in the object: billOfLading/hinterlandPreNotifications/plannedVisit.

Example:

"plannedVisit": {
    "eta": "2021-02-28T09:45:00Z",
    "ata": "2021-02-28T08:45:00Z"
},

Related to

Was this article helpful?

0 out of 1 found this helpful