Language

Data Input can happen in one of two ways:

  1. Saving one or more homogeneous data records into a single endpoint
  2. Saving multipe data records that can be potentially heterogeneous, related, or both

Saving homogeneous data records

A data entry request for a single endpoint (/hat/locations), with multiple records inserted in one go. The data provided in the example is merely an illustration - the HAT will accept any well-formed JSON data. Note the request is authenticated with an ACCESS_TOKEN obtained previously and the token has been issued for the namespace of hat specifically.

curl --request POST \
  --url https://test.hubat.net/api/v2/data/hat/locations \
  --header 'content-type: application/json' \
  --header 'x-auth-token: ACCESS_TOKEN' \
  --data '[{"id":85998,"name":"record 1","lastUpdated":"2017-04-23T16:11:17.000Z","data":{"locations":{"latitude":"51.671358277138","longitude":"0.101014673709963","accuracy":"10.0","timestamp":"2017-04-23T16:11:17+0000"}}},{"id":85997,"name":"record 3","lastUpdated":"2017-04-23T16:18:04.000Z","data":{"locations":{"latitude":"51.6658257133844","longitude":"0.080477950927866","accuracy":"1414.0","timestamp":"2017-04-23T16:18:04+0000"}}},{"id":85996,"name":"record 2","lastUpdated":"2017-04-23T16:12:58.000Z","data":{"locations":{"latitude":"51.674001392439","longitude":"0.100905202634514","accuracy":"1414.0","timestamp":"2017-04-23T16:12:58+0000"}}}]'
var data = JSON.stringify([
  {
    "id": 85998,
    "name": "record 1",
    "lastUpdated": "2017-04-23T16:11:17.000Z",
    "data": {
      "locations": {
        "latitude": "51.671358277138",
        "longitude": "0.101014673709963",
        "accuracy": "10.0",
        "timestamp": "2017-04-23T16:11:17+0000"
      }
    }
  },
  {
    "id": 85997,
    "name": "record 3",
    "lastUpdated": "2017-04-23T16:18:04.000Z",
    "data": {
      "locations": {
        "latitude": "51.6658257133844",
        "longitude": "0.080477950927866",
        "accuracy": "1414.0",
        "timestamp": "2017-04-23T16:18:04+0000"
      }
    }
  },
  {
    "id": 85996,
    "name": "record 2",
    "lastUpdated": "2017-04-23T16:12:58.000Z",
    "data": {
      "locations": {
        "latitude": "51.674001392439",
        "longitude": "0.100905202634514",
        "accuracy": "1414.0",
        "timestamp": "2017-04-23T16:12:58+0000"
      }
    }
  }
]);

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

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

xhr.open("POST", "https://test.hubat.net/api/v2/data/hat/locations");
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://test.hubat.net/api/v2/data/hat/locations",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "[{\"id\":85998,\"name\":\"record 1\",\"lastUpdated\":\"2017-04-23T16:11:17.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.671358277138\",\"longitude\":\"0.101014673709963\",\"accuracy\":\"10.0\",\"timestamp\":\"2017-04-23T16:11:17+0000\"}}},{\"id\":85997,\"name\":\"record 3\",\"lastUpdated\":\"2017-04-23T16:18:04.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.6658257133844\",\"longitude\":\"0.080477950927866\",\"accuracy\":\"1414.0\",\"timestamp\":\"2017-04-23T16:18:04+0000\"}}},{\"id\":85996,\"name\":\"record 2\",\"lastUpdated\":\"2017-04-23T16:12:58.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.674001392439\",\"longitude\":\"0.100905202634514\",\"accuracy\":\"1414.0\",\"timestamp\":\"2017-04-23T16:12:58+0000\"}}}]",
  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://test.hubat.net/api/v2/data/hat/locations"

