Language
+49 40 / 39 90 34 94 contact@herberg-systems.com

DIE ABOUT CARGO API –
DATENAUSTAUSCH LEICHT GEMACHT

Integrieren Sie die About Cargo-Funktionalität
schnell & einfach in Ihre eigene IT

DIE ABOUT CARGO API – DATEN­AUSTAUSCH LEICHT GEMACHT
Integrieren Sie die About Cargo-Funktionalität schnell & einfach in Ihre eigene IT

Die About Cargo API

Die About Cargo API ist eine Schnittstelle, mit der Sie alle Funktionen und Daten über eine REST-Schnittstelle abfragen können. Unsere API bietet Ihnen damit die Möglichkeit, die About Cargo-Funktionalität als Bestandteil Ihrer eigenen internen IT oder Ihrer Softwarelösung zu nutzen. Die About Cargo API ist eine Sammlung von HTTP RPC-Methoden, die die folgende Form haben: https://app.about-cargo.com/…

Die Methoden der About Cargo API erlauben Ihnen, berechnete Ankunftszeiten von Schiffen abzufragen und in Ihrer eigenen IT weiterzuverarbeiten. Das bedeutet, dass Sie die Daten in maschinenlesbarer Form mit unserem Service austauschen, ohne dass eine Benutzungsoberfläche aufgerufen werden muss.

Der Vorteil: Sie können die Daten für Ihre eigenen Zwecke digital weiterverarbeiten, ohne dass menschliche Interaktionen notwendig sind.

So können Sie zum Beispiel alle 10 Minuten abfragen, ob sich die Ankunftszeit eines Schiffes verschoben hat, und im Bedarfsfall den zuständigen Mitarbeiter mittels Ihrer IT informieren.

Die Abfrage der API erfolgt über das Internet, denn About Cargo ist ein Cloud Service. Um die API nutzen zu können, benötigt Ihr Client (die abfragende Seite) eine Internetverbindung über das HTTPS-Protokoll.

In welcher Sprache und mit welchen Werkzeugen Ihr Client implementiert wird, hängt von Ihrer internen IT-Struktur ab. Wenn Sie Microsoft Server oder Microsoft PCs verwenden, können Sie einen About Cargo API Client zum Beispiel in Microsoft DotNET entwickeln. Ein Beispiel finden Sie hier.

Wie funktioniert die API?

About Cargo ist ein Cloud Service, der regelmäßig aktuelle Schiffspositionen und weitere Informationen verarbeitet, um die Ankunfts- und Abfahrtszeiten eines Containerschiffes vorauszuberechnen. Das System verarbeitet die Positionen und stellt intern die aktuellen Ankunftszeiten in seiner Datenbank zur Verfügung. Der Client sendet eine Anfrage (Request) an das System und erhält als Antwort (Response) die Daten zurück. Das System berechnet keine feste Ankunftszeit eines Schiffes, sondern immer einen Erwartungshorizont. Ein Beispiel: Das Schiff MS Anna ist auf dem Weg von Santos (Brasilien) nach Rotterdam. Der Algorithmus berechnet folgende Werte:

Wahrscheinliche Ankunftszeit

Das ist die gemittelte wahrscheinliche Ankunftszeit, die sich aus der letzten Positionsmeldung ergibt. Beispiel: Das Schiff kommt am 12.7.2018 um 9:00 Uhr an.

Genauigkeit der Ankunftszeit

Dieser Wert gibt an, wie genau die Ankunftszeit berechnet wurde. Wenn z.B. die Genauigkeit 4 Stunden beträgt, liegt der Erwartungshorizont bei 12.7.2018 um 9:00 Uhr +/- 4 Stunden, also zwischen 5:00 und 13:00 Uhr.

Aktualität
der Ankunftszeit

Dieser Wert sagt etwas darüber aus, wie alt die Vorhersage ist. Beispiel: Ein Wert von 5 Stunden sagt aus, dass die Daten, die als Grundlage für die Bewertung dienen, 5 Stunden alt sind.

Früheste wahrscheinliche Ankunftszeit

Bei der frühesten wahrscheinlichen Ankunftszeit berechnet der Algorithmus, wann es das jeweilige Linienschiff frühestens gerade noch schaffen könnte.

Geplante Ankunfts- und Abfahrtzeiten

Das sind die Zeiten, die die Linienreederei auf ihrer Webseite veröffentlicht. Sie können diese Zeiten aber auch selbst über die API in das System übergeben, um einen Alarm zu erhalten, wenn ein Schiff sich verspätet.

Späteste wahrscheinliche Ankunftszeit

