API – Reference

API Reference

Cargo Spectre can seamlessly integrate into your existing warehouse
management software. Our API is simple to use and available at NO COST
to any Cargo Spectre customer.

OVERVIEW

Our API uses HTTP REST/SOAP. It is not encrypted, and should only be used in local networks if message
privacy is important. The default port used is 7100, although it is configurable in the config.xml.
Requests are made as either a POST or GET request to the server’s IP address on the specified port. The server responds with either XML or binary data in the case of a file request.

URL Endpoints

Cargo Spectre uses localhost (port 7100 by default) for all API calls, but does need access to certain external addresses for the following services:

URL Service
https://*.spectre-licensing.com

Licensing and optional cloud storage of cargo data

  • Main licensing server
  • Primary backup
  • Secondary backup (only during outages)
https://*.ubuntu.com
https://*.launchpad.net
Updates
https://spectre-support.centralus.cloudapp.azure.com Client version updates and support
https://*.teamviewer.com Remote support

POST Requests

Input Format

A POST request should contain a body with XML containing the list of requested actions.

<Requests>
	<ApiName>
		<ApiInputTree>
	</ApiName>
	<AnotherApiName/>
</Requests>

We can request multiple API calls at a time, duplicates included. They will be executed in order, but keep in mind that a blocking SOAP call will take longer with more API calls. Note: In the below example, Snapshot does not happen until Dimension is completed. After both Dimension and Snapshot are completed, the server returns the results of both in the output format.

<Requests>
	<Dimension/>
	<Snapshot/>
</Requests>

Output Format

<Responses>
	<ApiName code="0">
		<ApiOutputTree>
	</ApiName>
	<ApiName code="5" description="some error"/>
</Responses>

For each API request, there will be a corresponding response tree. Each response is accompanied by an error code attribute. An error code of 0 means the call was successful.

Example output:

<Responses> 
	<Dimension code="0"> 
		<Info> 
			<Dimensions> 
				<Length>60.5</Length>
				<Width>60.5</Width>
				<Height>61.0</Height>
				<Volume>223275.000</Volume>
				<Weight> 
					<Net>100</Net>
					<Gross>150</Gross>
					<Tare>50</Tare>
				</Weight>
				<Barcode>123456</Barcode>
			</Dimensions>
			<Units> 
				<Length>Inches</Length>
				<Volume>Cubic Feet</Volume>
				<Weight>lb</Weight>
			</Units>
		</Info>
	</Dimension>
	<Snapshot code="0"> 
		<Directory> 
			<Clouds> 
				<Path>Jun-13_09-24-36_2016/073340441047-raw.pcd</Path>
			</Clouds>
			<Images> 
				<Path>Jun-13_09-24-36_2016/color-image0.png</Path>
			</Images>
			<Xmls> 
				<Path>Jun-13_09-24-36_2016/info.xml</Path>
			</Xmls>
		</Directory>
	</Snapshot>
</Responses>

That is the expected response for a requests that calls for a Dimension action followed by a Snapshot action.

Additional Example Request:

POST http://192.168.1.169:7100 with the following body:

<Requests>
	<Ping/>
</Requests>

Example Response:

<Responses>
	<Ping code="0">
</Responses>

GET Requests

Input Format

Every API call that can be specified with POST can also be sent through GET. The GET call does the same thing as POST but converts it to a single request without any inputs. Some API calls will return errors if used in this way if they require inputs to do something.

Note: API actions (/file, /dimension, /settings, etc) should all be lowercase.

Example:

http://ip_address:7100/dimension

Clients can retrieve specific files from the machine through GET calls. The Snapshot API, for instance, returns paths to various different data files for a particular piece of freight. You can use GET with a prepended “/file” to grab such files. Files can only be retrieved from within the “~/Cargo-Spectre” directory and no files outside of that will be accessible through this method.

Example:

http://ip_address:7100/file/Jun-13_09-24-36_2016/color-image0.png

Output Format

Output for GET requests is the same as for POST requests. See Output format above.


Current API List

<Dimension>

Reports the dimensions, and volume of the object. May also include the weight and barcode of the object if applicable. Additionally, the barcode may be optionally supplied as part of a Dimension POST command and will be reported along with the dimensions.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<Dimension/>
</Requests>