payload = "[{\"id\":85998,\"name\":\"record 1\",\"lastUpdated\":\"2017-04-23T16:11:17.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.671358277138\",\"longitude\":\"0.101014673709963\",\"accuracy\":\"10.0\",\"timestamp\":\"2017-04-23T16:11:17+0000\"}}},{\"id\":85997,\"name\":\"record 3\",\"lastUpdated\":\"2017-04-23T16:18:04.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.6658257133844\",\"longitude\":\"0.080477950927866\",\"accuracy\":\"1414.0\",\"timestamp\":\"2017-04-23T16:18:04+0000\"}}},{\"id\":85996,\"name\":\"record 2\",\"lastUpdated\":\"2017-04-23T16:12:58.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.674001392439\",\"longitude\":\"0.100905202634514\",\"accuracy\":\"1414.0\",\"timestamp\":\"2017-04-23T16:12:58+0000\"}}}]"
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://test.hubat.net/api/v2/data/hat/locations")

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 = "[{\"id\":85998,\"name\":\"record 1\",\"lastUpdated\":\"2017-04-23T16:11:17.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.671358277138\",\"longitude\":\"0.101014673709963\",\"accuracy\":\"10.0\",\"timestamp\":\"2017-04-23T16:11:17+0000\"}}},{\"id\":85997,\"name\":\"record 3\",\"lastUpdated\":\"2017-04-23T16:18:04.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.6658257133844\",\"longitude\":\"0.080477950927866\",\"accuracy\":\"1414.0\",\"timestamp\":\"2017-04-23T16:18:04+0000\"}}},{\"id\":85996,\"name\":\"record 2\",\"lastUpdated\":\"2017-04-23T16:12:58.000Z\",\"data\":{\"locations\":{\"latitude\":\"51.674001392439\",\"longitude\":\"0.100905202634514\",\"accuracy\":\"1414.0\",\"timestamp\":\"2017-04-23T16:12:58+0000\"}}}]"

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

If the data gets saved, the response includes the full data, wrapped in the Record data structure: - endpoint field that includes the specific endpoint the record was assigned to - recordId - UUID of the data record - data - the data JSON structure exactly as submitted


HTTP/1.1 201 Created
Content-Type: application/json


[
  {
    "endpoint": "locations",
    "recordId": "f8c011d1-98f0-4e5f-89a6-64b949724eba",
    "data": {
      "id": 185998,
      "data": {
        "locations": {
          "accuracy": "10.0",
          "latitude": "51.671358277138",
          "longitude": "0.101014673709963",
          "timestamp": "2017-04-23T16:11:17+0000"
        }
      },
      "name": "record 1",
      "lastUpdated": "2017-04-23T16:11:17.000Z"
    },
    "links": [

    ]
  },
  {
    "endpoint": "locations",
    "recordId": "0a79bef4-9a8e-4d19-937d-9a759fc2981b",
    "data": {
      "id": 185997,
      "data": {
        "locations": {
          "accuracy": "1414.0",
          "latitude": "51.6658257133844",
          "longitude": "0.080477950927866",
          "timestamp": "2017-04-23T16:18:04+0000"
        }
      },
      "name": "record 3",
      "lastUpdated": "2017-04-23T16:18:04.000Z"
    },
    "links": [

    ]
  },
  {
    "endpoint": "locations",
    "recordId": "b6ebcdc3-235e-4e8c-834c-eec08beb55cd",
    "data": {
      "id": 185996,
      "data": {
        "locations": {
          "accuracy": "1414.0",
          "latitude": "51.674001392439",
          "longitude": "0.100905202634514",
          "timestamp": "2017-04-23T16:12:58+0000"
        }
      },
      "name": "record 2",
      "lastUpdated": "2017-04-23T16:12:58.000Z"
    },
    "links": [

    ]
  }
]

If there are any problems with your JSON (e.g. it is malformed), you will receive a Bad Request response code with the details of the error in the body of the response. If, for example, such data (as decided by its hash) already exists in the HAT, none of the data in the request will be saved and you will receive a message indicating so:


HTTP/1.1 400 Bad Request
Content-Type: application/json


{
  "message": "Duplicate Data",
  "cause": "Could not insert data - Duplicate data"
}

Note: all data entry operations are transactional, i.e. insertion of all data provided in the request succeeds or the whole request fails and no data gets inserted.

To illustrate HAT’s acceptance of any valid JSON data, here is another example, saving very different profile data in the same namespace, but a different endpoint:

curl --request POST \
  --url https://test.hubat.net/api/v2/data/rumpel/profile \
  --header 'content-type: application/json' \
  --header 'x-auth-token: ACCESS_TOKEN' \
  --data '{"profile":{"website":{"link":"https://example.com","private":"false"},"nick":{"private":"true","name":""},"primary_email":{"value":"testuser@example.com","private":"false"},"private":"false","youtube":{"link":"","private":"true"},"address_global":{"city":"London","county":"","country":"UK","private":"true"},"age":{"group":"","private":"true"},"personal":{"first_name":"","private":"false","preferred_name":"Test","last_name":"User","middle_name":"","title":""},"blog":{"link":"","private":"false"},"facebook":{"link":"","private":"false"},"address_details":{"no":"","street":"","private":"false","postcode":""},"emergency_contact":{"first_name":"","private":"true","relationship":"","last_name":"","mobile":""},"alternative_email":{"private":"true","value":""},"fb_profile_photo":{"private":"false"},"twitter":{"link":"","private":"false"},"about":{"body":"A short bio about me shown on my PHATA","private":"false","title":"Me the Test User"},"mobile":{"no":"","private":"true"},"gender":{"type":"","private":"true"}}}'