Dabei handelt es sich um die Zeit, die der Algorithmus im schlechtesten Fall als späteste Ankunftszeit des jeweiligen Linienschiffes errechnet.

So nutzen Sie die About Cargo API

Schritt 1: Authentifikationsprozess für den Zugang zur About Cargo API

Um auf die About Cargo-API zugreifen zu können, benötigen Sie zunächst einen Zugriffsschlüssel. Hierfür kontaktieren Sie gerne das Herberg Systems Team. Für Testzwecke können Sie auf kostenlose Zugänge zugreifen. Sie erhalten von uns einen Nutzernamen und ein Passwort, um einen sogenannten JWT Token zu beziehen und einen Zugang zur API zu bekommen.

Nach Erhalt der Nutzerdaten müssen folgende Schritte durchgeführt werden, um auf die About Cargo-API zuzugreifen:

  1. Der Client erfragt zunächst mit den Berechtigungsnachweisen (Benutzername, Kennwort) ein JWT Token.
  2. Wenn die Anmeldedaten gültig sind und der Nutzer berechtigt ist, auf die API zuzugreifen, wird ein JWT Token zurückgegeben.
  3. Der Client kann dann auf die About Cargo-API zugreifen. Hierfür muss der JWT Token in dem Request Header mit übergeben werden. Der JWT Token ist 3600 Sekunden gültig. 
  4. Wenn der JWT Token gültig ist, wird das Ergebnis der API-Anfrage an den Client zurückgesendet.
  5. Wenn eine API-Anfrage mit einem ungültigen JWT Token durchgeführt wird, erhält der Nutzer eine „401 – JWT token expired“ Meldung, also eine Benachrichtigung, dass der Token bereits abgelaufen ist. Nach dem Ablaufen des Tokens kann der Client einen neuen JWT Authentifikationstoken anfordern, wie unter Schritt 1 erklärt.

Nachfolgend werden die Schritte anhand von Beispielen erklärt:

1. Einen Token anfragen

Vor dem Abrufen der API fragt der Client einen JWT Token ab.

Hierfür muss er einen Post Request an die URL https://staging.about-cargo.com/api/token mit dem Content-Type application/json und dem Body {“username”:”<username>”, “password”:”<password>”} senden.

Bitte ersetzen Sie <username> und <password> mit den erhaltenen Anmeldedaten.

Beispielhafter Request für einen Token, der Curl benutzt:

