Working With a Stream

Disconnects

Validic will close a streaming connection for the following reasons:
A streaming server is restarted. This is usually related to a code deploy and is not very frequent.
Validic network configuration changes. These events are rare, and would represent load balancer restarts or network reconfigurations, for example. Validic will work diligently to notify customers if we feel any changes made by us will impact users.

The client is responsible for reestablishing the connection if a disconnect occurs. Validic will maintain a customer's checkpoint in a stream for 7 days. If a customer re-connects to their stream after 7 days the customer will start consuming data from the beginning of the stream.

Processing

Once connected to a stream, all data received by validic will be transmitted in a data event. Additionally, a poke event will be sent every 5 seconds to maintain a heartbeat with the client.
Messages streamed by this API are JSON encoded. Keep in mind that the attributes of a JSON-encoded object are unordered - do not rely on fields appearing in any given order. Also keep in mind that your JSON parser should tolerate unexpected or missing fields.

Events streamed through the connection are delimited by consecutive \n characters:

event: data
data: {"category":"daily","checksum":"3f5278b39427bb0dede1f13f4ba3d22c","created_at":"2017-03-28T00:08:28.718Z","end_time":"2017-03-28T03:59:59Z","id":"a7810c17f561c564547d0ab0498c6a97","log_id":"2017-03-27","metrics":[{"origin":"manual","type":"active_duration","unit":"min","value":0.0},{"origin":"manual","type":"basal_energy_burned","unit":"kcal","value":1467.0},{"origin":"manual","type":"distance","unit":"km","value":4.1},{"origin":"manual","type":"elevation","unit":"m","value":0.0},{"origin":"manual","type":"floors_climbed","unit":"count","value":0},{"origin":"manual","type":"steps","unit":"count","value":5713},{"origin":"manual","type":"energy_burned","unit":"kcal","value":2072.0}],"offset_origin":"profile","origin":"manual","segments":[],"source":{"type":"fitbit"},"start_time":"2017-03-27T04:00:00Z","type":"summary","user":{"customer_id":"58209c808a5da50001de6e2d","uid":"TY892FG61","user_id":"583efed88a5da50001a45083"},"utc_offset":-14400,"version":"1.0"}\n

Data Events

Each data events sent from the streaming API will contain a JSON encoded Validic standard objects which will include a type attribute defining the standard object type. The data object could be one of the following types:
Types

  • Summary
  • Measurement
  • Sleep
  • Nutrition
  • Workout
    These messages will be sent in near-realtime to when the data is received by Validic, in the order, they were received from the source.

Unique Identifiers & Updates

Each data object contains a unique id which defines a unique event type received processing data events, you will receive the same id multiple times, likely with summary data types. Because the data is transmitted through to the client in which it was received, the last record received is the most up to date record for the event.
When receiving an updated event, a customer that is persisting this data should leverage the id to find the existing record in their system. Validic provides a checksum in each event. A difference in checksum values represents modified data for records with the same id. A final comparison on the created_at value can occur if there is concern about out of order processing as the most recent created_at time represents the most up to date record.

Example
data: {  
   "category":"daily",
   "checksum":"c9a1eb48cbf2504e6a7a1055238ae153",
   "created_at":"2017-03-29T15:31:33.959Z",
   "end_time":"2017-03-30T03:59:59Z",
   "id":"97a2d220620bfa419f8bb0228c5fac73",
   "log_id":"2017-03-29",
   "metrics":[  
      {  
         "origin":"manual",
         "type":"active_duration",
         "unit":"min",
         "value":0.0
      },
      {  
         "origin":"manual",
         "type":"basal_energy_burned",
         "unit":"kcal",
         "value":897.0
      },
      {  
         "origin":"manual",
         "type":"distance",
         "unit":"km",
         "value":1.76
      },
      {  
         "origin":"manual",
         "type":"steps",
         "unit":"count",
         "value":2415
      },
      {  
         "origin":"manual",
         "type":"energy_burned",
         "unit":"kcal",
         "value":1184.0
      }
   ],
   "offset_origin":"profile",
   "segments":[  

   ],
   "source":{  
      "type":"fitbit"
   },
   "start_time":"2017-03-29T04:00:00Z",
   "type":"summary",
   "user":{  
      "organization_id":"58cb55c98SAMPLE01f75db3",
      "uid":"demotestuser1",
      "user_id":"58d96aSAMPLE001a25d40"
   },
   "utc_offset":-14400,
   "user_notes": [],
   "version":"1.0"
}

Poke: This event is sent every 5 seconds to maintain a heartbeat between the streaming API and the client.
event: poke
data: {"ts":"2017-01-01T12:00:00.000Z"}

👍

Related Articles

Streaming Best Practices

SSE Libraries

There are many libraries already built to process Server Sent Events (SSE).