Working with the Validic Connect API
Receiving Sync Notifications
Because the authorization is completed on a Validic hosted page, we will send a sync notification in the form of an HTTP POST to your designated Notification URL. This is a url that you will provide to us after being given Validic Connect Credentials and will be where Validic sends http POSTs to notify of successful syncs and disconnects.
https://yourdomain.com/validic_notifications
Below is the format for a sync notification.
{ "data": { "type": "sync", "message": "Confirmed authorization", "third_party": "NAME_OF_THIRD_PARTY", "connected_third_parties": ["ARRAY_OF_CONNECTED_THIRD_PARTIES"], "user": { "_id": "VALIDIC_USER_ID", "uid": "YOUR_USER_ID" } } }
NAME_OF_THIRD_PARTY
is the name of the organization for which the user has just given access to his or her data. For example, ACME Wellness.ARRAY_OF_CONNECTED_THIRD_PARTIES
is the current list of all organizations for which the user has given access to his or her data. For example, [ACME Wellness, VMS Healthcare].
This notification confirms the completion of the authorization. Once your system receives this notification, you can begin submitting user data.
Receiving Disconnect Notifications
Conversely, when a user disconnects your application from the third-party (they no longer want to share their data) you will receive a notification of disconnect.
https://yourdomain.com/validic_notifications
Below is the format for a disconnect notification.
{ "data": { "type": "disconnect", "message": "Confirmed disconnect", "third_party": "NAME_OF_THIRD_PARTY", "connected_third_parties": ["ARRAY_OF_CONNECTED_THIRD_PARTIES"], "user": { "_id": "VALIDIC_USER_ID", "uid": "YOUR_USER_ID" } } }
NAME_OF_THIRD_PARTY
is the name of the organization for which the user has just revoked access to his or her data. For example, ACME Wellness.ARRAY_OF_CONNECTED_THIRD_PARTIES
is the current list of all organizations for which the user still allows access to his or her data. For example, [VMS Healthcare].
Note: you should continue to POST this user’s data to Validic if there are other organizations with access to this his or her data. Only once you receive a disconnect notification with an empty array of connected_third_parties should you stop sending that user’s data to Validic.
Pushing User Data
You are now ready to send data for your users. To do so, submit a POST request to the following URL with the users activity data. The example below is for sending a Routine record to Validic:
ORGANIZATION_ID
is your Validic Connect Organization IDUSER_ID
is your user’s Validic Connect ID
POST https://api.validic.com/v1/organizations/{ORGANIZATION_ID}/users/{USER_ID}/routine.json -H 'Content-Type': 'application/json' { "routine": { "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 9355, "distance": 7290.33, "floors": 23, "elevation": 3.4, "calories_burned": 2874, "activity_id": "12345" }, "access_token": "YOUR_ORGANIZTION_ACCESS_TOKEN" }
A successful request will return with:
{ "code": 201, "message": "Ok", "routine": { "_id": "51552cdbfded0807c400006d", "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 9355, "distance": 7290.33, "floors": 23.0, "elevation": 3.4, "calories_burned": 2874, "source": "sample_app", "source_name": "Sample App", "last_updated": "2013-03-10T07:12:16+00:00" } }
Your activity_id
should be a unique identifier for this record in your system, analogous to the uid
you submitted earlier. The Validic _id
for this activity should then be saved as part of the activity record in your database for reconciliation purposes later.
Pushing User Data in Bulk
Partners have the option to push up to 100 records in a single POST. Do do so, include your objects in an array:
POST https://api.validic.com/v1/organizations/{ORGANIZATION_ID}/users/{USER_ID}/routine.json -H 'Content-Type': 'application/json' { "routine": [ { "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 9355, "distance": 7290.33, "floors": 23, "elevation": 3.4, "calories_burned": 2874, "activity_id": "12345" }, { "timestamp": "2013-03-10T08:10:19+00:00", "utc_offset": "+00:00", "steps": 10355, "distance": 17290.33, "floors": 20, "elevation": 3.1, "calories_burned": 5674, "activity_id": "123456" } ], "access_token": "YOUR_ORGANIZATION_ACCESS_TOKEN" }
A successful request will return with:
201 { "routine": [ { "_id": "51552cdbfded0807c400006d", "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 9355, "distance": 7290.33, "floors": 23.0, "elevation": 3.4, "calories_burned": 2874, "source": "sample_app", "source_name": "Sample App", "activity_id": "12345", "last_updated": "2013-03-10T07:12:16+00:00" }, { "_id": "51452bxbf3edc801c4d0008b", "timestamp": "2013-03-10T08:10:19+00:00", "utc_offset": "+00:00", "steps": 10355, "distance": 17290.33, "floors": 20, "elevation": 3.1, "calories_burned": 5674, "source": "sample_app", "source_name": "Sample App", "activity_id": "123456", "last_updated": "2013-03-10T07:12:16+00:00" } ], "errors": [] }
If any of the objects are successfully created you will receive a 201 response. If no objects were successfully created you will receive a 422. In the case where some records successfully created and others were not, you will receive a 201 but with the bad records included in the errors array. Each of the bad records can be identified by the given activity_id:
POST https://api.validic.com/v1/organizations/{ORGANIZATION_ID}/users/{USER_ID}/routine.json -H 'Content-Type': 'application/json' { "routine": [ { "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 9355, "distance": 7290.33, "floors": 23, "elevation": 3.4, "calories_burned": 2874, "activity_id": "12345" }, { "timestamp": "invalid timestamp", "utc_offset": "+00:00", "steps": 10355, "distance": 17290.33, "floors": 20, "elevation": 3.1, "calories_burned": 5674, "activity_id": "123456" } ], "access_token": "YOUR_ORGANIZATION_ACCESS_TOKEN" }
A successful request will return with:
201 { "routine": [ { "_id": "51552cdbfded0807c400006d", "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 9355, "distance": 7290.33, "floors": 23.0, "elevation": 3.4, "calories_burned": 2874, "source": "sample_app", "source_name": "Sample App", "last_updated": "2013-03-10T07:12:16+00:00" } ], "errors": [ { "code": 422, "message": "Unprocessable Entity", "errors": "Timestamp does not meet format specification or not in UTC time", "activity_id": "123456" } ] }
Updating User Data
If you wish to modify a record in Validic you can do so with a PUT request using the existing record’s Validic _id
as returned from a successful POST:
PUT https://api.validic.com/v1/organizations/{ORGANIZATION_ID}/users/{USER_ID}/routine/{VALIDIC_RECORD_ID}.json -H 'Content-Type': 'application/json' { "routine": { "steps": 10355 }, "access_token": "YOUR_ORGANIZATION_ACCESS_TOKEN" }
A successful request will return with:
200 { "code": 200, "message": "Ok", "routine": { "_id": "51552cdbfded0807c400006d", "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "+00:00", "steps": 10355, "distance": 7290.33, "floors": 23.0, "elevation": 3.4, "calories_burned": 2874, "source": "sample_app", "source_name": "Sample App", "last_updated": "2013-03-10T07:12:16+00:00" } }
Note: this is particularly relevant for Routine data which represents aggregated data (for example “steps”) instead of single data point for the day. For partners wishing to push Routine step data, for example, they should POST a single record that represents that day’s running total and subsequently send PUT requests to update that single record’s step count.
Deleting User Data
If you wish to delete a record in Validic you can do so with a DELETE request using the existing record’s Validic _id
:
DELETE https://api.validic.com/v1/organizations/{ORGANIZATION_ID}/users/{USER_ID}/routine/{VALIDIC_RECORD_ID}.json -H 'Content-Type': 'application/json' { "access_token": "YOUR_ORGANIZATION_ACCESS_TOKEN" }
How Validic Handles Timestamps and Timezones
“Consumer” organizations consuming data through Validic expect records to include both a timestamp and a offset as a string. When pushing data to Validic, it is your responsibility to first include the timezone in which the activity was recorded as the utc_offset
, then to convert your timestamp of when the activity was recorded to ISO 8601 format in UTC time as the timestamp
.
# Ruby Example your_timestamp = DateTime.now => #< DateTime: 2015-05-14T16:01:32-04:00 ((2457157j,72092s,110881000n),-14400s,2299161j) > utc_offset = your_timestamp.zone => "-04:00" timestamp = your_timestamp.new_offset(0).iso8601 => "2015-05-14T20:01:32+00:00"
Handling Custom Data
Outside of our standard attributes, Validic is capable of accepting new fields you define as part of your POST. To do so, set the extras field to be a JSON object and include your new field as part of that object.
Organizations consuming data through Validic will have to add an “expanded” parameter to their GET call and set it to “true” to see this extras data. Note, however, that when a “consumer” organization chooses to include your application as a source in their Validic marketplace, they will be given integration notes concerning the specifics of your data coming through Validic. This will discuss any extras data you will choose to send to Validic and any additional notes concerning your integration.
Note: It is normal that some data may not fall clearly in the Validic standard object schema. If that is the case, partners should make their best guess for how the mappings should work and send that mapping to Validic for review.
https://api.validic.com/v1/organizations/5176906c6deddac02c000001/users/51552cd7fded0807c4000017/fitness.json -H 'Content-Type': 'application/json' { "fitness": { "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "-05:00", "type": "Running", "intensity": "medium", "start_time": "2013-03-09T02:12:16-05:00", "distance": 5149.9, "duration": 1959, "calories": 350, "activity_id": "12345", "extras": { "stars": 3, "stride_length": 5 } }, "access_token": "YOUR_ORGANIZATION_ACCESS_TOKEN" }
That response:
{ "code": 201, "message": "Ok", "fitness": { "_id": "51552cd8fded0807c400002a", "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "-05:00", "type": "Running", "intensity": "medium", "start_time": "2013-03-09T02:12:16-05:00", "distance": 5149.9, "duration": 1959, "calories": 350, "extras": { "stars": 3, "stride_length" 5 }, "source": "sample_app", "source_name": "Sample App", "last_updated": "2013-03-10T07:12:16+00:00" } }
Flagging Validated Data
Many organizations consuming data from Validic treat data generated using a device differently than data manually entered from a user. To differentiate between the two they rely on the validated
flag as discussed in the enterprise documentation.
Validic Connect Partners who can verify that a record is generated by a device can do so by setting validated
to true and including the name of the device with which it was recorded as an extras field:
https://api.validic.com/v1/organizations/5176906c6deddac02c000001/users/51552cd7fded0807c4000017/fitness.json -H 'Content-Type': 'application/json' { "fitness": { "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "-05:00", "type": "Running", "intensity": "medium", "start_time": "2013-03-09T02:12:16-05:00", "distance": 5149.9, "duration": 1959, "calories": 350, "activity_id": "12345", "validated": true, "extras": { "device": "ACME Pedometer" } }, "access_token": "YOUR_ORGANIZATION_ACCESS_TOKEN" }
That response:
{ "code": 201, "message": "Ok", "fitness": { "_id": "51552cd8fded0807c400002a", "timestamp": "2013-03-10T07:12:16+00:00", "utc_offset": "-05:00", "type": "Running", "intensity": "medium", "start_time": "2013-03-09T02:12:16-05:00", "distance": 5149.9, "duration": 1959, "calories": 350, "validated": true, "extras": { "device": "ACME Pedometer" }, "source": "sample_app", "source_name": "Sample App", "last_updated": "2013-03-10T07:12:16+00:00" } }