Configuration APIs
The config APIs suport and automate the functionality exposed to non-technical users via the configuration Web UI. There are individual functions to work with each aspect of configuration, as well as bulk operations to fetch and set a full end-to-end configuration (useful for backup in-production, or populating CI tests). What follows here are simple examples of how to use the most common functions.
Categories#
Multiple Categories and Fields can be created, updated, or retrieved in a single call. In this example, three categories are created to define specific types of data that is referenced throughout the API examples:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/categories" \
-d '{
"categories" : [ {
"stableId" : "contact",
"name" : "Contact",
"fields" : [ {
"stableId" : "contact.name",
"name" : "Name"
},{
"stableId" : "contact.phone",
"name" : "Phone"
}, {
"stableId" : "contact.email",
"name" : "Email"
} ]
}, {
"stableId" : "financial",
"name" : "Financial",
"fields" : [ {
"stableId" : "financial.ccnumber",
"name" : "Credit Card Number"
} ]
}, {
"stableId" : "medication",
"name" : "Medication",
"fields" : [ {
"stableId" : "medication.name",
"name" : "Name"
}, {
"stableId" : "medication.dose",
"name" : "Dose"
} ]
}, {
"stableId" : "credentials",
"name" : "Credentials",
"fields" : [ {
"stableId" : "credentials.email",
"name" : "Email"
} ]
} ]
}'
Throughout the APIs the pattern is that name fields are human-readable, may be repeated, and may be changed at any point. The values for stableId, however, must never change and each stable identifier must be globally unique. The set of characters valid for a stable identifier are the alpha-numerics and the period, dash, and underscore characters.
Picking stable identifiers
A "stable identifier" is just some unique string that isn't going to change. These are used by the context model to allow the names shown in the UI to change without affecting the structure of rules or data mapping. In these examples strings are concatenated, in a smilar fashion the pattern that the UI uses. In practice you can use any scheme, like UUIDs, that is natural to your environment as long as it guarantees uniqueness.
Neither the names nor the stable identifiers dictate any specific datastore schema or document structure. The mappings from configuration category to schema fields are defined via the mapping API.
Platform Use#
Platform Use defines both core and opt-in Purposes, with descriptions and valid Categories. In this example, three purposes are created that are core to all platform users, and one purpose is created which can only be asserted once a user opts-in:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/platform-use" \
-d '{
"purposes" : [ {
"name" : "Promotions",
"summary" : "Direct marketing about promotional opportunities",
"stableId" : "use.promotions",
"categoryIds" : [ "contact" ],
"optIn" : true
}, {
"name" : "Billing",
"summary" : "Support billing tasks for platform customers",
"stableId" : "use.billing",
"categoryIds" : [ "contact", "financial" ]
}, {
"name" : "Targeted Ads",
"summary" : "Advertisements targeting a specific group",
"stableId" : "use.targetedads",
"categoryIds" : [ "contact" ]
}, {
"name" : "Fulfillment",
"summary" : "Help in the process of providing to users their prescriptions",
"stableId" : "use.fulfillment",
"categoryIds" : [ "contact", "medication" ]
} ]
}'
Providing human-readable details
Most of the components in configuration have (optional) summary and fullDetails fields. These are a place to provide (respectively) one-linerers and long-form description. Think of these both as useful documentation for technical and non-technical roles to communicate, and as part of the Customer Experience during onboarding when personalized terms are presented. Typically this language is provided by a legal or privacy role via the UI, so most the examples in this section don't include them as the focus is on the functionality of the APIs.
This says that all first-party users must acknowledge that specific categories of their data will be used for the purpose of "billing" and "targettedads". As a result, the platform team gets a clear definition for correct use, and can use the APIs defined in other sections to validate data use for this purpose. It also means that (e.g.) an OAuth token can be issued that is only valid for one or more of these purposes, which will restrict use to these categories.
Platform Sharing#
Following on the Platform Use example above, in this example the internal use "billing" is connected to external sharing with parties who get data to support this purpose:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/platform-sharing" \
-d '{
"purposes" : [ {
"name": "Billing",
"stableId" : "sharing.billing",
"platformUsePurposeId" : "use.billing",
"categoryCeilingIds": [ "contact", "financial" ],
"thirdParties" : [ {
"name" : "Stripe",
"stableId" : "sharing.billing.stripe",
"serviceProvider" : true
} ]
}, {
"name" : "Login",
"stableId" : "sharing.login",
"categoryCeilingIds" : [ "contact" ],
"thirdParties" : [ {
"name" : "Facebook",
"stableId" : "sharing.login.facebook",
"serviceProvider" : false
} ]
} ]
}'
This creates new Purposes that can be asserted for sharing with any of the listed Third-Parties. "Billing" is connected it to the Platform Use Purpose named "billing", while "Login" is purely about sharing data for supporting third-party login. The "ceiling" names the maximum set of categories that can be shared under this Purpose, and may not exceed what the Platform Use defines. In-turn, each Third-Party may have access to this set of categories (as in this example) or the set of categories can be narrowed further.
Platform Overrides#
Overrides may be applied to both Platform Use and Platform Sharing Purposes. In this example, any marketing Purposes would be dropped from the allowed set for anyone under 13 or anyone who lives in an EU country:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/platform-use/overrides" \
-d '{
"overrides" : [ {
"name" : "MarketingAgeLimit",
"propertyName" : "age",
"values" : [ "13" ],
"allowedPurposeIds" : [ "use.billing", "use.fulfillment" ]
}, {
"name" : "MarketingEULimit",
"propertyName" : "location",
"values" : [ "FR", "DE" ],
"allowedPurposeIds" : [ "use.billing", "use.fulfillment" ]
} ]
}'
UserAccess#
User Access defines rights for Users and their Guardians, including overrides for Users based on age or location. In this example, core rights are defined for all users of the platform:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/user-access" \
-d '{
"categoryIds" : [ "contact", "financial", "medication" ]
}'
Following on, in this example a Child is considered anyone under 18, and any associated Guardians may turn off specific Third-Party flows for their Child's data:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/user-access/guardian" \
-d '{
"thresholdAge" : 18,
"allowedToDisable" : [ {
"purposeId" : "sharing.login",
"thirdPartyIds" : [ "sharing.login.facebook" ]
} ],
"categoryIds" : [ "contact", "financial", "medication" ]
}'
Contractual Exchange#
Contracts are put in-place to define rights and obligations on third-party data exchange. For instance, a user might sign up for a digital health application that has a B2B contract with a hospital in support of treatment. The contract allows patients of that treatment to onboard under the protection of its terms. In this example, that contract disallows billing and marketing purposes, and gives Some Hospital access to patient contact and medication data:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/contractual-exchange" \
-d '{
"purposes" : [ {
"name" : "Treatment",
"stableId" : "exchange.treatment",
"terms" : [ {
"name" : "Some Hospital",
"stableId" : "exchange.treatment.somehospital",
"contractAccessCategoryIds" : [ "contact", "medication" ],
"platformUsePurposeIds" : [],
"platformSharingPurposeIds" : [ "sharing.login" ]
} ]
} ]
}'
As in the Overrides above, the Platform Use and Platform Sharing Purposes are defining a subset of valid use and sharing, often dropping things like "AI Training" or "Advertising." A common implementation model is to grant security credentials to API endpoints, and use Tranquil Data to ensure that any Contract Entity is only getting the right subset of data, both to protect the user and platform, and to protect the Entities who want to demonstrate that they didn't acrue risk by acciedentally receiving data outside of their contract terms.
Consented Sharing#
Consents allow users to share data for specific Purposes. Typically there is some legal agreement in-place that governs this sharing, but unlike Contractual Exchange, sharing is one-way based on the categories that a user allows, and there are no overrides involved. In this example, a consent is defined to share into a clinical trial that a user may, on their own, decide to be part of:
curl -X PUT -H "Content-Type: application/json" \
"http://localhost:8890/config/consented-sharing" \
-d '{
"purposes" : [ {
"name" : "Trials",
"summary" : "Conents to share with organizations running clinical trials",
"stableId" : "consent.trials",
"terms" : [ {
"name" : "Some Hospital",
"summary" : "Study that is designed to help users manage medication for a specific condition",
"stableId" : "consent.trials.somehospital",
"requestedCategoryIds" : [ "contact", "medication" ]
} ]
} ]
}'
A user would now be able to consent to sharing their contact and medication data through this consent, and in return would expect help managing their medications.