var data = JSON.stringify({
  "profile": {
    "website": {
      "link": "https://example.com",
      "private": "false"
    },
    "nick": {
      "private": "true",
      "name": ""
    },
    "primary_email": {
      "value": "testuser@example.com",
      "private": "false"
    },
    "private": "false",
    "youtube": {
      "link": "",
      "private": "true"
    },
    "address_global": {
      "city": "London",
      "county": "",
      "country": "UK",
      "private": "true"
    },
    "age": {
      "group": "",
      "private": "true"
    },
    "personal": {
      "first_name": "",
      "private": "false",
      "preferred_name": "Test",
      "last_name": "User",
      "middle_name": "",
      "title": ""
    },
    "blog": {
      "link": "",
      "private": "false"
    },
    "facebook": {
      "link": "",
      "private": "false"
    },
    "address_details": {
      "no": "",
      "street": "",
      "private": "false",
      "postcode": ""
    },
    "emergency_contact": {
      "first_name": "",
      "private": "true",
      "relationship": "",
      "last_name": "",
      "mobile": ""
    },
    "alternative_email": {
      "private": "true",
      "value": ""
    },
    "fb_profile_photo": {
      "private": "false"
    },
    "twitter": {
      "link": "",
      "private": "false"
    },
    "about": {
      "body": "A short bio about me shown on my PHATA",
      "private": "false",
      "title": "Me the Test User"
    },
    "mobile": {
      "no": "",
      "private": "true"
    },
    "gender": {
      "type": "",
      "private": "true"
    }
  }
});

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

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

xhr.open("POST", "https://test.hubat.net/api/v2/data/rumpel/profile");
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://test.hubat.net/api/v2/data/rumpel/profile",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"profile\":{\"website\":{\"link\":\"https://example.com\",\"private\":\"false\"},\"nick\":{\"private\":\"true\",\"name\":\"\"},\"primary_email\":{\"value\":\"testuser@example.com\",\"private\":\"false\"},\"private\":\"false\",\"youtube\":{\"link\":\"\",\"private\":\"true\"},\"address_global\":{\"city\":\"London\",\"county\":\"\",\"country\":\"UK\",\"private\":\"true\"},\"age\":{\"group\":\"\",\"private\":\"true\"},\"personal\":{\"first_name\":\"\",\"private\":\"false\",\"preferred_name\":\"Test\",\"last_name\":\"User\",\"middle_name\":\"\",\"title\":\"\"},\"blog\":{\"link\":\"\",\"private\":\"false\"},\"facebook\":{\"link\":\"\",\"private\":\"false\"},\"address_details\":{\"no\":\"\",\"street\":\"\",\"private\":\"false\",\"postcode\":\"\"},\"emergency_contact\":{\"first_name\":\"\",\"private\":\"true\",\"relationship\":\"\",\"last_name\":\"\",\"mobile\":\"\"},\"alternative_email\":{\"private\":\"true\",\"value\":\"\"},\"fb_profile_photo\":{\"private\":\"false\"},\"twitter\":{\"link\":\"\",\"private\":\"false\"},\"about\":{\"body\":\"A short bio about me shown on my PHATA\",\"private\":\"false\",\"title\":\"Me the Test User\"},\"mobile\":{\"no\":\"\",\"private\":\"true\"},\"gender\":{\"type\":\"\",\"private\":\"true\"}}}",
  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://test.hubat.net/api/v2/data/rumpel/profile"

