# 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](https://docs.dataswyft.com/build/dataswyft-one-apis/data-api/data-debits).

## Fetch Data Debits

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

```kotlin
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)`. `HATError`is 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:

```javascript
[
    {
        "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***&#x20;
  3. `start` is the start date that this `Data Bundle` has become active. The date is in `ISO` format. ***Optional***&#x20;
  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***&#x20;
  5. `cancelAtPeriodEnd` is a flag indicating if the permissions will auto cancel when the `Data Debit` ends.&#x20;
  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.&#x20;
  8. `active` indicates if the `Data Bundle` is active.&#x20;
  9. `accepted` indicates if the `Data Bundle` has been accepted.&#x20;
  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.:&#x20;
      1. `name` is the name of the `bundle`. This has to be unique.&#x20;
      2. `bundle` is a `Dictionary` of type`Dictionary<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:&#x20;
         1. `endpoints` is an array of `DataOfferRequiredDataDefinitionBundleKeyEndpointsV2` containing the `PDA URLs` to include, a desired `mapping` or `filtering` for the fields:&#x20;
            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&#x20;
               2. `transformation` is the transformation type to be done on the field. There are 4 different options: ***Optional***&#x20;
                  1. `identity` keeps the value as-is, effect is the same as if transformation was not defined&#x20;
                  2. `datetimeExtract` with `part` – extract part of a date from an ISO 8601 formatted date field&#x20;
                  3. `timestampExtract` with `part` – extract part of a date from a UNIX timestamp date field&#x20;
                  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](https://github.com/Hub-of-all-Things/HAT-API-Android/blob/b51dda7df876280a0805eb12f79714c14e3904c3/hat/src/main/java/com/hubofallthings/android/hatApi/objects/HATOperator.kt). ***Optional***
                     1. `find` allows you to search a particular `String`, field name: `search`. Also, you can nest more `operators`, field name: `operator`.&#x20;
                     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`.&#x20;
                     4. `in` together with `value` field set to check if field is in (is contained by) `value`.&#x20;
            4. `links` each `endpoint` can contain other `endpoint` objects. ***Optional***&#x20;
         2. `orderBy` lets you define the field to order the data. ***Optional***&#x20;
         3. `ordering` lets you define the `ordering` of the data; `ascending` or `descending`. ***Optional***&#x20;
         4. `limit` is an `Int` which lets you define how many data points you like from this `endpoint`. ***Optional***&#x20;
  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:

```javascript
{
  "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:

```kotlin
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)
  )
```

* `endpoint`is 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 `name`parameter, 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:

```javascript
{
    "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](https://app.gitbook.com/s/-MU8i7kzqfJronlf3llG/build/tutorials/android-developer-guide.md#fetch-data-debits) for an explanation of what the above structure means.&#x20;

A request that has failed will look like this:

```javascript
{
  "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:

```bash
"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 `Android`application 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](https://docs.dataswyft.com/build/advanced-topics/pda-authentication/password-management/ios-swift/1.-authentication#step-2-logging-in-the-user).&#x20;
* `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](https://docs.dataswyft.com/build/advanced-topics/pda-authentication/password-management/ios-swift/1.-authentication#step-1-redirect-user-to-pda-login).

## Get Data Debit values

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

```kotlin
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)`. `HATError`is 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:

```javascript
  {
    "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:

```javascript
{
  "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
