Custom Marketplace

What is the Custom Marketplace?

The Inform Marketplace is where users browse and connect health apps and devices so their data will be available to your system. The Custom Marketplace is one of three "flavors" of the Marketplace and it supports Cloud and Cellular sources only.

The Standard Marketplace is a Inform API JSON endpoint that returns all of the details you will need to build your own marketplace or connection list. Using the results you get from the Custom Marketplace, you can build your own user experience that is styled the way you want. The JSON is the same data we use to build our Standard Marketplace so there won't be a discrepancy in how the connection process works.

You have full control to build the behavior that your users will need -- just keep in mind that users will still need to be routed to the appropriate source for Cloud connections and that user experience is controlled by the source.

📌

Are you looking for an experience that supports mobile?

If you're looking for a customizable solution that supports Cloud, Cellular, and Mobile, then Unified Sources is for you.


What is the User Experience like?

The user experience is whatever you'd like it to be. Since Inform is simply providing you with details in a JSON format, you can use those details -- plus any that you want to add -- to create a connection workflow that works best for your users. All the styling and behavior is built by you.

If you'd like to get an idea of what a typical workflow might look like, then have a look at how our Standard Marketplace works.

The Standard Marketplace is designed to support Cloud and Cellular sources, just like the Custom Marketplace, and it provides a full, but basic, experience that you can use right away as either your own connection workflow or as inspiration for a custom workflow that you build using the Custom Marketplace.

📘

The Custom Marketplace is great for Cellular sources

The Custom Marketplace is a great option if you want to use Cellular sources. With the Custom Marketplace, you can show or hide any sources that it returns.

Want to display Cellular Sources and let your users enter in their device identifier? You can do that with the Custom Marketplace.

Want to get fancy and hide the Cellular Sources so your users don't have to worry about entering complicated device identifiers? You can do that with the Custom Marketplace too (along with the appropriate Direct Connection endpoint for the Cellular source).

Guide the user through the connection of their Cellular and Cloud Sources using the Custom Marketplace details to power your user experience, then be sure to display feedback to them based on whether you receive a message parameter in your redirect. If no parameter is present, the connection succeeded. If ?message=access_denied is present, the user cancelled or denied permissions. Note: In rare edge cases, a connection failure may redirect without a message parameter—always verify the connection status via the Marketplace JSON. If a disconnect URL displays for the user, then the connection was successful. You will receive a connection event in the Streaming API for all successful Custom Marketplace connections, if your stream is set up to receive them.

If your user ever needs to disconnect from a source, they will need to navigate back to the Custom Marketplace where you should display a Disconnect button for any connected sources. You'll be able to tell whether a source is connected or not from the JSON returned by the Custom Marketplace.

❗️

Please plan your user documentation and user experience so that users can get back to the Custom Marketplace to disconnect, when appropriate.


How do I use the Custom Marketplace?

The Custom Marketplace JSON can be requested simply by adding &format=json to the end of the user's marketplace URL, which you can get from the user's profile.

For example, if the user's marketplace url is:

https://syncmydevice.com/?token=4deee4c7c81e9b652d22c8999beaf7c972daa513c6cf6aaa6af636f8117bf929

then that user's Custom Marketplace can be accessed at:

https://syncmydevice.com/?token=4deee4c7c81e9b652d22c8999beaf7c972daa513c6cf6aaa6af636f8117bf929&format=json

BUT you're not done yet...because....

🚧

Redirect URI is Required

When using the Custom Marketplace, clients must append a redirect_uri query parameter to the connect_url and disconnect_url provided in the Custom Marketplace JSON response.

The redirect_uri ensures that users are properly redirected following the connection process, otherwise, the user will be redirected to the Standard Marketplace and not your super awesome custom connection experience.

Any redirect_uri that you specify must begin with https:// or the resulting URL will fail. You should also url-encode your uri.

Here's an example of how to indicate the redirect_uri for a connection. In this example the user will be redirected to https://www.google.com (don't do this, of course -- this is just an example):

https://syncmydevice.com/?token=4deee4c7c81e9b652d22c8999beaf7c972daa513c6cf6aaa6af636f8117bf929&format=json&redirect_uri=https%3A%2F%2Fwww.google.com

Last, be sure that you can handle the message parameter that may be appended to your redirect_uri. On success, no parameter is added—verify the connection via the marketplace JSON as you would expect a disconnect link on that vendor connection for the user. On failure or cancellation, ?message=access_denied is typically appended. Best practice: Always verify the actual connection state via the Marketplace JSON rather than relying solely on the presence or absence of the message parameter.

Setting Scope Overrides

📘

This feature is currently supported for Google Health only

We plan to expand scopes_override support to other sources in the future. For now, adding this parameter to a connect_url for any source other than Google Health has no effect.

