Language

HATs in the ecosystem report aggregated metadata about their data operations to DEX. Specifically, they report how many of specific values have been sent to the HAT by Data Plugs, as well as how many have been retrieved from the HAT with Data Debits. Furthermore, since Data Debits are the mechanism for third-parties to request data from the individual, they also report operations on Data Debits: creation, removal, enabling and disabling. This allows DEX to monitor commercial data exchanges for security, quality assurance and trust.

Collecting available statistics

Current DEX statistics lookup for all available data points is a single, public (no authentication required) API call:

curl --request GET \
  --url https://dex.hubofallthings.com/stats
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://dex.hubofallthings.com/stats");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://dex.hubofallthings.com/stats",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://dex.hubofallthings.com/stats"

response = requests.request("GET", url)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://dex.hubofallthings.com/stats")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body

Which responds with aggregated statistics:


HTTP/1.1 200 OK
Content-Type: application/json


[
  {
    "title": "Data Plugs",
    "value": 7,
    "updated": 1496407712243
  },
  {
    "title": "Total Offer Claims",
    "value": 70,
    "updated": 1496407712248
  },
  {
    "title": "Data Out",
    "value": 24317796,
    "updated": 1496407712246
  },
  {
    "title": "Data In",
    "value": 3118189,
    "updated": 1496407712239
  },
  {
    "title": "Top Datapoints",
    "value": 17476332,
    "children": {
      "longitude in locationv1 of rumpel": {
        "title": "longitude in locationv1 of rumpel",
        "value": 607523,
        "updated": 1496407713864
      },
      "...": "..."
    },
    "updated": 1496407713864
  },
  {
    "title": "HATs",
    "value": 387,
    "updated": 1496407712236
  }
]

Retrieving data points available in HATs

The HAT store is very flexible in what data it accepts via its APIs for storage to limit the amount of setup required before a developer can start storing data in it, however that also means it may not be easy for others to find out what data is available for exchange. Therefore, DEX processes all incoming metadata to aggregate available data properties:

curl --request GET \
  --url https://dex.hubofallthings.com/stats/available-data
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://dex.hubofallthings.com/stats/available-data");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://dex.hubofallthings.com/stats/available-data",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://dex.hubofallthings.com/stats/available-data"

response = requests.request("GET", url)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://dex.hubofallthings.com/stats/available-data")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body

The full response can be rather long, so an example is included on a separate page.

Describing availalbe data

While the list of available data is very detailed, human-beings need proper, textual descriptions of what those data points are to be able to use them in meaningful ways. While it is not possible to derive a description just from the fact that a specific datapoint is being exchanged, DEX provides means to add those descriptions via a (currently authorized for management accounts only) API:

curl --request POST \
  --url https://dex.hubofallthings.com/stats/available-data/descriptions \
  --header 'content-type: application/json' \
  --header 'x-auth-token: ACCESS_TOKEN' \
  --data '[{"namespace":"dex","description":"Data stored by the Data Exchange in individual HATs","endpoints":[{"endpoint":"databuyer","description":"DataBuyer service related information","fields":[{"name":"merchants[]","description":"The list of merchants the user is following","count":9},{"name":"date","description":"The date this record was updated on","count":17}]}]}]'
var data = JSON.stringify([
  {
    "namespace": "dex",
    "description": "Data stored by the Data Exchange in individual HATs",
    "endpoints": [
      {
        "endpoint": "databuyer",
        "description": "DataBuyer service related information",
        "fields": [
          {
            "name": "merchants[]",
            "description": "The list of merchants the user is following",
            "count": 9
          },
          {
            "name": "date",
            "description": "The date this record was updated on",
            "count": 17
          }
        ]
      }
    ]
  }
]);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://dex.hubofallthings.com/stats/available-data/descriptions");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("x-auth-token", "ACCESS_TOKEN");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://dex.hubofallthings.com/stats/available-data/descriptions",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "[{\"namespace\":\"dex\",\"description\":\"Data stored by the Data Exchange in individual HATs\",\"endpoints\":[{\"endpoint\":\"databuyer\",\"description\":\"DataBuyer service related information\",\"fields\":[{\"name\":\"merchants[]\",\"description\":\"The list of merchants the user is following\",\"count\":9},{\"name\":\"date\",\"description\":\"The date this record was updated on\",\"count\":17}]}]}]",
  CURLOPT_HTTPHEADER => array(
    "content-type: application/json",
    "x-auth-token: ACCESS_TOKEN"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://dex.hubofallthings.com/stats/available-data/descriptions"

payload = "[{\"namespace\":\"dex\",\"description\":\"Data stored by the Data Exchange in individual HATs\",\"endpoints\":[{\"endpoint\":\"databuyer\",\"description\":\"DataBuyer service related information\",\"fields\":[{\"name\":\"merchants[]\",\"description\":\"The list of merchants the user is following\",\"count\":9},{\"name\":\"date\",\"description\":\"The date this record was updated on\",\"count\":17}]}]}]"
headers = {
    'content-type': "application/json",
    'x-auth-token': "ACCESS_TOKEN"
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://dex.hubofallthings.com/stats/available-data/descriptions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["x-auth-token"] = 'ACCESS_TOKEN'
request.body = "[{\"namespace\":\"dex\",\"description\":\"Data stored by the Data Exchange in individual HATs\",\"endpoints\":[{\"endpoint\":\"databuyer\",\"description\":\"DataBuyer service related information\",\"fields\":[{\"name\":\"merchants[]\",\"description\":\"The list of merchants the user is following\",\"count\":9},{\"name\":\"date\",\"description\":\"The date this record was updated on\",\"count\":17}]}]}]"

response = http.request(request)
puts response.read_body

The response to the call is the entire data structure availalble, with the matching entities having updated descriptions.

Private endpoints

The other endpoints are used by automatic communication between systems, e.g. the HATs reporting statistics events.