Skip to content

User APIs

The user APIs simplify common processes like onboarding users against clearly stated terms, acquiring and enforcing informed consent, giving guardians access and controls for their children's data, and managing the use of third-party data. This section walks through a few of the most common flows to provide concrete examples of API use.

Picking user names

In the examples that follow, you'll see email addresses used to identify users. This is done to make the examples easier to read. You are free to choose any arbitrary, unique identifiers for your users, but it is recommended that you pick a scheme that doesn't use identifying information. If you want help with this reach out, and we're happy to get you grounded on best-practices.

First-party Onboarding#

Once you've configured your service with use and sharing rules, a common next-step is connecting Tranquil Data to the user-onboarding process. This ensures that users are accepting clear and personalized terms, that users are notified when those terms change, and that use and sharing of user data across your platform is done correctly against these terms.

In your website or application logic, you already have some flow that handles account creation. It probably asks for a username, password, and some additional context about each user. Depending on the application or vertical this might include location, date of birth, employer, health insurance plan, etc. The user is then asked to acknowledge a privacy policy (or some similar document) before proceeding. This is typically the first step where you integrate Tranquil Data. Instead of simply asking the user to check a box, you make a single API call to get all of the terms that personally apply to the user. Essentially, this is getting all of the summary and description language you configured, and dropping any pieces that don't apply based on the provided context, so that on the fly you can present a personalized "privacy nutrition label" to each user.

In the simplest version of this, the user isn't providing any context when they create an account:

curl -X PUT -H "Accept: application/json" -H "Content-Type: application/json" \
    "http://localhost:8890/user/terms/query" \
-d '{}'

This will return the complete set of terms that apply to all users by default. In a more interesting example, a user might create an account with some attributes that affect use and/or that is under some contractual relationship that changes terms. For this flow the app will verify the attributes and/or contractual relationship, and hit the same endpoint as above with the additional context:

curl -X PUT -H "Accept: application/json" -H "Content-Type: application/json" \
    "http://localhost:8890/user/terms/query" \
-d '{
        "attributes" : {"dob": "2015-09-13", "location": "US"},
        "contractualRelationship" : {
            "purposeId": "exchange.treatment",
            "termsId" : "exchange.treatment.somehospital"
        }
    }'

As a result, the set of terms changes, dropping purposes that are overridden based on the age, location, or contract, and adding details about which categories of data are shared under the contractual terms. The format returned by both examples is the same, making it simple to build a single look and feel for any arbitrary user context.

As an example, suppose a user onboards with a known location and date of birth. You would use the above call to retrieve the personalized terms based on those attributes, and when the user has accepted those terms, you'll make two API calls. The first creates the user, and the second acknowledges that the user has accepted the personal terms.

curl -X PUT -H "Content-Type: application/json" \
    "http://localhost:8890/user" \
-d '{
        "userId" : "carol@example.com",
        "attributes" : {"dob": "2019-09-13", "location": "US"}
    }'
curl -X PUT "http://localhost:8890/user/terms?userId=carol@example.com"

With the user tracked in Tranquil Data you will connect data to that user, enforce correct use of data against the terms the user just acknowledged, and give the user controls over how their data is used or shared. You also get a way to ensure that the user is up to date with terms. Each time a user logs back into your platform, you have a single API call to ask "did any terms that apply to this user expand so that I need to get the user's acceptance again?" There's a single API call to do this, and a single API call to get those terms again without having to repeat any details about the user:

curl -X GET -H "Accept: application/json" \
    "http://localhost:8890/user/status?userId=carol@example.com"
curl -X GET -H "Accept: application/json" \
    "http://localhost:8890/user/terms?userId=carol@example.com"
curl -X PUT "http://localhost:8890/user/terms?userId=carol@example.com"

If the first call returns true in the field reacceptRequired, then you make the second call to get the latest, personalized terms, show them to the user, and then make the third call (just as in the previous example) to track that the user acknowledged the new terms.

You may already have users onboarded that you want to bring onto Tranquil Data. You may also have a flow where front-end and back-end are separated and the back-end is only notified once the user has created their account. In either case, the APIs are designed to make it easy to support these flows incrementally and start by providing your users with a view into their personalized terms without other application changes.