POST with Barcode – Body:

<Requests>
	<Dimension>
		<Barcode>14232<Barcode/>
	<Dimension/>
</Requests>

Example GET Request:

GET http://192.168.1.114:7100/Dimension

Example Response:

<Responses>
	<Dimension code="0">
		<Info>
			<Dimensions>
				<Length>34.2</Length>
				<Width>27.9</Width>
				<Height>34.2</Height>
				<Volume>32851.964</Volume>
				<Weight>
					<Net>0</Net>
					<Gross>0</Gross>
					<Tare>0</Tare>
				</Weight>
				<Barcode>14232</Barcode>
			</Dimensions>
			<Units>
				<Length>centimeters</Length>
				<Volume>cubic centimeters</Volume>
				<Weight>kilograms</Weight>
			</Units>
			<Scanner>
				<Mode/>
			</Scanner>
		</Info>
	</Dimension>
</Responses>

<Snapshot>

Saves reported dimensions along with images, clouds, and other metadata.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<Snapshot/>
</Requests>

Example GET Request:

GET http://192.168.1.114:7100/Snapshot

Example Response:

<Responses>
	<Snapshot code="0">
		<Directory>
			<Misc>
				<Path>Jul-6_21-25-32_2018/Freight-Report.pdf</Path>
			</Misc>
			<Clouds>
				<Path>Jul-6_21-25-32_2018/005337361647-raw.pcd</Path>
				<Path>Jul-6_21-25-32_2018/combined-raw.pcd</Path>
				<Path>Jul-6_21-25-32_2018/005302461647-raw.pcd</Path>
				<Path>Jul-6_21-25-32_2018/box.pcd</Path>
			</Clouds>
			<Images>
				<Path>Jul-6_21-25-32_2018/color-image1.png</Path>
				<Path>Jul-6_21-25-32_2018/color-image0.png</Path>
				<Path>Jul-6_21-25-32_2018/PDFImage.png</Path>
			</Images>
			<Xmls>
				<Path>Jul-6_21-25-32_2018/info.xml</Path>
			</Xmls>
		</Directory>
	</Snapshot>
</Responses>

<File>

API that retrieves the specified file within the specified folder. Only files within the “~/Cargo-Spectre” directory may be retrieved with this method – no other files on the system will be accessible. Thus, for the example below, the following file in the following path is retrieved on the specified machine: “~/Cargo-Spectre/SnapshotFolder_DateTime/Freight-Report.pdf”.

Example GET Request:

GET http://192.168.1.114:7100/File/SnapshotFolder_DateTime/Freight-Report.pdf

<Ping>

Simple API that always returns success.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<Ping/>
</Requests>

Example GET Request:

GET http://192.168.1.114:7100/Ping

Example Response:

<Responses>
	<Ping code="0"/>
</Responses>

<SetBarcode>

Sets the barcode value of the item to be scanned. This will allow, e.g., the “Dimension” API call to return the barcode as part of its response.

Please note: This will only affect the very next scan – it cannot be applied retroactively to just-performed scans.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<SetBarcode>
		<Value>123ABC</Length>
	</SetBarcode>
</Requests>

Example Response:

<Responses>
	<SetBarcode code="0"/>
</Responses>    

<ReportError>

If a piece has a questionable scan, it’s possible to report an error to us. This will upload the previous scan’s data to our cloud (including your calibration) where we can investigate what may have happened. Such cases can also be added to our regressions to better ensure accuracy in future versions. When using this reporting tool, we ask you to measure the cargo by an alternative method and then provide us with the measured: Length, Width, and Height (using the unit of measurement that your Cargo Spectre is set to).

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<ReportError>
		<Length>30.0</Length>
		<Width>20.0</Width>
		<Height>40</Height>
	</ReportError>
</Requests>

Example Response:

<Responses>
	<ReportError code="0"/>
</Responses>    

<SetSetting>

Sets custom settings for the server to use. You can use this to modify settings such as a machine name or the measurement units.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<SetSetting>
		<Path>/Settings/Device/Name</Path>
		<Value>Loading Dock</Value>
	</SetSetting>
</Requests>

Example Response:

<Responses>
    <SetSetting code="0"/>
</Responses>
Paths (case sensitive) Accepted values (case sensitive) Description
/Settings/Device/Name <any string> Human-readable name for a particular machine
/Settings/Device/Scale/Format Totalcomp Continuous Format | FB1100 Continuous Format | Rice Lake Continuous Format | CI200 Continuous Format Scale data format
/Settings/Device/Scale/Baud 9600 | 14400 | 19200 | 28800 | 38400 | 56000 | 57600 | 115200 Baud rate for an attached scale
/Settings/Device/Scale/Parity 8 data bits, no parity bit, 1 stop bit | 7 data bits, even parity bit, 1 stop bit | 7 data bits, odd parity bit, 1 stop bit Communication information for an attached scale
/Settings/Device/Scale/Ntep <any string> The NTEP certification number for the attached scale
/Settings/Printing/Pdf true | false Generates a freight report PDF when enabled
/Settings/Printing/Logo <a string that is a valid file path to an image> A file path for a company logo to be displayed on freight reports
/Settings/RemoteApi/Port <any integer in range 1024-49151> Port number
/Settings/Scanner/Mode Cargo | Parcel Scanning mode. Select “cargo” for two camera operation, and “parcel” for one camera.
/Settings/Scanner/Upload Never | When saving  Uploads scans to cloud storage
/Settings/Snapshot/Images/Format jpg | png The file format to save images in
/Settings/Units/Length millimeters | centimeters | meters | inches | feet Length measurement unit for dimensions
/Settings/Units/Volume cubic millimeters | cubic centimeters | cubic meters | cubic inches | cubic feet Volume measurement unit
/Settings/Units/Weight kilograms | lb Weight measurement unit

<GetSetting>

This retrieves the value of any setting set either through the Cargo Spectre settings menu or the <SetSetting> command detailed above.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<GetSetting>
		<Path>/Settings/Units/Length</Path>
	</GetSetting>
</Requests>

Example Response:

<Responses>
	<GetSetting code="0"/>
		<Length>centimeters</Length>
	</GetSetting>
</Responses>

Example GET Request:

GET http://192.168.1.114:7100/GetSetting

Example Response (GET, or POST with no path specified):

<Responses>
	<GetSetting code="0">
		<Settings>
			<Device>
				<Name>000000000000</Name>
				<Scale>
					<Format>Totalcomp Continuous Format</Format>
					<Baud>9600</Baud>
					<Parity>8 data bits, no parity bit, 1 stop bit</Parity>
					<Height>0</Height>
					<HeightUnit>0</HeightUnit>
				</Scale>
			</Device>
			<Scanner>
				<Mode>Cargo</Mode>
			</Scanner>
			<Units>
				<Length>centimeters</Length>
				<Volume>cubic centimeters</Volume>
				<Weight>kilograms</Weight>
			</Units>
			<Support>
				<Running>true</Running>
				<Sample>
					<Tag>2018-02-26T05:17:06</Tag>
					<Count>0</Count>
				</Sample>
				<LoginPrompt>false</LoginPrompt>
			</Support>
			<Calibration>
				<Crash>false</Crash>
				<Path>~/.spectre/Jul-6_21-23-31_2018</Path>
			</Calibration>
			<RemoteApi>
				<Port>7100</Port>
			</RemoteApi>
		</Settings>
	</GetSetting>
</Responses>

<GetErrorStatus>

This returns the last status code set by the Cargo Spectre server, whether error or success.

Example POST Request:

POST http://192.168.1.114:7100

Body:

<Requests>
	<GetErrorStatus/>
</Requests>

Example GET Request:

GET http://192.168.1.114:7100/GetErrorStatus

Example Response:

<Responses>
	<Ping code="0"/>
</Responses>

Cloud Server

The cloud server is separate from the other Cargo Spectre API calls and uses a different endpoint. Endpoint: http://spectre-licensing.com

Matchmaking

The matchmaking API will return a list of all Cargo Spectre devices that have successfully checked out a license using your credentials. You can manually view these records at http://spectre-licensing.com.
Endpoint: POST http://spectre-licensing.com/matchmaking/list

JSON (default)

Request example (included in the POST body):

