{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"REST Data Source JSON Format","description":"Hyperproof developer resources for custom integrations.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"rest-data-source-json-format","__idx":0},"children":["REST Data Source JSON Format"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For Hypersync apps that retrieve data from a REST data source, the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/hypersync-sdk/doc/005-data-sources"},"children":["RestDataSourceBase"]}," class makes it possible to extract, transform and sort multiple data sets without writing code. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/json/dataSource.json"]}," file is used to define these datasets."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["At the top level, a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSource.json"]}," file should expose an object with three properties: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["baseUrl"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSets"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["messages"]},". Note that only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSets"]}," is required--",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["baseUrl"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["messages"]}," are both optional."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"baseurl","__idx":1},"children":["baseUrl"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["baseUrl"]}," is a simple string property that is used as a base for all of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["url"]}," properties in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSets"]}," collection. When this property is specified in a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSource.json"]}," file, the URLs in the individual data sets are treated as relative."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the APIs in your data sets do not share a common root, omit the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["baseUrl"]}," property and use full URLs in your data set definitions."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"datasets","__idx":2},"children":["dataSets"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A \"data set\" is a named object used to identify a data object or a data collection (i.e. data array) that can be retrieved from a data source."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSets"]}," can and ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["should"]}," be re-used across multiple proof types, and can also be used in non-proof scenarios such as collecting user data during the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validateCredentials"]}," process."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["There should be one property in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSets"]}," object for each data set that is used by your custom Hypersync app."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each data set object contains the following properties:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required?"},"children":["Required?"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["url"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Relative or full URL for the REST API"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["method"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["body"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Body included in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH"]}," requests"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["result"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["object"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["array"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["description"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A description of the data set"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["documentation"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Link to the REST API documentation"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["joins"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Additional data sets to join to this data set"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["lookups"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Lookups that are retrieved for each object in the result"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["filter"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Predicate applied to retrieved data"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["transform"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Transform to apply to each object in the filtered result"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["sort"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Sort to apply to the transformed data"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["pagingScheme"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Definition of pagination behavior"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"transforming-data","__idx":3},"children":["Transforming Data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Often objects returned from a REST API contain property values that need to be formatted before they are presented to the user."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transform"]}," property is where we define the fields that we wish to return in the dataset. The property name is the field name that will be available in the dataset. The value of the property refers to the property in the Json returned from the API call that we will display."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The simplest transformation is the ability to rename the property we wish to display as described above. In the example included in the JSONata discussion below, we can see that the dataset field ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["realname"]}," is renamed from the JSON API result property ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["full_name"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["realname"]}," is the name of the field to be referenced in your proof.json"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"transform-with-jsonata","__idx":4},"children":["Transform with JSONata"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sometimes the data returned for your API needs to be transformed in some way before it can be used in your dataset. The Hypersync SDK makes use of the query and transformation language JSONata. This allows the use of an extensive library of expressions to transform your data."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here are a few examples."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In our final dataset, we need to have a property named ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["owner"]}," that contains the value of the API result property ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["full_name"]},". If the value of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["full_name"]}," is empty, we use JSONata to replace it with the value from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["username"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For our ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["role"]}," property, we use JSONata to force this value to contain a concatenated string of values from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["roles"]}," array which is returned from the API result."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The API result value for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["last_login_time"]}," is a unix timestamp in seconds. We use JSONata to convert this value into milliseconds and then into a readable timestamp."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The full JSONata documentation of operators and functions can be found here."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["https://docs.jsonata.org/overview"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example","__idx":5},"children":["Example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"{\n  \"$schema\": \"https://cdn.jsdelivr.net/gh/Hyperproof/hypersync-sdk/schema/restDataSource.schema.json\",\n  \"baseUrl\": \"https://THE_SERVICE.com/api/v2\",\n  \"dataSets\": {\n    \"users\": {\n            \"description\": \"Returns a list of all the users\",\n            \"documentation\": \"\",\n            \"url\": \"/v1/objects/user\",\n            \"transform\": {\n                \"username\": \"username\",\n                \"realname\": \"full_name\",\n                \"owner\": \"[(full_name) = ''] ? username : full_name\",\n                \"email\": \"email\",\n                \"role\": \"$join([roles], ', ')\"\n                \"enabled\": \"enabled\",\n                \"last_login_time\": \"$fromMillis(last_login_time * 1000)\",\n            },\n            \"result\": \"array\"\n        }\n    }\n}\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"transform-with-value-lookups","__idx":6},"children":["Transform with Value Lookups"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Often, an API returns a value or set of values that need to be mapped to alternate values for readability, consistency, or other reasons. For example, an API that returns user information may return a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}," property with values ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["active"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["deactivated"]},". In this case it may be desirable to map these values to the strings \"Active\" and \"Inactive\" respectively. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["valueLookups"]}," object in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSource.json"]}," makes this sort of mapping possible without writing code."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each property in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["valueLookups"]}," can be thought of as a map. The keys of the map are the values that are to be mapped, and the values are the strings that should be used instead of the value that was returned from the REST API."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once a mapping has been defined under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["valueLookups"]},", it can be referenced in the data sets in your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dataSource.json"]}," file using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$vlookup"]}," function."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example-1","__idx":7},"children":["Example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"{\n  \"$schema\": \"https://cdn.jsdelivr.net/gh/Hyperproof/hypersync-sdk/schema/restDataSource.schema.json\",\n  \"baseUrl\": \"https://THE_SERVICE.com/api/v2\",\n  \"dataSets\": {\n    \"currentUser\": {\n      \"description\": \"Returns information about the authorized user.\",\n      \"documentation\": \"https://THE_SERVICE.com/docs/api/users/me\",\n      \"url\": \"users/me\",\n      \"transform\": {\n        \"username\": \"username\",\n        \"firstName\": \"givenName\",\n        \"lastName\": \"surname\"\n      },\n      \"result\": \"object\"\n    },\n    \"groups\": {\n      \"description\": \"Returns a list of all the groups in My Service.\",\n      \"documentation\": \"https://THE_SERVICE.com/docs/api/groups\",\n      \"url\": \"groups\",\n      \"transform\": {\n        \"id\": \"id\",\n        \"groupName\": \"groupName\",\n        \"members\": \"memberCount\"\n      },\n      \"result\": \"array\"\n    },\n    \"users\": {\n      \"description\": \"Returns a list of all the users in My Service.\",\n      \"documentation\": \"https://THE_SERVICE.com/docs/api/users\",\n      \"url\": \"users\",\n      \"transform\": {\n        \"id\": \"id\",\n        \"firstName\": \"givenName\",\n        \"lastName\": \"surname\",\n        \"email\": \"emailAddress\",\n        \"status\": \"$vlookup('statuses', status)\"\n      },\n      \"result\": \"array\"\n    }\n  },\n  \"valueLookups\": {\n    \"statuses\": {\n      \"active\": \"Active\",\n      \"deactivated\": \"Inactive\"\n    }\n  }\n}\n\n"},"children":[]}]},"headings":[{"value":"REST Data Source JSON Format","id":"rest-data-source-json-format","depth":1},{"value":"baseUrl","id":"baseurl","depth":2},{"value":"dataSets","id":"datasets","depth":2},{"value":"Transforming Data","id":"transforming-data","depth":1},{"value":"Transform with JSONata","id":"transform-with-jsonata","depth":2},{"value":"Example","id":"example","depth":2},{"value":"Transform with Value Lookups","id":"transform-with-value-lookups","depth":2},{"value":"Example","id":"example-1","depth":2}],"frontmatter":{"seo":{"title":"REST Data Source JSON Format"}},"lastModified":"2026-04-28T16:53:40.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/hypersync-sdk/doc/052-data-source-json","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}