4. Data Debits

Data Debits

PDA Data Debits are the cornerstone of consented data exchange. It is the only way data can be retrieved from the PDA by anyone else than the owner and enforces a strictly defined format defining the specific data requested for the user to review and approve. Read more on the Data Debit API.

Fetch Data Debits

You can fetch the available Data Debits by using the next function:

HATDataDebitsService().getAvailableDataDebits(
            userToken: userToken,
            userDomain: userDomain,
            succesfulCallBack: gotDataDebits,
            failCallBack: failedGettingDataDebits)
  • userToken is the user's token to authenticate with the PDA.

  • userDomain is the user's PDA address used to form the url to fetch the available Data Debits.

  • succesfulCallBack is a callback used when the request is successful with a type of (List<DataDebitObject>, String?) -> Unit).

    The first parameter is a list of DataDebitObject. This is the structure of Data Debits. More on that in the next section.

    The second parameter is an optional String, the refreshed user token that the PDA returns.

  • failCallBack is a callback that is used when the request has failed. The type of the function is ((HATError) -> Unit). HATErroris a custom object describing the errors that have occurred during the querying of the PDA.

A successful response will have statusCode 200 and look like this:

[
    {
        "dataDebitKey": "97a0748f-bf81-4aaa-8f39-97ac2557d920",
        "dateCreated": "2018-01-02T15:22:42+0000",
        "permissions": [
            {
                "dateCreated": "2018-01-02T15:22:42+0000",
                "purpose": "This Data Debit is in a legacy format, and the HAT App is unable to display all the information associated with it fully. This may include a logo, title and full description",
                "start": "2018-01-02T15:23:02.000Z",
                "period": 86400000,
                "cancelAtPeriodEnd": true,
                "termsUrl": "",
                "bundle": {
                    "name": "97a0748f-bf81-4aaa-8f39-97ac2557d920",
                    "bundle": {
                        "iphone/locations": {
                            "endpoints": [
                                {
                                    "endpoint": "iphone/locations",
                                    "mapping": {
                                        "accuracy": "accuracy",
                                        "latitude": "latitude",
                                        "longitude": "longitude",
                                        "timestamp": "timestamp",
                                        "lastUpdated": "lastUpdated",
                                        "locations.accuracy": "locations.accuracy",
                                        "locations.latitude": "locations.latitude",
                                        "locations.longitude": "locations.longitude",
                                        "locations.timestamp": "locations.timestamp"
                                    },
                                    "filters": []
                                }
                            ]
                        },
                        "rumpel/locations/ios": {
                            "endpoints": [
                                {
                                    "endpoint": "rumpel/locations/ios",
                                    "mapping": {
                                        "speed": "speed",
                                        "course": "course",
                                        "altitude": "altitude",
                                        "latitude": "latitude",
                                        "longitude": "longitude",
                                        "dateSynced": "dateSynced",
                                        "dateCreated": "dateCreated",
                                        "dateCreatedLocal": "dateCreatedLocal",
                                        "verticalAccuracy": "verticalAccuracy",
                                        "horizontalAccuracy": "horizontalAccuracy"
                                    },
                                    "filters": []
                                }
                            ]
                        }
                    }
                },
                "accepted": false,
                "active": false,
                "end": "2018-01-03T15:23:02.000Z"
            }
        ],
        "requestClientName": "Data Exchange",
        "requestClientUrl": "https://dex.hubofallthings.com/",
        "requestClientLogoUrl": "https://dex.hubofallthings.com/assets//images/dex.png",
        "active": false,
        "accepted": false,
        "start": "2018-01-02T15:23:02.000Z",
        "end": "2018-01-03T15:23:02.000Z",
        "permissionsActive": null,
        "permissionsLatest": {
            "dateCreated": "2018-01-02T15:22:42+0000",
            "purpose": "This Data Debit is in a legacy format, and the HAT App is unable to display all the information associated with it fully. This may include a logo, title and full description",
            "start": "2018-01-02T15:23:02.000Z",
            "period": 86400000,
            "cancelAtPeriodEnd": true,
            "termsUrl": "",
            "bundle": {
                "name": "97a0748f-bf81-4aaa-8f39-97ac2557d920",
                "bundle": {
                    "iphone/locations": {
                        "endpoints": [
                            {
                                "endpoint": "iphone/locations",
                                "mapping": {
                                    "accuracy": "accuracy",
                                    "latitude": "latitude",
                                    "longitude": "longitude",
                                    "timestamp": "timestamp",
                                    "lastUpdated": "lastUpdated",
                                    "locations.accuracy": "locations.accuracy",
                                    "locations.latitude": "locations.latitude",
                                    "locations.longitude": "locations.longitude",
                                    "locations.timestamp": "locations.timestamp"
                                },
                                "filters": []
                            }
                        ]
                    },
                    "rumpel/locations/ios": {
                        "endpoints": [
                            {
                                "endpoint": "rumpel/locations/ios",
                                "mapping": {
                                    "speed": "speed",
                                    "course": "course",
                                    "altitude": "altitude",
                                    "latitude": "latitude",
                                    "longitude": "longitude",
                                    "dateSynced": "dateSynced",
                                    "dateCreated": "dateCreated",
                                    "dateCreatedLocal": "dateCreatedLocal",
                                    "verticalAccuracy": "verticalAccuracy",
                                    "horizontalAccuracy": "horizontalAccuracy"
                                },
                                "filters": []
                            }
                        ]
                    }
                }
            },
            "accepted": false,
            "active": false,
            "end": "2018-01-03T15:23:02.000Z"
        }
    }
]
  • dataDebitKey is the data debit key, defined when creating the Data Debit. It's unique across PDA.

  • dateCreated is the date that this Data Debit was created. The date is in ISO format as String.

  • permissions is the permissions info for this Data Debit: What URLs it has access, from which date to which date, etc.

    1. dateCreated is the date that this Data Bundle was created. The date is in ISO format as String.

    2. purpose is a short description for the Data Bundle explaining its purpose. Optional

    3. start is the start date that this Data Bundle has become active. The date is in ISO format. Optional

    4. end is the start date that this Data Bundle will surpass the assigned duration stated in period. The date is in ISO format. Optional

    5. cancelAtPeriodEnd is a flag indicating if the permissions will auto cancel when the Data Debit ends.

    6. termsUrl is a URL to show the user the terms and conditions for this Data Bundle .

    7. period is the duration that the Data Bundle can be active. Value in seconds.

    8. active indicates if the Data Bundle is active.

    9. accepted indicates if the Data Bundle has been accepted.

    10. bundle is where the permissions are defined; what endpoints this Data Debit will have access to, which fields from that endpoint, a name, under what circumstances etc.:

      1. name is the name of the bundle. This has to be unique.

      2. bundle is a Dictionary of typeDictionary<String, DataOfferRequiredDataDefinitionBundleKeyV2>, it allows for defining multiple different endpoints by giving a different name. This means that you can combine multiple and different endpoints, each with its own requirements:

        1. endpoints is an array of DataOfferRequiredDataDefinitionBundleKeyEndpointsV2 containing the PDA URLs to include, a desired mapping or filtering for the fields:

          1. endpoint is the actual endpoint that you would like access to, for example rumpel/profile .

          2. mapping is the selected fields from this endpoint that you would like to have in the Data Debit.

          3. filters lets you filter a field by some requirements. For example, you can define something like age between 18 and 35. Optional

            1. field is the field that you would like to apply filtering to

            2. transformation is the transformation type to be done on the field. There are 4 different options: Optional

              1. identity keeps the value as-is, effect is the same as if transformation was not defined

              2. datetimeExtract with part – extract part of a date from an ISO 8601 formatted date field

              3. timestampExtract with part – extract part of a date from a UNIX timestamp date field

              4. searchable convert the field to searchable text. Must be used together with the find operator below 3. operator is the type of the filtering. There are 4 different types, each with a different structure. You can read more into it and check out Operator class in HAT API Android here. Optional

                1. find allows you to search a particular String, field name: search. Also, you can nest more operators, field name: operator.

                2. contains allows you to search if a particular substring is contained into a String, field name: value of type Bool.

                3. between allows you to search if an Int is between 2 values named upper and lower.

                4. in together with value field set to check if field is in (is contained by) value.

          4. links each endpoint can contain other endpoint objects. Optional

        2. orderBy lets you define the field to order the data. Optional

        3. ordering lets you define the ordering of the data; ascending or descending. Optional

        4. limit is an Int which lets you define how many data points you like from this endpoint. Optional

    11. conditions check bundle for the structure. The purpose is to allow the Data Bundle to have some conditions that have to be fulfilled first, attached to it in order to become `active`. Optional

  • requestClientName is the name of the client that created this Data Debit

  • requestClientUrl is the URL to the website of the client

  • requestClientLogoUrl is a URL for the logo of the client

  • requestDescription is a description for the Data Debit. Optional

  • requestApplicationId If the Data Debit is tied to an Application this will be the application id. Otherwise it's nil. Optional

  • active indicates if the Data Debit is active

  • accepted indicates if the Data Debit has been accepted

  • start is the date that this Data Debit has started. The date is in ISO format as String. Optional

  • end is the date that this Data Debit will end. The date is in ISO format as String. Optional

  • permissionsActive Latest active permissions. Look at permissions. Optional

  • permissionsLatest Latest permissions. Look at permissions.