By default, the scopes requested from a user during a custom marketplace connection are whatever your organization has configured with us. If you're not sure what's set for your organization you can always ask our Customer Support team.

If you need more control on a per-connection basis, per user, you can override those default scopes at connection time by adding a scopes_override query parameter to the connect_url.

This feature is available in the custom marketplace only. It is not yet supported in the unified marketplace.

A few things to know about how scopes_override works:

  • Scope names must exactly match the source's own scope names. See the "Valid Scopes by Source" section below.
  • To request more than one scope, separate them with commas.
  • You should also url-encode the scopes.
  • A small set of required scopes (like Settings) is always requested no matter what, since Inform needs those to function. That means you may still see an extra scope or two being requested depending on the source, if we need them for data processing.
  • If a scope you pass is invalid, or isn't enabled for your org, it's silently dropped and the connection continues with whatever valid scopes remain (we log the drop on our end, but the user won't see an error for it).
  • If scopes_override is empty, it's ignored, and your org's configured scopes are used instead. Same thing if you exclude scopes_override ; your org's configured scopes are used in that case.

Valid Scopes by Source

The scope names you pass in scopes_override must exactly match one of the values the source supports below. Any scope not listed here is treated as invalid and will be silently dropped from the request.

Today, Google Health is the only source that supports scopes_override, but we'll add rows to this table as we extend support to other sources.

SourceScopeDescriptionResource Type
google_healthhttps://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
url-encoded: https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.activity_and_fitness.readonly
Activity datasummaries, workouts, intraday
google_healthhttps://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
url-encoded: https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.health_metrics_and_measurements.readonly
Vitals and body measuresmeasurements
google_healthhttps://www.googleapis.com/auth/googlehealth.sleep.readonly
url-encoded: https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.sleep.readonly
Sleep detailssleep
google_healthhttps://www.googleapis.com/auth/googlehealth.nutrition.readonly
url-encoded: https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.nutrition.readonly
Daily nutrient summaries and food itemsnutrition

Examples

Here's what the override looks like in practice. Assume this is your base connect URL:

https://syncmydevice.com/connect/google_health?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d

Passing a single scope:

https://syncmydevice.com/connect/google_health?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d&scopes_override=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.sleep.readonly

Result: only the Sleep scope, plus the required Settings scope, is requested.

Passing two scopes (comma-separated):

https://syncmydevice.com/connect/google_health?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d&scopes_override=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.activity_and_fitness.readonly%2Chttps%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.sleep.readonly

Result: Activity, Sleep, and Settings scopes are requested.

Passing two scopes where one is invalid or not configured for your org:

https://syncmydevice.com/connect/google_health?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d&scopes_override=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgooglehealth.activity_and_fitness.readonly%2CNOT_A_SCOPE

Result: NOT_A_SCOPE is dropped. Only Activity and Settings scopes are requested.

Passing an empty scopes list:

https://syncmydevice.com/connect/google_health?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d&scopes_override=

Result: the parameter is ignored, and your org's normally configured scope list is used.

Passing a list with only invalid scopes:

https://syncmydevice.com/connect/google_health?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d&scopes_override=INVALID%2Calso_invalid

Result: only the required Settings scope is requested, nothing else.




What Does the Custom Marketplace look like?

Whatever you like! You're going to be building the user experience and styling it however you'd like.

Here's an example of what you get from the Custom Marketplace. These details will help you with your display so that you don't have to go hunt down a bunch of info like source name, logo images, and the like. We'll maintain all of this info for you.

You just have to build the user experience to display what you want from this info and route the user properly for connections and disconnections.

https://syncmydevice.com/?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d&format=json&redirect_uri=https%3A%2F%2Fwww.google.com

[
    {
        "type": "omron",
        "connected": true,
        "logo_url": "//assets.prod.validic.com/cmapi/images/sources/omron.png",
        "disconnect_url": "https://syncmydevice.com/connect/omron?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d"
    },
    {
        "type": "polar",
        "connected": true,
        "logo_url": "//assets.prod.validic.com/cmapi/images/sources/polar.png",
        "disconnect_url": "https://syncmydevice.com/connect/polar?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d"
    },
    {
        "type": "fitbit",
        "connected": true,
        "logo_url": "//assets.prod.validic.com/cmapi/images/sources/fitbit.png",
        "disconnect_url": "https://syncmydevice.com/connect/fitbit?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d"
    },
    {
        "type": "garmin",
        "connected": true,
        "logo_url": "//assets.prod.validic.com/cmapi/images/sources/garmin.png",
        "disconnect_url": "https://syncmydevice.com/connect/garmin?token=ae4fdfd364e42137af14b207eSAMPLEbcdefaae7b99e3e49361SAMPLE1eb0d"
    },
  ...
]

Did this page help you?