payload = "{\"profile\":{\"website\":{\"link\":\"https://example.com\",\"private\":\"false\"},\"nick\":{\"private\":\"true\",\"name\":\"\"},\"primary_email\":{\"value\":\"testuser@example.com\",\"private\":\"false\"},\"private\":\"false\",\"youtube\":{\"link\":\"\",\"private\":\"true\"},\"address_global\":{\"city\":\"London\",\"county\":\"\",\"country\":\"UK\",\"private\":\"true\"},\"age\":{\"group\":\"\",\"private\":\"true\"},\"personal\":{\"first_name\":\"\",\"private\":\"false\",\"preferred_name\":\"Test\",\"last_name\":\"User\",\"middle_name\":\"\",\"title\":\"\"},\"blog\":{\"link\":\"\",\"private\":\"false\"},\"facebook\":{\"link\":\"\",\"private\":\"false\"},\"address_details\":{\"no\":\"\",\"street\":\"\",\"private\":\"false\",\"postcode\":\"\"},\"emergency_contact\":{\"first_name\":\"\",\"private\":\"true\",\"relationship\":\"\",\"last_name\":\"\",\"mobile\":\"\"},\"alternative_email\":{\"private\":\"true\",\"value\":\"\"},\"fb_profile_photo\":{\"private\":\"false\"},\"twitter\":{\"link\":\"\",\"private\":\"false\"},\"about\":{\"body\":\"A short bio about me shown on my PHATA\",\"private\":\"false\",\"title\":\"Me the Test User\"},\"mobile\":{\"no\":\"\",\"private\":\"true\"},\"gender\":{\"type\":\"\",\"private\":\"true\"}}}"
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://test.hubat.net/api/v2/data/rumpel/profile")

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 = "{\"profile\":{\"website\":{\"link\":\"https://example.com\",\"private\":\"false\"},\"nick\":{\"private\":\"true\",\"name\":\"\"},\"primary_email\":{\"value\":\"testuser@example.com\",\"private\":\"false\"},\"private\":\"false\",\"youtube\":{\"link\":\"\",\"private\":\"true\"},\"address_global\":{\"city\":\"London\",\"county\":\"\",\"country\":\"UK\",\"private\":\"true\"},\"age\":{\"group\":\"\",\"private\":\"true\"},\"personal\":{\"first_name\":\"\",\"private\":\"false\",\"preferred_name\":\"Test\",\"last_name\":\"User\",\"middle_name\":\"\",\"title\":\"\"},\"blog\":{\"link\":\"\",\"private\":\"false\"},\"facebook\":{\"link\":\"\",\"private\":\"false\"},\"address_details\":{\"no\":\"\",\"street\":\"\",\"private\":\"false\",\"postcode\":\"\"},\"emergency_contact\":{\"first_name\":\"\",\"private\":\"true\",\"relationship\":\"\",\"last_name\":\"\",\"mobile\":\"\"},\"alternative_email\":{\"private\":\"true\",\"value\":\"\"},\"fb_profile_photo\":{\"private\":\"false\"},\"twitter\":{\"link\":\"\",\"private\":\"false\"},\"about\":{\"body\":\"A short bio about me shown on my PHATA\",\"private\":\"false\",\"title\":\"Me the Test User\"},\"mobile\":{\"no\":\"\",\"private\":\"true\"},\"gender\":{\"type\":\"\",\"private\":\"true\"}}}"

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

Heterogeneous data records can be inserted simultaneously using the batch-data API endpoint. One example where such data insertion is useful is HAT notes, where a text-based note is saved with an attached “nudge” - a time-based reminder connected to the note. It is important to keep notes and nudges logically separate, because both can be used independently, e.g. a nudge can be attached to certain locations, photos, posts…

curl --request POST \
  --url https://test.hubat.net/api/v2/data-batch \
  --header 'content-type: application/json' \
  --header 'x-auth-token: ACCESS_TOKEN' \
  --data '[{"endpoint":"rumpel/notable","data":{"id":84995,"lastUpdated":"2017-04-23T14:21:51+01:00","data":{"notablesv1":{"authorv1":{"phata":"testing.hubat.net"},"created_time":"2017-04-10T14:19:59:+01:00","shared":"true","shared_on":"twitter","message":"Showcasing the new HAT APIs","public_until":"2017-05-11T14:21:54+01:00","updated_time":"2017-04-23T14:21:58+01:00","kind":"note"}}},"links":[{"endpoint":"rumpel/nudge","data":{"type":"time","nudge":"Share APIs with the world","time":"2017-04-30T14:22:52+01:00"}}]}]'
