Otonomo's Streaming Interface - Full

📘

Work In Progress

This feature is in the process of being implemented and should be used for reference only.

Target Audience

This guide is intended for developers who would like to use Otonomo's vehicle data streaming capability.

Some of the details in this doc are still work-in-progress and may change in the GA released version.

Streaming Functionality Overview

Otonomo has served vehicle data by having data consumers 'pull' data using HTTP GET requests sent from the data consumer side to Otonomo.
However, real-time vehicle data is often better served through a push mechanism, which ensures minimal delay and packet loss.
Otonomo is implementing a streaming mechanism which uses HTTP POST requests for pushing data to the data consumer.
The planned streaming mechanism will work with both anonymous and personal data types.
The streaming capability will also allow data consumers to define certain filters, such as geographical area and time ranges, whereby vehicles meeting these filter criteria would have their data streamed.

Subscribing to a New Stream

The following APIs in the 'Subscribing to a New Stream' section are still not implemented and are here for reference only.

To begin streaming data, data consumers creating Apps or Services need to be subscribed to a new data stream.
Apps and Services are created by Otonomo on behalf of the consumer after a consumer opens an account on the platform (sign-up (https://market.otonomo.io/onboarding/signup)).
The following message diagram describes a typical message flow:

369

Create Subscription API

Generates a new stream subscription based on the app's filters.

Request example:

POST api/consumers/<CONSUMER_NAME>/apps/<APP_NAME>/streams/subscriptions/

HEADERS: CONSUMER_TOKEN

body:
{
    "callback_url": "https://myapp.com/callback/",
    "callback_secret": "SDF45Dfw4t9gre$%^"
    "email": "[email protected]",
    "max_msg_size": 1024, # in Kbs
    "polygon": [[{"lat": 1, "lon": 1}, {"lat": 1, "lon": 2},
                 {"lat": 2, "lon": 2}, {"lat": 2, "lon": 1}]],
    "country_codes": ["uk", "it"],
    "cities": ["london"],
    "max_points_latency": 2000, # in Milliseconds
    "activity_timeframes_utc": [{"start_time": "00:30:00", "end_time": "03:45:00"},
                            {"start_time": "04:20:00", "end_time": "16:20:00"}]
}
ParametersDescription
consumer token (header)This is an HTTP authorization header, which should contain a general access token preceded by the token type string for OAuth2, "Bearer". To obtain this token, refer to the General Access Token API.
callback_urlThis URL points to your application server and is used for streaming data from Otonomo to your server.
callback_secretA shared secret between the application and Otonomo. This secret is included on the authorization header of the HTTP POST containing the streamed messages. Applications should verify the secret integrity.
emailThis optional field is used for alerting the developer on link issues. In case we fail to push the data several times, we will send an email notifying the issue to the relevant consumer.
polygonA set of coordinates which define a polygon. The polygon is used for defining an area. Vehicles moving in this area are included in the stream.
country_codesList of country codes. Vehicles moving in these countries will be included in the stream.
citiesList of cities. Vehicles moving in these cities will be included in the stream.
max_points_latencyOnly vehicle samples with lower latency will be streamed.
activity_timeframes_utcA list of start time and end time duplets, which define time ranges during a day when the stream should be active. If omitted, streams will be active at all times.
status"Enabled" (default), "disabled" - used for stopping a stream (see Update Subscription API below), "suspended" - set by the platform when the remote server pointed by call_back URI cannot be reached.

Response example:

201 Created
{
  'callback_url': 'https://myapp.com/callback/',
  'filters': {
    "polygon": [[{"lat": 1, "lon": 1}, {"lat": 1, "lon": 2},
                 {"lat": 2, "lon": 2}, {"lat": 2, "lon": 1}]],
    "country_codes": ["uk", "it"],
    "cities": ["london"],
    "max_points_latency": 2000, # in Milliseconds
    "activity_timeframes": [{"start_time": "00:30:00", "end_time": "03:45:00"},
                            {"start_time": "04:20:00", "end_time": "16:20:00"}]
  },
  'stream_id': '28d24e01-4020-49c4-ad9e-c60debd330c2',
  'status': 'enabled',
  'updated_at': '2019-01-29T14:32:39.956179Z',
  'email': "[email protected]"
}

Update Subscription API

Use this API to change the stream settings. The parameters used in the request body of this API should match the ones used in the Create Subscription API. Only the parameters that need modification should be included.
This API is also used for stopping a stream.
This is done by using “status” = “disabled”.

Request example (all parameters are optional):

PATCH api/consumers/<CONSUMER_NAME>/apps/<APP_NAME>/streams/subscriptions/<STREAM_ID>

HEADERS: CONSUMER_TOKEN

body:
{
    "callback_url": "https://myapp.com/new_callback/",
    "max_points_latency": 3000,
    "status": "enabled"
}

Response example:

200 OK
{
  'callback_url': 'https://myapp.com/new_callback/',
  'filters': {
        "max_points_latency": 3000
   },
  'stream_id': '28d24e01-4020-49c4-ad9e-c60debd330c2',
  'status': 'enabled',
  'updated_at': '2019-01-29T14:32:39.956179Z',
  'email': "[email protected]"
}

Get Active Subscriptions API

Returns all enabled subscriptions of an app.

Request example:

GET api/consumers/<CONSUMER_NAME>/apps/<APP_NAME>/streams/subscriptions/

HEADERS: CONSUMER_TOKEN

Response example:

200 OK
[
  {
    "callback_url": "https://myapp.com/callback/",
    "email": "[email protected]",
    "status": "enabled",
    "updated_at": "2019-01-29T14:24:44.125076Z",
    "filters": {
        "polygon": [[{"lat": 1, "lon": 1}, {"lat": 1, "lon": 2},
                     {"lat": 2, "lon": 2}, {"lat": 2, "lon": 1}]],
        "country_codes": ["uk", "it"],
        "cities": ["london"],
        "max_points_latency": 2000, # in Milliseconds
        "activity_timeframes": [{"start_time": "00:30:00", "end_time": "03:45:00"},
                                {"start_time": "04:20:00", "end_time": "16:20:00"}]
    },
    "stream_id": "8e5572b0-9b0e-41f1-8b3e-1490cd51912b"
  },
  {
    "callback_url": "https://myapp.com/callback2/",
    "email": "[email protected]",
    "status": "enabled",
    "updated_at": "2019-01-29T14:24:44.125500Z",
    "filters": {
     
    },
    "stream_id": "872c864e-c303-4688-97db-25e6bf78a977"
  }
]

Get Subscription API

Returns the details of a specified subscription.

Request example:

GET api/consumers/<CONSUMER_NAME>/apps/<APP_NAME>/streams/subscriptions/<STREAM_ID>

HEADERS: CONSUMER_TOKEN

Response example:

200 OK
{
  'callback_url': 'https://myapp.com/callback/',
  'stream_id': 'a659ce56-2708-43a1-adec-830efa7653b0',
    "filters": {
     
    },
  'updated_at': '2019-01-29T14:19:14.809030Z',
  'status': 'enabled',
  'email': '[email protected]'
}

The Vehicle Data Stream

After subscribing to a stream, Otonomo starts sending HTTP POST messages, containing vehicle data, to the call-back URL provided on the stream subscription API.
Every one second, a new HTTP POST request is generated with all the accumulated vehicle data points from the previous POST request.
A POST request can contain up to 1,000 vehicle data points. If no new points have arrived since last HTTP POST, no new POST will be issued.
In case Otonomo fails to push the data several times, an email is sent (to the address provided on the Create Subscription API) notifying about the issue and its cause. There is no retroactive pushing of the data while the feed was down.

The HTTP POST payload is a standard JSON message with three keys:
"subscription_id", "num_of_records", and 'data' key.
The value for the 'data' key is a list of vehicle messages grouped into data points.

The format below is still a draft and may change in the final implementation.

Structure of HTTP POST message for streamed vehicle data:
The headers included on the POST request are:

  1. 'authorization: token'
  2. 'content-type: application/json'

Message Body:

{
  "data": [
    {
      "time": 1557060437000,
      "otonomo_id": "33f0da57aa025edca68bf29d51278e87",
      "latitude": 7,
      "longitude": -162,
      "heading": 182,
      "speed": 124,
    },
    {
      "time": 1557060440000,
      "otonomo_id": "33f0da57aa025edca68bf29d51278e87",
      "latitude": -49,
      "longitude": 16,
      "heading": 60,
      "speed": 181,
    }
  ],
  "num_of_records": 2,
  "subscription_id": "01fba5398b7d4055a12fe6a7a6cd79c4"
}