A request that has failed will look like this:

{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
  • error is the error that has occurred

  • message is a more descriptive message about the error that has occurred

Create Data Debit

You can also create a Data Debit by using the function below:

val endpoint = DataOfferRequiredDataDefinitionBundleKeyEndpointsV2(endpoint: "rumpel/profile")
val bundle = DataOfferRequiredDataDefinitionObjectV2(
  name: "test1",
  bundle: arrayList(rumpel/profile" to DataOfferRequiredDataDefinitionBundleKeyV2(endpoints: arrayList(endpoint))))

val dataDebitToCreate = DataDebitCreationObject(
  dataDebitKey: "test1",
  purpose: "none",
  start: "2018-11-14T23:51:40+0000",
  period: 432000000,
  termsUrl: "none",
  cancelAtPeriodEnd: false,
  requestClientName: "none",
  requestClientUrl: "none",
  requestClientLogoUrl: "none",
  bundle: bundle)

  HATDataDebitService().createDataDebit(
    dataDebitID: dataDebitID,
    bundle: dataDebitToCreate,
    userToken: userToken,
    userDomain: userDomain,
    succesfulCallBack: dataDebitCreated,
    failCallBack: dataDebitCreationFailed)
  )
  • endpointis the PDA endpoint you would like access to. DataOfferRequiredDataDefinitionBundleKeyEndpointsV2 also allows

    you to set up mapping and filtering if you wish. The minimum requirement is to specify the endpoint you want to use.

  • bundle is a grouping of different endpoints under one category. You can define one category, with the nameparameter, but you can have multiple endpoints in the bundle section. Note that name has to be unique.

  • dataDebitKey is a key to the specific Data debit. This has to be unique.

  • purpose is a small description of the purpose for this Data Debit

  • start is the start date that this Data Debit can become available. The date is in ISO format.

  • period is the duration that the Data Debit will be active in seconds

  • termsUrl is the URL of the terms and conditions for this Data Debit

  • cancelAtPeriodEnd is a bool flag for if the Data Debit should be cancelled with the period passes

  • requestClientName is the name of the client that created this Data Debit

  • requestClientUrl is the URL to the client's website

  • requestClientLogoUrl is the URL for the client's logo

  • bundle is the description of what endpoints we want to have access to

A successful response will have statusCode 201 and look like this:

{
    "dataDebitKey": "test1",
    "dateCreated": "2018-11-14T23:51:40+0000",
    "permissions": [
        {
            "dateCreated": "2018-11-14T23:51:40+0000",
            "purpose": "none",
            "start": "2018-11-14T23:51:40+0000",
            "period": 432000000,
            "cancelAtPeriodEnd": false,
            "termsUrl": "none",
            "conditions": {
                "name": "data-debit-id-test-name",
                "bundle": {
                    "test": {
                        "endpoints": [
                            {
                                "endpoint": "rumpel/profile"
                            }
                        ]
                    }
                }
            },
            "bundle": {
                "name": "data-debit-id-test1",
                "bundle": {
                    "test": {
                        "endpoints": [
                            {
                                "endpoint": "rumpel/profile"
                            }
                        ]
                    }
                }
            },
            "accepted": false,
            "active": false,
            "end": null
        }
    ],
    "requestClientName": "none",
    "requestClientUrl": "none",
    "requestClientLogoUrl": "none",
    "requestDescription": "none",
    "active": false,
    "accepted": false,
    "start": "2018-04-18T09:26:57.000Z",
    "end": null,
    "permissionsActive": null,
    "permissionsLatest": {
      "dateCreated": "2018-11-14T23:51:40+0000",
      "purpose": "none",
      "start": "2018-11-14T23:51:40+0000",
      "period": 432000000,
      "cancelAtPeriodEnd": false,
      "termsUrl": "none",
      "conditions": {
          "name": "data-debit-id-test-name",
          "bundle": {
              "test": {
                  "endpoints": [
                      {
                          "endpoint": "rumpel/profile"
                      }
                  ]
              }
          }
      },
      "bundle": {
          "name": "data-debit-id-test1",
          "bundle": {
              "test": {
                  "endpoints": [
                      {
                          "endpoint": "rumpel/profile"
                      }
                  ]
              }
          }
      },
      "accepted": false,
      "active": false,
      "end": null
    }
}

Read here for an explanation of what the above structure means.

A request that has failed will look like this:

{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
  • error is the error that has occurred

  • message is a more descriptive message about the error that has occurred

Approve Data Debits

Not all apps can directly approve Data Debits. This has to do with the permissions of the apps. Currently, only HAT App and web Rumpel can approve Data Debits. Due to the restrictions this guide will explain how to use the generic way of doing it, that will work on all apps. To approve a Data Debit you have to open the following URL in a browser:

"https://$hatAddress/#/data-debit/$dataDebitID/quick-confirm?redirect=$appScheme://$dataDebitHost&fallback=$appScheme/dataDebitFailure"
  • hatAddress is the (fully qualified domain) address of the PDA, e.g. postman.hubat.net

  • dataDebitID is the data debit id that you want to approve

  • appScheme is the URL to which the user should be sent after completing authentication. Optional. For an Androidapplication that would probably be: $applicationName://success and has to be added in the AndroidManifest file of the

    project in Xml as data host and scheme. You can read more here.

  • dataDebitHost is a string after the :// part in the app url Scheme. For example dataswift-sandbox://dataDebitHost. With the dataswift-sandbox:// Android will launch your app. With the dataDebitHost you will know that this URL is specifically for the Data Debits.

The process is the same as when logging in the user. The browser will open, the user will have to complete their password, and then one of the 2 redirect URL will be called, depending on whether the request was successful or has failed for some reason. The app should know how to handle both scenarios. You can read more here.

Get Data Debit values

You can fetch the values of a specific Data Debit by using the next function:

HATDataDebitsService().getDataDebitValues(
  dataDebitKey: dataDebitKey,
  userToken: userToken,
  userDomain: userDomain,
  succesfulCallBack: gotDataDebits,
  failCallBack: failedGettingDataDebits)
  • dataDebitKey is the data debit key that we want the values from

  • userToken is the user's token to authenticate with the PDA

  • userDomain is the user's PDA address used to form the url to fetch the values of the Data Debit.

  • succesfulCallBack is a callback function, that is called when the request is successful, with a type of((HATDataDebitValuesObject, String?) -> Unit). This is the structure of Data Debit Values. More on that in the next section.

    The second parameter is an optional String, the refreshed user token that the PDA returns.

  • failCallBack is a callback that is used when the request has failed. The type of the function is ((HATError, String?) -> Unit). HATErroris a custom object describing the errors that have occurred during the querying of the PDA. The second parameter is the dataDebitKey.

A successful response will have statusCode 200 and look like this:

  {
    "bundle": {
        "profile": [
            {
                "endpoint": "rumpel/profile",
                "recordId": "137e0409-effc-454f-b1f0-56fe87ad7762",
                "data": {
                    "name": "",
                    "nick": "",
                    "photo_url": "https://postman.hubat.net/api/v2.6/files/content/rumpel1537454603415.jpg"
                }
            }
        ],
        "notables": [
            {
                "endpoint": "rumpel/notablesv1",
                "recordId": "d1d26a7d-0c7f-4ba2-8caa-13a4b5671444",
                "data": {
                    "kind": "note",
                    "author": {
                        "name": "",
                        "phata": "postman.hubat.net",
                        "nickname": "",
                        "photo_url": ""
                    },
                    "shared": true,
                    "message": "oooo",
                    "shared_on": [
                        "phata"
                    ],
                    "created_time": "2018-11-08T11:24:58Z",
                    "updated_time": "2018-11-08T11:24:58Z"
                }
            }
        ]
      }
    }

Inside the bundle there are 2 different values: profile and notables. Those 2 values are Arrays that contain the actual data for each endpoint specified when this Data Debit was created. In this example the 2 structures are the profile and notables.

A request that has failed will look like this:

{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
  • error is the error that has occurred

  • message is a more descriptive message about the error that has occurred

Last updated