Backend documentation

Overview

The API follows the JSON API standard.

Authentication

Every request to the sync endpoint must be authenticated with an authorization header with a JWT, encrypted with the shared token_secret which is available on the admin dashboard under "Authentication tokens". The JWT must include the claims sub and exp in the payload. sub (subject) is fixed to "sync". The expiration date (unix epoch) should be set to a short time into the future to avoid a lost token being useful for a long time.

{
  "sub": "sync",
  "exp": 1533040854
}

Authorization: Bearer abc123.def456.gehz7890

Storyline synchronization API

Endpoint for synchronization of the complete storyline of one tenant. Meant to be implemented by customers that run their own service.

The storyline is an endless stream of chronologically sorted entries. New entries are appended continuously by the Modedetection. This endpoint implements a mechanism to retrieve the complete stream, grouped into pages of reasonable size, by adding a link to the next page of data to a response that contains entries. An initial request without the special page parameter will return the first available page, and include a link to the next page. When the end is reached, an empty page without a next link is returned. In this case the consumer should pause for a short time and then retry to load the same page again.

Example initial request without page parameter:

GET https://api.motion-tag.de/sync/storyline

{
  "data": [
    {
      "type" : "Track",
      "id" : "8861e1e2-abd0-41cc-9b3d-f8c2d2613cf4",
      "attributes" : {
        "user_id" : "d28907c7-0846-461f-950e-9d40f2ca418c",
        "created_at" : "2018-01-01T16:00:00Z",
        "started_at" : "2018-01-01T14:00:00Z",
        "started_at_timezone" : "Europe/Zurich",
        "finished_at" : "2018-01-01T15:00:00Z",
        "finished_at_timezone" : "Europe/Zurich",
        "geometry" : {
           "type" : "LineString",
           "coordinates" : [
              [
                 1,
                 1.5
              ],
              [
                 1.5,
                 2
              ]
           ]
        },
        "track_mode" : "bicycle",
        "track_length_in_meters" : 5000
      }
    },
    {
       "type" : "Stay",
       "id" : "c862b09b-2786-4be3-b0d6-90997783a343",
       "attributes" : {
         "user_id" : "437b0a94-d495-4e4e-96fb-fe1783b5c95e",
         "created_at" : "2018-01-01T16:00:00Z",
         "started_at" : "2018-01-01T14:00:00Z",
         "started_at_timezone" : "Europe/Zurich",
         "finished_at" : "2018-01-01T15:00:00Z",
         "finished_at_timezone" : "Europe/Zurich",
         "geometry" : {
            "type" : "Point",
            "coordinates" : [
               1,
               1.5
            ]
         },
         "stay_purpose" : "study"
       }
    },
    "..."
  ],
  "links": {
    "next" : "https://api.motion-tag.de/sync/storyline?page[after]=abc123"
  }
}

The consumer is expected to store the received entries and immediately afterwards request the next page given in links.next. The value of page[after] has no meaning beyond being used by the server to determine the next page.

Example request with no more data:

GET https://api.motion-tag.de/sync/storyline?page[after]=abc123

{
  "data": []
}

The consumer should pause for a short time and then request the same URL again.