{
    "email": "fake@company.com",
    "password": "FakePassword123!"
}

Response example:

{
  "matches": [
    {
      "publicIP": "100.150.162.60",
      "localIP": "192.168.1.100:321",
      "macAddress": "bbb156d2651f",
      "machineName": "Dock 5",
      "lastUpdated": "2016-12-18T13:57:14.777059"
    },
    {
      "publicIP": "",
      "localIP": "127.0.0.1:7100",
      "macAddress": "f46d04698d",
      "machineName": "Receiving Bay",
      "lastUpdated": "2016-11-20T16:21:07.8148707"
    },
    {
      "publicIP": "48.78.4.91",
      "localIP": "192.168.1.197:7100",
      "macAddress": "742f681c2d",
      "machineName": "Departure Scanner",
      "lastUpdated": "2016-11-20T15:16:27.4377527"
    }
  ],
  "error": null
}

XML

Note: to receive XML back, the request must specify the Accept header with the value set to application/xml otherwise the response will be returned in JSON.

Request example:

<MatchmakingRequest>
	<Email>fake@company.com</Email>
	<Password>FakePassword123</Password>
</MatchmakingRequest>

Response example:

<MatchmakingResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<Matches>
		<Match>
			<PublicIP>100.150.162.60</PublicIP>
			<LocalIP>192.168.1.100:321</LocalIP>
			<MACAddress>bbb156d2651f</MACAddress>
			<MachineName>Dock 5</MachineName>
			<LastUpdated>2016-12-18T13:57:14.777059</LastUpdated>
		</Match>
		<Match>
			<PublicIP>8.211.81.5</PublicIP>
			<LocalIP>127.0.0.1:7100</LocalIP>
			<MACAddress>f46d04698d</MACAddress>
			<MachineName>Receiving Bay</MachineName>
			<LastUpdated>2016-11-20T16:21:07.8148707</LastUpdated>
		</Match>
		<Match>
			<PublicIP>48.78.4.91</PublicIP>
			<LocalIP>192.168.1.197:7100</LocalIP>
			<MACAddress>742f681c2d</MACAddress>
			<MachineName>Departure Scanner</MachineName>
			<LastUpdated>2016-11-20T15:16:27.4377527</LastUpdated>
		</Match>
	</Matches>
</MatchmakingResponse>

Search by Barcode

The Search Request API will return a cargoID and scanDate based on an inputted barcode parameter. Endpoint: POST http://spectre-licensing.com/api/cargo/search

JSON Request Example (included in the POST body):

{
    "email": "fake@company.com",
    "password": "FakePassword123!",
    "barcode": "12341234"
}


Note: to receive XML back, the request must specify the Accept header with the value set to application/xml otherwise the response will be returned in JSON.

XML Request Example:

<SearchRequest>
	<Email>fake@company.com</Email>
	<Password>FakePassword123</Password>
	<Barcode>12341234</Barcode>
</SearchRequest>

JSON Response Example:

{
    "searchResults": [
        {
            "barcode": "12341234",
            "cargoID": 11111,
            "scanDate": "yyyy-mm-ddT00:00:00"
        }
    ],
    "error": null
}

JSON Exporting

Cargo Spectre users can export cargo data from the cloud using the JSON Export feature. There are two ways to export cargo data:

In order to export from the cloud, you will need to provide a URL endpoint that accepts HTTP POST requests. Cargo Spectre users have the ability to set a different URL for each Cargo Spectre device, so you may want to have a few different URL paths. For example:

Exported from URL
Customer 1, Machine A https://my-company-name.com/customer-1/machine-A
Customer 1, Machine B https://my-company-name.com/customer-1/machine-B
Customer 2, Machine A https://my-company-name.com/customer-2/machine-A

The exported JSON will take the following format (excluding the comments):