curl -X POST "https://staging.about-cargo.com/api/token" -H "accept: application/json" -H "Content-Type: 
application/json" -d "{ \"username\": \"<username>\", \"password\": \"<password>\"}"

2. Beispielhafte Antwort eines Tokens

{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NDkxMTkzMDUsImV4cCI6MTU0OTEyMjkwNSwicm9sZXM
iOlsiUk9MRV9TVVBFUkFETUlOIiwiUk9MRV9VU0VSIl0sInVzZXJuYW1lIjoiU3VwZXJhZG1pbiJ9.pch9E7AOZPD-2hFxtgWVpdMw
l4fWWx2oknC8zDuQIMcajEXAtrKZGgCtbWxPwYDH9wrEswB66q3zC8BSDwsEloPXwfwP7f3tC7ZVNwRwb0Okdp6jTI46Fr3mTTKpOj
DGOwNKoj88FO8-ZYi_LUPIl2lKEWE5qkyTIzV3BVOOJdaOmvEknuIlJLxodwKIKLshk24npEwZhNEr_eCejFcyNoq-_gHpw9JPKILW
pMtKSrOHHcP6nrgxSFD6iYMyieWUevxohJ-j7g9rt3ITydP4t9udTtbSnXi9MbQriPYuSsygtraAcyId1Ii1QP7FigjitZgc9tXbzh
4-kCFyX28O2vT8D4zSQ12RPEO3Vm_3ZdivuOjYUKkSOMGYsjJrS9ySxyMzZqrsi_rX37VS2BqCYu5VRlNOIdxg_JwH1MJqrAoe_6SB
I9tFTltgfMnBjCBMvVmD5z5noGs0IzSmBOyiPYRJAR23A88BzONKf-ybgNWVKSzU0M4vZLjQtkCB_j8QbFsbyRk4gqpmog5FZzNgUO
9NFymPm5g3I3EuOoRJ_PzTCLxKbX5JdM6Y_8mOnrc-wsE7wOskK--DhgOiCZiI_Fwc9fCa2RscRDb0ph-N4QuVrs98yyA3mT3jC-i_
FvCzuY9SGiLHgblpa_BzcaacCTXEQnZ-PX_eqlp_1zjcSWY" }

3. Gebrauch des Tokens

Der Authentifikationstoken sollte bei jeder Anfrage bis zu dessen Ablauf genutzt werden. Der Token muss in jeder API-Anfrage nach dem Schlüsselwort Bearer im Autorisierungsheader enthalten sein. Eine Übersicht über alle möglichen API-Anfragen können Sie unter https://staging.about-cargo.com/api abfragen.


Beispielhafte API-Anfrage zum Abrufen aller Schiffe:

curl -X GET "https://staging.about-cargo.com/api/vehicles" -H "accept: application/json" -H "
Authorization:
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NDkxMTkzMDUsImV4cCI6MTU0OTEyMjkwNSwicm9sZXMiO
lsiUk9MRV9TVVBFUkFETUlOIiwiUk9MRV9VU0VSIl0sInVzZXJuYW1lIjoiU3VwZXJhZG1pbiJ9.pch9E7AOZPD-2hFxtgWVpdMwl4
fWWx2oknC8zDuQIMcajEXAtrKZGgCtbWxPwYDH9wrEswB66q3zC8BSDwsEloPXwfwP7f3tC7ZVNwRwb0Okdp6jTI46Fr3mTTKpOjDG
OwNKoj88FO8-ZYi_LUPIl2lKEWE5qkyTIzV3BVOOJdaOmvEknuIlJLxodwKIKLshk24npEwZhNEr_eCejFcyNoq-_gHpw9JPKILWpM
tKSrOHHcP6nrgxSFD6iYMyieWUevxohJ-j7g9rt3ITydP4t9udTtbSnXi9MbQriPYuSsygtraAcyId1Ii1QP7FigjitZgc9tXbzh4-
kCFyX28O2vT8D4zSQ12RPEO3Vm_3ZdivuOjYUKkSOMGYsjJrS9ySxyMzZqrsi_rX37VS2BqCYu5VRlNOIdxg_JwH1MJqrAoe_6SBI9
tFTltgfMnBjCBMvVmD5z5noGs0IzSmBOyiPYRJAR23A88BzONKf-ybgNWVKSzU0M4vZLjQtkCB_j8QbFsbyRk4gqpmog5FZzNgUO9N
FymPm5g3I3EuOoRJ_PzTCLxKbX5JdM6Y_8mOnrc-wsE7wOskK--DhgOiCZiI_Fwc9fCa2RscRDb0ph-N4QuVrs98yyA3mT3jC-i_Fv
CzuY9SGiLHgblpa_BzcaacCTXEQnZ-PX_eqlp_1zjcSWY"


4. Beispielhafte Antwort der API mit einer Liste aller Schiffe

[
{
"id": 1,
"name": "ship 1",
"alias": "",
"identifier": "9683867",
"isActive": true,
"updatedDate": "2018-10-25T10:54:00+00:00",
"createdDate": "2018-09-28T12:19:17+00:00",
"type": "/api/vehicle_types/1",
"carrier": "/api/carriers/6"
},
{
"id": 2,
"name": "Ship 2",
"alias": "",
"identifier": "9717228",
"isActive": true,
"updatedDate": "2018-10-25T10:53:58+00:00",
"createdDate": "2018-09-28T12:19:17+00:00",
"type": "/api/vehicle_types/1",
"carrier": "/api/carriers/6"
},
]
Schritt 2: Schiff aktivieren

Es gibt ca. 5000 Containerschiffe weltweit. Damit unser Service kostengünstig angeboten werden kann, bildet das System nur die Schiffe ab, die für Kunden relevant sind. Daher müssen Schiffe zunächst registriert und aktiviert werden. Daraufhin fragt das System die Positionen regelmäßig ab.

Der Client muss also zunächst ein Schiff registrieren, wenn dieses noch nicht im System hinterlegt ist. Sobald eine Position für das Schiff vorliegt, berechnet der Algorithmus auf Anfrage einen Erwartungszeitraum. Diesen kann der Client dann abfragen.

 

Folgend werden die Schritte für die Aktivierung beschrieben:

Zunächst muss festgestellt werden, ob das Schiff bereits registriert ist:

GET https://staging.about-cargo.com/api/vehicles?imoNumber=91234567

Wenn kein Datensatz zurückkommt, muss eine Registrierung für das Schiff erfolgen. Hierbei ist zunächst die ID des Carriers notwendig, zu dem das Schiff gehört:

GET https://staging.about-cargo.com/api/carriers

liefert z. B. zurück:

{
        "type_id": 1,
        "vehicle_ids": [
            591,
            1253
        ],
        "connection_ids": [
            2
        ],
        "id": 2,
        "name": "NYK",
        "is_active": true,
        "updated_date": null,
        "created_date": "2018-09-28T12:19:14+00:00"
    },

In diesem Fall fungiert der Carrier "NYK" und die dazugehörende ID "2" als Beispiel. Das Schiff wird wie folgt aktiviert:

HTTP POST https://staging.about-cargo.com/api/vehicles
{
"type_id": 1,
"carrier_id": 2,
"name": "MS Anna",
"identifier": "91234567"
}

Hierbei bedeutet type_id = 1, dass es sich um ein Seeschiff handelt. Der "identifier" ist die IMO Nummer des Schiffes.

 

Es kann sein, dass ein Schiff bereits im System registriert, aber noch nicht aktiviert ist. In diesem Fall müssen die folgenden Schritte ausgeführt werden.

Fragen Sie mit der IMO Nummer ein bestimmtes, bereits in der About Cargo API registriertes, Schiff ab:

GET https://staging.about-cargo.com/api/vehicles?imoNumber=91234567

Die Antwort könnte so aussehen:

[
{
"id": 1432,
"name": "MS Anna",
"alias": "Test 1",
"identifier": "99112233",
"isActive": false,
"activeUntil": "2019-01-31T00:00:00+00:00",
"updatedDate": "2019-01-12T10:11:13+00:00",
"createdDate": "2019-01-01T10:05:56+00:00",
"type": "/api/vehicle_types/1",
"carrier": "/api/carriers/3"
}
]

Das Attribut "isActive" gibt Auskunft über den Aktivierungsstatus des Schiffes. Derzeit ist das Schiff inaktiv.

Um es zu aktivieren, führen Sie diese Anfrage aus:

PUT https://staging.about-cargo.com/api/vehicles/1432

Im Body der Anfrage setzen Sie das Attribut "isActive" auf "true":

{
"isActive": true
}

Das Ergebnis ist die Aktivierung des Schiffes im System:

{
"id": 1432,
"name": "MS Anna",
"alias": "Test 1",
"identifier": "99112233",
"isActive": true,
"activeUntil": "2019-03-31T00:00:00+00:00",
"updatedDate": "2019-03-12T10:11:13+00:00",
"createdDate": "2019-01-01T10:05:56+00:00",
"type": "/api/vehicle_types/1",
"carrier": "/api/carriers/3"
}

Jetzt ist das Schiff im System aktiv.

Schritt 3: Den Berechnungsalgorithmus aufrufen

Für alle aktivierten Schiffe fragt das System regelmäßig die Position ab und berechnet auf Anfrage das ETA für den nächsten Hafen.

In diesem Szenario liefert der Client die Informationen über das Schiff und den nächsten Zielhafen, um direkt den Berechnungsalgorithmus aufzurufen. Hier wird immer nur die nächste Ankunftszeit berechnet.

GET https://staging.about-cargo.com/api/etas/calculate?imoNumber=91234567&unLoCode=BRIBB

liefert als Antwort den Erwartungshorizont für das Schiff mit der IMO Nummer 91234567 und den Hafen Imbituba in Brasilien:

{
    "id": 14,
    "eta_planned": null,
    "average": 1633,
    "minimum": 1410,
    "maximum": 1712,
    "median": 1598,
    "standard_deviation": 123,
    "accuracy": 246,
    "is_active": true,
    "updated_date": null,
    "created_date": "2018-10-26T15:51:07+00:00"
}

Alle Zeiten sind in Minuten. Das bedeutet folgendes:

Variable Wert Entspricht Bedeutung
average 1633 Minuten 27 Stunden 13 Minuten Durchschnittliche Dauer bis zur Ankunft
minimum 1410 Minuten 23 Stunden 30 Minuten Minimale Dauer bis zur Ankunft
maximum 1712 Minuten 28 Stunden 32 Minuten Maximale Dauer bis zur Ankunft
median 1598 Minuten 26 Stunden 38 Minuten Median der verschiedenen Werte bis zur Ankunft
standard_deviation 123 Minuten 2 Stunden 3 Minuten Standardabweichung bis zur Ankunft

In diesem Fall ist das ETA also 27 Stunden +/- 2 Stunden, wenn man den Durchschnitt nimmt, bzw. 26 Stunden, 38 Minuten +/- 2 Stunden, wenn man den Median zugrunde legt.

Ist das Schiff nicht aktiv, liegt keine Position vor oder kann es nicht dem Serviceleg zugeordnet werden, kommt eine entsprechende Fehlermeldung zurück.

Beispiel für einen REST-Client in C#

In diesem Abschnitt zeigen wir Ihnen wie Sie einen REST-Client in C# implementieren, mit dem Sie die About Cargo API anfragen können.

Die About Cargo Schnittstelle stellt die Daten im JSON-Format bereit. Die Klasse RestClient ruft die Schnittstelle auf und liefert die Daten als dynamic-Datenobjekt zurück.

 

Folgende Schritte sind nötig, um über einen REST-Client eine Anfrage stellen zu können:

  1. Zunächst müssen Sie eine neue Instanz erzeugen
  2. Daraufhin müssen Sie ein Token für die About Cargo API erfragen
  3. Danach kann der Rest-Client Daten von About Cargo anfragen

 

Wie erzeuge ich eine neue Instanz?

Der erste Schritt zum Erzeugen einer neuen Instanz ist:

RestClient client = new RestClient();

 

Wie erhalte ich ein Token?

Um ein Anmeldetoken zu erhalten, rufen Sie folgende Methode auf:

client.requestToken(<username>, <password>);

Hierbei müssen <username> und <password> durch Ihre eigenen Zugangsdaten ersetzt werden.
Nach erfolgreichem Aufruf ist der Token in dem Client-Objekt gespeichert.

 

Wie frage ich konkrete Daten ab?

Anschließend können Sie konkrete Daten über die Schnittstelle z. B. wie folgt aufrufen:

var objects = client.get("vehicles");


oder

var objects = client.get("etas/calculate?imoNumber=91234567&unLoCode=DEHAM");


Beispielcode für den REST-Client in C#

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Web.Helpers;
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Web.Helpers;

namespace AboutCargoTrial
{
    /// <summary>
    /// This is a sample implementation for a REST client that is able to access 
    /// the AboutCargo API described at www.about-cargo.com.
    /// </summary>
    public class RestClient
    {
        /// <summary>
        /// The URL
        /// </summary>
        public string Url { get; set; }
        
        /// <summary>
        /// The JWT Token
        /// </summary>
        public string AccessToken { get;set; }
        
        /// <summary>
        /// Constructor
        /// Contains the fixed URL to the test instance base URL.
        /// </summary>
        public RestClient()
        {
            Url = "https://staging.about-cargo.com/api/";
        }
        
        /// <summary>
        /// Get data from the API.
        /// </summary>
        /// <param name="methodStr">The API method to be called</param>
        /// <returns>A dynamic object or null.</returns>
        public dynamic get (string methodStr)
        {
        	// define URI by adding the method to be called to the base URL
            var myUri = new Uri(new Uri(Url), methodStr);
            
            // configure request object to use the JWT access token
            var myWebRequest = WebRequest.Create(myUri);
			var myHttpWebRequest = (HttpWebRequest)myWebRequest;
			myHttpWebRequest.PreAuthenticate = true;
			myHttpWebRequest.Headers.Add("Authorization", "Bearer " + AccessToken);
			myHttpWebRequest.Accept = "application/json";
            
            // prepare sink for responses
            var myWebResponse = myWebRequest.GetResponse();
            var responseStream = myWebResponse.GetResponseStream();
            if (responseStream == null) {
                return null;
            }
            
            // read the complete JSON response
            var myStreamReader = new StreamReader(responseStream, Encoding.Default);
            var json = myStreamReader.ReadToEnd();
            
            // clean up
            responseStream.Close();
            myWebResponse.Close();
            
            // decode JSON response and return the result
            dynamic data = Json.Decode(json);
            return data;
            
        }
        
        /// <summary>
        /// Retrieve a JWT Token for login.
        /// </summary>
        /// <param name="username">The user name</param>
        /// <param name="password">The password</param>
        public void requestToken (string username, string password)
        {
        	// define URI for getting the JWT token
            var myUri = new Uri(new Uri(Url) , "token");
            
            // configure request object to get the JWT access token
            var myWebRequest = (HttpWebRequest) WebRequest.Create(myUri);
            myWebRequest.ContentType = "application/json";
            myWebRequest.Accept      = "application/json";
            myWebRequest.Method      = "POST";

            // create a request stream containing user name and password
            using (var streamWriter = new StreamWriter(myWebRequest.GetRequestStream()))
            {
                string json = "{\"username\": \""+username+"\"," + "\"password\": \""+password+"\"}";

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }

            // prepare sink for the response
            var httpResponse = (HttpWebResponse) myWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
            	// read complete response
                string jsonResult = streamReader.ReadToEnd();
                
                // decode JSON response and grab the token
                dynamic data = Json.Decode(jsonResult);
                AccessToken = data.token;
            }
            
        }
    }
}

 

© All rights reserved