var data = JSON.stringify([
  {
    "endpoint": "rumpel/notable",
    "data": {
      "id": 84995,
      "lastUpdated": "2017-04-23T14:21:51+01:00",
      "data": {
        "notablesv1": {
          "authorv1": {
            "phata": "testing.hubat.net"
          },
          "created_time": "2017-04-10T14:19:59:+01:00",
          "shared": "true",
          "shared_on": "twitter",
          "message": "Showcasing the new HAT APIs",
          "public_until": "2017-05-11T14:21:54+01:00",
          "updated_time": "2017-04-23T14:21:58+01:00",
          "kind": "note"
        }
      }
    },
    "links": [
      {
        "endpoint": "rumpel/nudge",
        "data": {
          "type": "time",
          "nudge": "Share APIs with the world",
          "time": "2017-04-30T14:22:52+01:00"
        }
      }
    ]
  }
]);

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

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

xhr.open("POST", "https://test.hubat.net/api/v2/data-batch");
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://test.hubat.net/api/v2/data-batch",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "[{\"endpoint\":\"rumpel/notable\",\"data\":{\"id\":84995,\"lastUpdated\":\"2017-04-23T14:21:51+01:00\",\"data\":{\"notablesv1\":{\"authorv1\":{\"phata\":\"testing.hubat.net\"},\"created_time\":\"2017-04-10T14:19:59:+01:00\",\"shared\":\"true\",\"shared_on\":\"twitter\",\"message\":\"Showcasing the new HAT APIs\",\"public_until\":\"2017-05-11T14:21:54+01:00\",\"updated_time\":\"2017-04-23T14:21:58+01:00\",\"kind\":\"note\"}}},\"links\":[{\"endpoint\":\"rumpel/nudge\",\"data\":{\"type\":\"time\",\"nudge\":\"Share APIs with the world\",\"time\":\"2017-04-30T14:22:52+01:00\"}}]}]",
  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://test.hubat.net/api/v2/data-batch"

payload = "[{\"endpoint\":\"rumpel/notable\",\"data\":{\"id\":84995,\"lastUpdated\":\"2017-04-23T14:21:51+01:00\",\"data\":{\"notablesv1\":{\"authorv1\":{\"phata\":\"testing.hubat.net\"},\"created_time\":\"2017-04-10T14:19:59:+01:00\",\"shared\":\"true\",\"shared_on\":\"twitter\",\"message\":\"Showcasing the new HAT APIs\",\"public_until\":\"2017-05-11T14:21:54+01:00\",\"updated_time\":\"2017-04-23T14:21:58+01:00\",\"kind\":\"note\"}}},\"links\":[{\"endpoint\":\"rumpel/nudge\",\"data\":{\"type\":\"time\",\"nudge\":\"Share APIs with the world\",\"time\":\"2017-04-30T14:22:52+01:00\"}}]}]"
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://test.hubat.net/api/v2/data-batch")

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 = "[{\"endpoint\":\"rumpel/notable\",\"data\":{\"id\":84995,\"lastUpdated\":\"2017-04-23T14:21:51+01:00\",\"data\":{\"notablesv1\":{\"authorv1\":{\"phata\":\"testing.hubat.net\"},\"created_time\":\"2017-04-10T14:19:59:+01:00\",\"shared\":\"true\",\"shared_on\":\"twitter\",\"message\":\"Showcasing the new HAT APIs\",\"public_until\":\"2017-05-11T14:21:54+01:00\",\"updated_time\":\"2017-04-23T14:21:58+01:00\",\"kind\":\"note\"}}},\"links\":[{\"endpoint\":\"rumpel/nudge\",\"data\":{\"type\":\"time\",\"nudge\":\"Share APIs with the world\",\"time\":\"2017-04-30T14:22:52+01:00\"}}]}]"

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

The response will include the main data record with the note as well as a separate data record with the nudge, linked to the main one.

Data records do not necessarily need to be linked up when being inserted. This can be done later by referring to the records using their IDs:

curl --request POST \
  --url 'https://test.hubat.net/api/v2/data-link?records=6dcff611-45cb-49a9-82ca-318b9e5a3c17' \
  --header 'content-type: application/json' \
  --header 'x-auth-token: ACCESS_TOKEN' \
  --data '{}'
var data = JSON.stringify({});

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

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

xhr.open("POST", "https://test.hubat.net/api/v2/data-link?records=6dcff611-45cb-49a9-82ca-318b9e5a3c17");
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://test.hubat.net/api/v2/data-link?records=6dcff611-45cb-49a9-82ca-318b9e5a3c17",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{}",
  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://test.hubat.net/api/v2/data-link"

payload = "{}"
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://test.hubat.net/api/v2/data-link?records=6dcff611-45cb-49a9-82ca-318b9e5a3c17")

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 = "{}"

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