{
  "responses": {
    "dimension": {
      "code": 0, // Number - Anything besides 0 indicates an error has occurred
      "info": {
        "cargoID": 43286, // Number - Internal Cargo Spectre ID
        "name": "", // String - Optional cargo name
        "barcode": "FAKEBARCODE123", // String
        "comments": "Comments are optional and can be left blank. This is what we will use for Estes PRO", // String
        "scanDate": "2018-11-16T03:49:18", // String - UTC time in ISO format
        "machineName": "Laptop", // String - Human readable name of the Spectre machine that authored the data
        "scanGuid": "3a75b02a-9300-4ba4-a117-87869dc14e9a", // String - This may be used in future sharing scenarios
        "dimensions": {
          "length": 0.81, // Number
          "width": 0.54, // Number
          "height": 0.55, // Number
          "volume": 0.247132, // Number
          "weight": {
            "net": 75.5, // Number
            "gross": 76.5, // Number
            "tare": 1.5 // Number
          },
        },
        "units": {
          "length": "meters", // String - Applies to Length, Width, and Height
          "volume": "cubic meters", // String - Applies to Volume
          "weight": "lb" // String - Applies to Net, Gross, and Tare
        }
      }
    },
    "snapshot": {
      "code": 0, // Number - Anything besides 0 indicates an error has occurred
      "directory": { // All path values are relative to: https://cargospectre.blob.core.windows.net/scans/
        "clouds": {
          "path": [ // Array of strings - Point cloud 3D models of the scene
            "fake@shipper.com\\f2222139-ca9a-4c4a-8f44-e144455f0721\\combined-raw.pcd",
            "fake@shipper.com\\f2222139-ca9a-4c4a-8f44-e144455f0721\\box.pcd"
          ]
        },
        "images":{
          "path": [ // Array of strings - Images of the cargo
            "fake@shipper.com\\f2222139-ca9a-4c4a-8f44-e144455f0721\\color-image0.jpg"
          ]
        },
        "thumbnails": {
          "path": [ // Array of strings - Same as the images above just smaller (for faster loading if needed)
            "fake@shipper.com\\f2222139-ca9a-4c4a-8f44-e144455f0721\\thumbnail\\color-image0.jpg"
          ]
        },
        "misc": {
          "path": [ // Array of strings - Freight reports or other cargo documents
            "fake@shipper.com\\f2222139-ca9a-4c4a-8f44-e144455f0721\\Freight-Report.pdf"
          ]
        }
      }
    }
  }
}

Additional notes

  • After retrieving the JSON, you may make subsequent network calls the the images and files hosted in cloud storage and download them.
  • If your customer has multiple cameras or Kinects plugged in, there will be additional images and thumbnails in their respective path arrays.

Proxy Server

The proxy server provides a simple way to access any Cargo Spectre device without having to worry about local network configurations. The proxy server URL is: https://proxy.spectre-licensing.com

API differences

Sending API requests via the proxy server is similar to the normal API, but with the following differences:

  • Requests are sent to https://proxy.spectre-licensing.com/api instead of a given Spectre’s IP address.
  • All requests must include a Basic Authorization Header.
  • Requests will also need to include the name of the machine to send the request to.

Example 1

A request to dimension using a Spectre named “ATL Pallet Scanner” would look like this:

GET https://proxy.spectre-licensing.com/api/ATL%20Pallet%20Scanner/dimension
Authorization Basic ZG9ja01hbmFnZXJAZmFrZUxvZ2lzdGljcy5jb206eW91clBhc3N3b3JkSGVyZQ==

Notice how:

  • The machine name was URL encoded and spaces in the name were each converted to “%20”
  • The Authorization header was constructed by converting “dockManager@fakeLogistics.com:yourPasswordHere”to base 64

Example 2

A request to dimension and then immedately snapshot using a Spectre named “Receiving Bay #3” would look like this:

POST https://proxy.spectre-licensing.com/api/Receiving%20Bay%20%233
Authorization Basic ZG9ja01hbmFnZXJAZmFrZUxvZ2lzdGljcy5jb206eW91clBhc3N3b3JkSGVyZQ==
<Requests>
  <Dimension/>
  <Snapshot/>
</Requests>

Example 3

A request to download an image file named “color-image1.jpg” using a Spectre named “LGB-Dock-5” would look like this:

GET https://proxy.spectre-licensing.com/api/LGB-Dock-5/file/color-image1.jpg
Authorization Basic ZG9ja01hbmFnZXJAZmFrZUxvZ2lzdGljcy5jb206eW91clBhc3N3b3JkSGVyZQ==