First-party Discretionary Sharing#

As you saw in the configuration examples, you can define multiple purposes for discretionary sharing. These fall into platform-use opt-ins and fine-grained consents. Once a user exists in Tranquil Data, you can present these options to that user, and enforce sharing as consent is given, adjusted, or revoked. It is up to you how fine or course-grained the UX is that you present to your users, but we recommend that you define specific, fine-gained options to better ensure that user preferences are met and audit trails are meaningful.

In this example, our user consents to share their contact data with a clinical trial:

curl -X PUT -H "Content-Type: application/json" \
    "http://localhost:8890/user/consent" \
-d '{
        "userId" : "carol@example.com",
        "consents" : {
            "affirmativeConsents" : [ {
                "purposeId" : "consent.trials",
                "termsId" : "consent.trials.somehospital",
                "categoryIds" : [ "contact" ]
            } ]
        }
    }'

There are two things to note in this example. First, Some Hospital asked for contact and medication data, but the user has decided only to share their contact data at first. Giving a user this kind of fine-grained engagement at the start is a great way to build trust, and encourage them to share more as they feel comfortable. The second point to note is that there are now two ways that data about this user flows to Some Hospital: via contractual exchange and via consent. The decision trace will disambiguate these two flows, so it will be possible to explain not just what data went to a given party, but why each specific purpose-based flow allowed specific categories of data.

Child Protection#

An increasingly important capability of any data platform is to give guardians the ability to consent on behalf of their children, create accounts that given them access and control over a child's data, and turn off specific capabilities that they don't want applied to their children. There are two common flows that support these relationships. The first is one where a child has already created an account, and a guardian (verified via some mechanism outside of Tranquil Data) creates an account connected to their child:

curl -X PUT -H "Content-Type: application/json" \
    "http://localhost:8890/user" \
-d '{
        "userId" : "alice@example.com"
    }'
curl -X PUT -H "Content-Type: application/json" \
    "http://localhost:8890/user/guardians" \
-d '{
        "guardianId" : "alice@example.com",
        "child" : {
            "childId" : "carol@example.com"
        }
    }'

In this example the guardian has not supplied any details about themselves, and is not accepting the platform terms because they are not a user of the platform so their data is not being used or shared. Typically the platform would use the getGuardianOptions() call to show a guardian what they have access to and what they can turn off. If the guardian is a user of the platform, or later decides to become a user of the platform, the same flow applies and now the guardian has a single login to both interact with the platform and support their child.

The second common flow is one where a child never logs into the system themselves (e.g., a clinical trial for someone too young to interact with a computer), and so a parent will accept terms and consent on behalf of their child. In this example, a user is created for the guardian and the child, the guardian is shown personalized terms as above, and then the guardian accepts terms on behalf of their child:

curl -X PUT "http://localhost:8890/user/terms?userId=carol@example.com&acceptorId=alice@example.com"

Going forward, the guardian can be notified when terms change, and the guardian may grant discretionary consents as above by including the grantorId field. At some point in the future, if the child becomes an active participant on the platform, the guardian relationship persists but now the child may have the option for driving discretionary consent.

Third-party Data Handling#

To this point the examples have been focused on first-parties and their data, or guardians of first-parties who share limited data. Most platforms, however, have a significant amount of third-party data through back-end (B2B) contracts. These users may not know that their data is present on a given platform, and likely have not been asked to agree to any platform-specific terms, so use and sharing of their data can only be done via the terms of the back-end contract.

To support third-party data, start by ensuring that each B2B relationship has a defined set of contractual exchange terms. As you accept data from a given party, use the APIs to create users associated with the records in the data-sechange and make sure that those users have the appropriate contractual relationship (as above), but don't call the API to mark those users as having accepted terms. These users are now recognized as third-party users, and their data will only be governed by the terms of the associated contract. Any use or sharing outside of those terms will be denied.

In this way, a platform always knows what data they have about a given third-party under any specific set of terms. There are now two ways to interact with third-party users should they ever come to a platform. One is to allow those users access to their data and rights (e.g., under GDPR) to have their data removed from the platform. The other is to give those users the choice to become first-party users by accepting terms, making it simple to onboard users with data that is already present.