diff --git a/.docs/.openapi/api-data.yaml b/.docs/.openapi/api-data.yaml
index 6d3e8693c52c8817f2d0243c22870005da54b556..6b1855a99e5e183c98270ce961899322beaa569e 100644
--- a/.docs/.openapi/api-data.yaml
+++ b/.docs/.openapi/api-data.yaml
@@ -11,7 +11,7 @@ info:
   version: 1.7.1
 externalDocs:
   description: Sourcecode Documentation
-  url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/system-services-metadata/
+  url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.1/system-services-metadata/
 servers:
 - url: http://localhost
   description: Development instance
@@ -57,48 +57,60 @@ paths:
         schema:
           type: string
           format: date-time
+      - name: Accept
+        in: header
+        required: true
+        schema:
+          type: string
       responses:
-        "200":
-          description: Retrieved view data
-          headers:
-            Access-Control-Expose-Headers:
-              description: Expose `X-Count` custom header
-              required: true
-              style: simple
-            X-Count:
-              description: Number of rows
-              required: true
-              style: simple
+        "403":
+          description: Not allowed to retrieve view data
           content:
             application/json:
               schema:
-                type: string
-        "409":
-          description: View schema could not be mapped
+                $ref: "#/components/schemas/ApiErrorDto"
+        "404":
+          description: Failed to find view in metadata database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to establish connection with the metadata service
+        "400":
+          description: Request pagination is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find view in metadata database
+        "406":
+          description: Failed to format data
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Request pagination is malformed
+        "409":
+          description: View schema could not be mapped
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to retrieve view data
+        "200":
+          description: Retrieved view data
+          headers:
+            Access-Control-Expose-Headers:
+              description: Expose `X-Count` custom header
+              required: true
+              style: simple
+            X-Count:
+              description: Number of rows
+              required: true
+              style: simple
+          content:
+            application/json:
+              schema:
+                type: string
+            text/csv: {}
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
@@ -144,48 +156,60 @@ paths:
         schema:
           type: string
           format: date-time
+      - name: Accept
+        in: header
+        required: true
+        schema:
+          type: string
       responses:
-        "200":
-          description: Retrieved view data
-          headers:
-            Access-Control-Expose-Headers:
-              description: Expose `X-Count` custom header
-              required: true
-              style: simple
-            X-Count:
-              description: Number of rows
-              required: true
-              style: simple
+        "403":
+          description: Not allowed to retrieve view data
           content:
             application/json:
               schema:
-                type: string
-        "409":
-          description: View schema could not be mapped
+                $ref: "#/components/schemas/ApiErrorDto"
+        "404":
+          description: Failed to find view in metadata database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to establish connection with the metadata service
+        "400":
+          description: Request pagination is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find view in metadata database
+        "406":
+          description: Failed to format data
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Request pagination is malformed
+        "409":
+          description: View schema could not be mapped
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to retrieve view data
+        "200":
+          description: Retrieved view data
+          headers:
+            Access-Control-Expose-Headers:
+              description: Expose `X-Count` custom header
+              required: true
+              style: simple
+            X-Count:
+              description: Number of rows
+              required: true
+              style: simple
+          content:
+            application/json:
+              schema:
+                type: string
+            text/csv: {}
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
@@ -234,7 +258,24 @@ paths:
         schema:
           type: integer
           format: int64
+      - name: Accept
+        in: header
+        required: true
+        schema:
+          type: string
       responses:
+        "404":
+          description: Failed to find table in metadata database
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "400":
+          description: Request pagination or table data select query is malformed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Get table data
           headers:
@@ -250,26 +291,21 @@ paths:
             application/json:
               schema:
                 type: string
-        "503":
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to get table data
+            text/csv: {}
+        "406":
+          description: Failed to format data
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find table in metadata database
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Request pagination or table data select query is malformed
+        "403":
+          description: Not allowed to get table data
           content:
             application/json:
               schema:
@@ -310,28 +346,28 @@ paths:
               $ref: "#/components/schemas/TupleUpdateDto"
         required: true
       responses:
-        "403":
-          description: Update table data not allowed
+        "404":
+          description: Failed to find table in metadata database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to establish connection with the metadata service
+        "400":
+          description: Request pagination or table data select query is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find table in metadata database
+        "202":
+          description: Updated table data
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Updated table data
-        "400":
-          description: Request pagination or table data select query is malformed
+        "403":
+          description: Update table data not allowed
           content:
             application/json:
               schema:
@@ -372,30 +408,30 @@ paths:
               $ref: "#/components/schemas/TupleDto"
         required: true
       responses:
-        "404":
-          description: Failed to find table in metadata database or blob in storage
-            service
+        "400":
+          description: Request pagination or table data select query is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "201":
-          description: Created table data
-        "503":
-          description: Failed to establish connection with the metadata service or
-            storage service
+        "403":
+          description: Create table data not allowed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Create table data not allowed
+        "503":
+          description: Failed to establish connection with the metadata service or
+            storage service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Request pagination or table data select query is malformed
+        "201":
+          description: Created table data
+        "404":
+          description: Failed to find table in metadata database or blob in storage
+            service
           content:
             application/json:
               schema:
@@ -436,14 +472,6 @@ paths:
               $ref: "#/components/schemas/TupleDeleteDto"
         required: true
       responses:
-        "503":
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Deleted table data
         "404":
           description: Failed to find table in metadata database
           content:
@@ -462,6 +490,14 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "202":
+          description: Deleted table data
+        "503":
+          description: Failed to establish connection with the metadata service
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - basicAuth: []
       - bearerAuth: []
@@ -505,7 +541,24 @@ paths:
         schema:
           type: integer
           format: int64
+      - name: Accept
+        in: header
+        required: true
+        schema:
+          type: string
       responses:
+        "404":
+          description: Failed to find table in metadata database
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "400":
+          description: Request pagination or table data select query is malformed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Get table data
           headers:
@@ -521,26 +574,21 @@ paths:
             application/json:
               schema:
                 type: string
-        "503":
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to get table data
+            text/csv: {}
+        "406":
+          description: Failed to format data
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find table in metadata database
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Request pagination or table data select query is malformed
+        "403":
+          description: Not allowed to get table data
           content:
             application/json:
               schema:
@@ -571,6 +619,11 @@ paths:
         schema:
           type: string
           format: uuid
+      - name: Accept
+        in: header
+        required: true
+        schema:
+          type: string
       - name: timestamp
         in: query
         required: false
@@ -590,14 +643,27 @@ paths:
           type: integer
           format: int64
       responses:
-        "400":
-          description: Invalid pagination
+        "404":
+          description: Failed to find database in metadata database or query in query
+            store of the data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to communicate with database
+        "403":
+          description: Not allowed to retrieve subset data
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "406":
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "400":
+          description: Invalid pagination
           content:
             application/json:
               schema:
@@ -623,15 +689,9 @@ paths:
             application/json:
               schema:
                 type: string
-        "404":
-          description: Failed to find database in metadata database or query in query
-            store of the data database
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to retrieve subset data
+            text/csv: {}
+        "503":
+          description: Failed to communicate with database
           content:
             application/json:
               schema:
@@ -661,6 +721,11 @@ paths:
         schema:
           type: string
           format: uuid
+      - name: Accept
+        in: header
+        required: true
+        schema:
+          type: string
       - name: timestamp
         in: query
         required: false
@@ -680,14 +745,27 @@ paths:
           type: integer
           format: int64
       responses:
-        "400":
-          description: Invalid pagination
+        "404":
+          description: Failed to find database in metadata database or query in query
+            store of the data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to communicate with database
+        "403":
+          description: Not allowed to retrieve subset data
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "406":
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "400":
+          description: Invalid pagination
           content:
             application/json:
               schema:
@@ -710,18 +788,12 @@ paths:
               description: The list of headers separated by comma
               style: simple
           content:
-            application/json:
-              schema:
-                type: string
-        "404":
-          description: Failed to find database in metadata database or query in query
-            store of the data database
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to retrieve subset data
+            application/json:
+              schema:
+                type: string
+            text/csv: {}
+        "503":
+          description: Failed to communicate with database
           content:
             application/json:
               schema:
@@ -756,39 +828,39 @@ paths:
               $ref: "#/components/schemas/QueryPersistDto"
         required: true
       responses:
-        "202":
-          description: Persisted subset
+        "403":
+          description: Not allowed to persist subset
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/QueryDto"
-        "503":
-          description: Failed to communicate with database
+                $ref: "#/components/schemas/ApiErrorDto"
+        "404":
+          description: Failed to find database in metadata database or query in query
+            store of the data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "417":
-          description: Failed to persist subset
+        "202":
+          description: Persisted subset
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database in metadata database or query in query
-            store of the data database
+                $ref: "#/components/schemas/QueryDto"
+        "400":
+          description: Malformed select query
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to persist subset
+        "503":
+          description: Failed to communicate with database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Malformed select query
+        "417":
+          description: Failed to persist subset
           content:
             application/json:
               schema:
@@ -867,28 +939,28 @@ paths:
               $ref: "#/components/schemas/ImportDto"
         required: true
       responses:
-        "202":
-          description: Imported dataset successfully
-        "403":
-          description: Import table dataset not allowed
+        "404":
+          description: Failed to find table in metadata database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to establish connection with the metadata service
+        "202":
+          description: Imported dataset successfully
+        "400":
+          description: Dataset and/or query are malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find table in metadata database
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Dataset and/or query are malformed
+        "403":
+          description: Import table dataset not allowed
           content:
             application/json:
               schema:
@@ -920,12 +992,6 @@ paths:
         schema:
           type: boolean
       responses:
-        "503":
-          description: Failed to communicate with database
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Found subsets
           content:
@@ -934,15 +1000,21 @@ paths:
                 type: array
                 items:
                   $ref: "#/components/schemas/QueryDto"
+        "404":
+          description: Failed to find database in metadata database or query in query
+            store of the data database
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: Not allowed to find subsets
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database in metadata database or query in query
-            store of the data database
+        "503":
+          description: Failed to communicate with database
           content:
             application/json:
               schema:
@@ -991,8 +1063,8 @@ paths:
               $ref: "#/components/schemas/SubsetDto"
         required: true
       responses:
-        "417":
-          description: Failed to insert query into query store of data database
+        "403":
+          description: Not allowed to find subset
           content:
             application/json:
               schema:
@@ -1003,21 +1075,21 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to communicate with database
+        "404":
+          description: Failed to find database in metadata database or query in query
+            store of the data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not allowed to find subset
+        "417":
+          description: Failed to insert query into query store of data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database in metadata database or query in query
-            store of the data database
+        "406":
+          description: Failed to format data
           content:
             application/json:
               schema:
@@ -1034,65 +1106,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-      security:
-      - basicAuth: []
-      - bearerAuth: []
-  /api/database/{databaseId}/view/{viewId}/export:
-    get:
-      tags:
-      - view-endpoint
-      summary: Get view data
-      description: "Gets data from view with id as downloadable file. For tables in\
-        \ private databases, the user needs to have at least *READ* access to the\
-        \ associated database."
-      operationId: exportDataset
-      parameters:
-      - name: databaseId
-        in: path
-        required: true
-        schema:
-          type: string
-          format: uuid
-      - name: viewId
-        in: path
-        required: true
-        schema:
-          type: string
-          format: uuid
-      - name: timestamp
-        in: query
-        required: false
-        schema:
-          type: string
-          format: date-time
-      responses:
-        "404":
-          description: Failed to find view in metadata database or export dataset
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "503":
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Export view data not allowed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Exported view data
-          content:
-            application/json:
-              schema:
-                type: string
-                format: binary
-        "400":
-          description: Request pagination or view data select query is malformed
+          description: Failed to communicate with database
           content:
             application/json:
               schema:
@@ -1129,26 +1144,6 @@ paths:
           type: integer
           format: int64
       responses:
-        "200":
-          description: Found table history
-          content:
-            application/json:
-              schema:
-                type: array
-                items:
-                  $ref: "#/components/schemas/TableHistoryDto"
-        "404":
-          description: Failed to find table history in data database
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: Find table history not allowed
           content:
@@ -1161,69 +1156,26 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-      security:
-      - basicAuth: []
-      - bearerAuth: []
-  /api/database/{databaseId}/table/{tableId}/export:
-    get:
-      tags:
-      - table-endpoint
-      summary: Get table data
-      description: "Gets data from table with id as downloadable file. For tables\
-        \ in private databases, the user needs to have at least *READ* access to the\
-        \ associated database."
-      operationId: exportDataset_1
-      parameters:
-      - name: databaseId
-        in: path
-        required: true
-        schema:
-          type: string
-          format: uuid
-      - name: tableId
-        in: path
-        required: true
-        schema:
-          type: string
-          format: uuid
-      - name: timestamp
-        in: query
-        required: false
-        schema:
-          type: string
-          format: date-time
-      responses:
-        "503":
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find table in metadata database
+        "200":
+          description: Found table history
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Export table data not allowed
+                type: array
+                items:
+                  $ref: "#/components/schemas/TableHistoryDto"
+        "503":
+          description: Failed to establish connection with the metadata service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Request pagination or table data select query is malformed
+        "404":
+          description: Failed to find table history in data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Exported table data
-          content:
-            application/json:
-              schema:
-                type: string
-                format: binary
       security:
       - basicAuth: []
       - bearerAuth: []
@@ -1251,11 +1203,6 @@ paths:
         schema:
           type: string
           format: uuid
-      - name: Accept
-        in: header
-        required: true
-        schema:
-          type: string
       - name: timestamp
         in: query
         required: false
@@ -1263,40 +1210,40 @@ paths:
           type: string
           format: date-time
       responses:
-        "503":
-          description: Failed to communicate with database
+        "200":
+          description: Found subset
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
+                $ref: "#/components/schemas/QueryDto"
+            text/csv: {}
         "403":
           description: Not allowed to find subset
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "406":
-          description: Failed to find acceptable representation
+        "404":
+          description: Failed to find database in metadata database or query in query
+            store of the data database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database in metadata database or query in query
-            store of the data database
+        "400":
+          description: Malformed select query
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Found subset
+        "406":
+          description: Failed to find acceptable representation
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/QueryDto"
-            text/csv: {}
-        "400":
-          description: Malformed select query
+                $ref: "#/components/schemas/ApiErrorDto"
+        "503":
+          description: Failed to communicate with database
           content:
             application/json:
               schema:
@@ -2102,6 +2049,7 @@ components:
       - id
       - language
       - licenses
+      - links
       - owner
       - publication_year
       - publisher
@@ -2117,6 +2065,8 @@ components:
           type: string
           format: uuid
           example: b97cd56b-66ca-4354-9e6c-f47210cfaaec
+        links:
+          $ref: "#/components/schemas/LinksDto"
         type:
           type: string
           example: database
@@ -2448,6 +2398,21 @@ components:
             \ preservation of copyright and license notices. Licensed works, modifications,\
             \ and larger works may be distributed under different terms and without\
             \ source code."
+    LinksDto:
+      required:
+      - self
+      - self_html
+      type: object
+      properties:
+        self:
+          type: string
+          example: http://example.com/api/
+        data:
+          type: string
+          example: http://example.com
+        self_html:
+          type: string
+          example: http://example.com
     RelatedIdentifierDto:
       required:
       - id
diff --git a/.docs/.openapi/api-metadata.yaml b/.docs/.openapi/api-metadata.yaml
index b7f380213b76fcf6455cba3b309a6fcf85c59440..e3769be04d2a9726dc40999bad56daa1c537d613 100644
--- a/.docs/.openapi/api-metadata.yaml
+++ b/.docs/.openapi/api-metadata.yaml
@@ -11,7 +11,7 @@ info:
   version: 1.7.1
 externalDocs:
   description: Sourcecode Documentation
-  url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/system-services-metadata/
+  url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.1/system-services-metadata/
 servers:
 - url: http://localhost
   description: Development instance
@@ -36,18 +36,18 @@ paths:
           type: string
           format: uuid
       responses:
-        "200":
-          description: Found user
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/UserDto"
         "404":
           description: User was not found
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "200":
+          description: Found user
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/UserDto"
         "403":
           description: Find user is not permitted
           content:
@@ -77,20 +77,20 @@ paths:
               $ref: "#/components/schemas/UserUpdateDto"
         required: true
       responses:
-        "403":
-          description: Not allowed to modify user metadata
+        "400":
+          description: Modify user query is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to modify user at auth service
+        "404":
+          description: Failed to find database/user in metadata database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database/user in metadata database
+        "503":
+          description: Failed to modify user at auth service
           content:
             application/json:
               schema:
@@ -101,8 +101,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/UserDto"
-        "400":
-          description: Modify user query is malformed
+        "403":
+          description: Not allowed to modify user metadata
           content:
             application/json:
               schema:
@@ -127,18 +127,18 @@ paths:
           type: string
           format: uuid
       responses:
-        "200":
-          description: Found user
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/UserDto"
         "404":
           description: User was not found
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "200":
+          description: Found user
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/UserDto"
         "403":
           description: Find user is not permitted
           content:
@@ -194,20 +194,8 @@ paths:
               $ref: "#/components/schemas/CreateDatabaseDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "409":
-          description: Query store could not be created
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to save in search service
+        "400":
+          description: Database create query is malformed or image is not supported
           content:
             application/json:
               schema:
@@ -224,8 +212,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Database create query is malformed or image is not supported
+        "409":
+          description: Query store could not be created
           content:
             application/json:
               schema:
@@ -243,6 +231,18 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "503":
+          description: Failed to save in search service
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -303,6 +303,12 @@ paths:
           type: string
           format: uuid
       responses:
+        "200":
+          description: Found database access
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/DatabaseAccessDto"
         "403":
           description: No access to this database
           content:
@@ -315,12 +321,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Found database access
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/DatabaseAccessDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -351,14 +351,9 @@ paths:
               $ref: "#/components/schemas/CreateAccessDto"
         required: true
       responses:
-        "404":
-          description: Database or user not found
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Access could not be updated in the data service
+        "502":
+          description: Access could not be updated due to connection error in the
+            data service
           content:
             application/json:
               schema:
@@ -372,9 +367,8 @@ paths:
                 $ref: "#/components/schemas/ApiErrorDto"
         "202":
           description: Modified access
-        "502":
-          description: Access could not be updated due to connection error in the
-            data service
+        "503":
+          description: Access could not be updated in the data service
           content:
             application/json:
               schema:
@@ -385,6 +379,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "404":
+          description: Database or user not found
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -415,14 +415,20 @@ paths:
               $ref: "#/components/schemas/CreateAccessDto"
         required: true
       responses:
+        "502":
+          description: Access could not be created due to connection error
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "202":
           description: Granting access succeeded
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/DatabaseAccessDto"
-        "404":
-          description: Database or user not found
+        "403":
+          description: Failed giving access
           content:
             application/json:
               schema:
@@ -439,14 +445,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Failed giving access
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "502":
-          description: Access could not be created due to connection error
+        "404":
+          description: Database or user not found
           content:
             application/json:
               schema:
@@ -475,6 +475,12 @@ paths:
           type: string
           format: uuid
       responses:
+        "502":
+          description: Access could not be created due to connection error
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: Revoke of access not permitted as no access was found
           content:
@@ -489,12 +495,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "502":
-          description: Access could not be created due to connection error
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: "User, database with access was not found"
           content:
@@ -534,6 +534,12 @@ paths:
           type: string
           format: uuid
       responses:
+        "200":
+          description: Found database access
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/DatabaseAccessDto"
         "403":
           description: No access to this database
           content:
@@ -546,12 +552,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Found database access
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/DatabaseAccessDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -665,18 +665,18 @@ paths:
               $ref: "#/components/schemas/BannerMessageUpdateDto"
         required: true
       responses:
-        "404":
-          description: Could not find message
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "202":
           description: Updated message
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/BannerMessageBriefDto"
+        "404":
+          description: Could not find message
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -694,16 +694,16 @@ paths:
           type: string
           format: uuid
       responses:
-        "202":
-          description: Deleted message
-          content:
-            application/json: {}
         "404":
           description: Could not find message
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "202":
+          description: Deleted message
+          content:
+            application/json: {}
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -817,9 +817,8 @@ paths:
         schema:
           type: string
       responses:
-        "400":
-          description: "Identifier could not be exported, the requested style is not\
-            \ known"
+        "403":
+          description: Not allowed to view identifier
           content:
             application/json:
               schema:
@@ -830,24 +829,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "409":
-          description: Exported resource was not found
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to find in data service
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "410":
-          description: Failed to retrieve from S3 endpoint
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Found identifier successfully
           content:
@@ -857,20 +838,26 @@ paths:
             application/ld+json:
               schema:
                 $ref: "#/components/schemas/LdDatasetDto"
-            text/csv: {}
             text/xml: {}
             text/bibliography: {}
             text/bibliography; style=apa: {}
             text/bibliography; style=ieee: {}
             text/bibliography; style=bibtex: {}
-        "403":
-          description: Not allowed to view identifier
+        "410":
+          description: Failed to retrieve from S3 endpoint
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Identifier could not be found
+        "409":
+          description: Exported resource was not found
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "400":
+          description: "Identifier could not be exported, the requested style is not\
+            \ known"
           content:
             application/json:
               schema:
@@ -881,6 +868,18 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "404":
+          description: Identifier could not be found
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "503":
+          description: Failed to find in data service
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
     put:
       tags:
       - identifier-endpoint
@@ -904,20 +903,20 @@ paths:
               $ref: "#/components/schemas/IdentifierSaveDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
+        "404":
+          description: "Failed to find database, table or view"
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Insufficient access rights or authorities
+        "202":
+          description: Saved identifier
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: "Failed to find database, table or view"
+                $ref: "#/components/schemas/IdentifierDto"
+        "400":
+          description: Identifier form contains invalid request data
           content:
             application/json:
               schema:
@@ -928,18 +927,18 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Identifier form contains invalid request data
+        "403":
+          description: Insufficient access rights or authorities
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Saved identifier
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/IdentifierDto"
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -957,12 +956,6 @@ paths:
           type: string
           format: uuid
       responses:
-        "502":
-          description: Connection to search service failed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "503":
           description: Failed to delete in search service
           content:
@@ -977,6 +970,12 @@ paths:
                 $ref: "#/components/schemas/ApiErrorDto"
         "202":
           description: Deleted identifier
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: Deleting identifier not permitted
           content:
@@ -1002,42 +1001,42 @@ paths:
           type: string
           format: uuid
       responses:
-        "502":
-          description: Connection to search service failed
+        "404":
+          description: "Failed to find database, table or view"
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Insufficient access rights or authorities
+        "400":
+          description: Identifier form contains invalid request data
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: "Failed to find database, table or view"
+        "202":
+          description: Published identifier
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
+                $ref: "#/components/schemas/IdentifierDto"
         "503":
           description: Failed to save in search service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Identifier form contains invalid request data
+        "403":
+          description: Insufficient access rights or authorities
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Published identifier
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/IdentifierDto"
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -1063,8 +1062,8 @@ paths:
               $ref: "#/components/schemas/DatabaseModifyVisibilityDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
+        "400":
+          description: The visibility payload is malformed
           content:
             application/json:
               schema:
@@ -1075,12 +1074,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: The visibility payload is malformed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: Visibility modification is not permitted
           content:
@@ -1093,6 +1086,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/DatabaseBriefDto"
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: Failed to find database in metadata database
           content:
@@ -1123,12 +1122,6 @@ paths:
           type: string
           format: uuid
       responses:
-        "403":
-          description: Find view is not permitted
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: "Database, view or user could not be found"
           content:
@@ -1141,6 +1134,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ViewDto"
+        "403":
+          description: Find view is not permitted
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -1171,12 +1170,6 @@ paths:
               $ref: "#/components/schemas/ViewUpdateDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: Database or View could not be found
           content:
@@ -1201,6 +1194,12 @@ paths:
             '*/*':
               schema:
                 $ref: "#/components/schemas/ViewBriefDto"
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "400":
           description: Update view query is malformed
           content:
@@ -1230,22 +1229,22 @@ paths:
           type: string
           format: uuid
       responses:
-        "502":
-          description: Connection to search service failed
+        "404":
+          description: "Database, view or user could not be found"
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
         "202":
           description: Delete view successfully
-        "503":
-          description: Failed to save in search service
+        "423":
+          description: Delete view resulted in an invalid query statement
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: "Database, view or user could not be found"
+        "503":
+          description: Failed to save in search service
           content:
             application/json:
               schema:
@@ -1256,8 +1255,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "423":
-          description: Delete view resulted in an invalid query statement
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1295,18 +1294,18 @@ paths:
           type: string
           format: uuid
       responses:
-        "403":
-          description: Access to the database is forbidden
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Find table successfully
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/TableDto"
+        "403":
+          description: Access to the database is forbidden
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: "Table, database or container could not be found"
           content:
@@ -1342,14 +1341,8 @@ paths:
               $ref: "#/components/schemas/TableUpdateDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to save in search service
+        "400":
+          description: Update table visibility payload is malformed
           content:
             application/json:
               schema:
@@ -1360,8 +1353,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/TableBriefDto"
-        "400":
-          description: Update table visibility payload is malformed
+        "503":
+          description: Failed to save in search service
           content:
             application/json:
               schema:
@@ -1372,6 +1365,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: Update table visibility not permitted
           content:
@@ -1403,28 +1402,28 @@ paths:
           type: string
           format: uuid
       responses:
-        "502":
-          description: Connection to search service failed
+        "400":
+          description: Delete table query resulted in an invalid query statement
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Access to the database is forbidden
+        "202":
+          description: Delete table successfully
+        "503":
+          description: Failed to save in search service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to save in search service
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Delete table successfully
-        "400":
-          description: Delete table query resulted in an invalid query statement
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1461,32 +1460,32 @@ paths:
           type: string
           format: uuid
       responses:
-        "502":
-          description: Connection to search service failed
+        "403":
+          description: Not the owner
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to save in search service
+        "404":
+          description: Failed to find database/table in metadata database
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Failed to map column statistic to known columns
+        "503":
+          description: Failed to save in search service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Not the owner
+        "400":
+          description: Failed to map column statistic to known columns
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database/table in metadata database
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1532,18 +1531,12 @@ paths:
               $ref: "#/components/schemas/ColumnSemanticsUpdateDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Access to the database is forbidden
+        "202":
+          description: Updated column semantics successfully
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
+                $ref: "#/components/schemas/ColumnDto"
         "404":
           description: Failed to find user/table/database/ontology in metadata database
           content:
@@ -1556,12 +1549,18 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Updated column semantics successfully
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ColumnDto"
+                $ref: "#/components/schemas/ApiErrorDto"
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "400":
           description: Update semantic concept query is malformed or update unit of
             measurement query is malformed
@@ -1594,18 +1593,12 @@ paths:
               $ref: "#/components/schemas/DatabaseTransferDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
+        "400":
+          description: Owner payload is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Transfer of ownership was successful
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/DatabaseBriefDto"
         "503":
           description: Failed to save in search service
           content:
@@ -1618,8 +1611,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Owner payload is malformed
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1630,6 +1623,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "202":
+          description: Transfer of ownership was successful
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/DatabaseBriefDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -1650,26 +1649,26 @@ paths:
           type: string
           format: uuid
       responses:
-        "502":
-          description: Connection to search service failed
+        "200":
+          description: Refreshed database views metadata
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
+                $ref: "#/components/schemas/DatabaseBriefDto"
         "503":
           description: Failed to save in search service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Refreshed database views metadata
+        "403":
+          description: Refresh view metadata is not permitted
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/DatabaseBriefDto"
-        "403":
-          description: Refresh view metadata is not permitted
+                $ref: "#/components/schemas/ApiErrorDto"
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1700,14 +1699,8 @@ paths:
           type: string
           format: uuid
       responses:
-        "403":
-          description: Not allowed to refresh table metadata
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "502":
-          description: Connection to search service failed
+        "400":
+          description: Failed to parse payload at search service
           content:
             application/json:
               schema:
@@ -1724,8 +1717,14 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Failed to parse payload at search service
+        "403":
+          description: Not allowed to refresh table metadata
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1754,12 +1753,6 @@ paths:
           type: string
           format: uuid
       responses:
-        "404":
-          description: Database or user could not be found
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: View of image was successful
           content:
@@ -1769,6 +1762,12 @@ paths:
                 items:
                   type: string
                   format: byte
+        "404":
+          description: Database or user could not be found
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -1793,14 +1792,20 @@ paths:
               $ref: "#/components/schemas/DatabaseModifyImageDto"
         required: true
       responses:
+        "403":
+          description: Modify of image is not permitted
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "410":
           description: File was not found in the Storage Service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "502":
-          description: Connection to search service failed
+        "404":
+          description: Database could not be found
           content:
             application/json:
               schema:
@@ -1817,14 +1822,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/DatabaseBriefDto"
-        "404":
-          description: Database could not be found
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "403":
-          description: Modify of image is not permitted
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -1948,12 +1947,6 @@ paths:
               $ref: "#/components/schemas/ImageCreateDto"
         required: true
       responses:
-        "400":
-          description: Image specification is invalid
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "409":
           description: Image already exists
           content:
@@ -1966,6 +1959,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ImageDto"
+        "400":
+          description: Image specification is invalid
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -2054,8 +2053,8 @@ paths:
               $ref: "#/components/schemas/CreateIdentifierDto"
         required: true
       responses:
-        "502":
-          description: Connection to search service failed
+        "404":
+          description: "Failed to find database, table or view"
           content:
             application/json:
               schema:
@@ -2066,26 +2065,26 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/IdentifierDto"
-        "403":
-          description: Insufficient access rights or authorities
+        "400":
+          description: Identifier form contains invalid request data
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: "Failed to find database, table or view"
+        "503":
+          description: Failed to save in search service
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "503":
-          description: Failed to save in search service
+        "403":
+          description: Insufficient access rights or authorities
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Identifier form contains invalid request data
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -2146,14 +2145,8 @@ paths:
               $ref: "#/components/schemas/CreateViewDto"
         required: true
       responses:
-        "423":
-          description: Create view resulted in an invalid query statement
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "502":
-          description: Connection to search service failed
+        "404":
+          description: Failed to find database/user in metadata database.
           content:
             application/json:
               schema:
@@ -2164,8 +2157,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ViewBriefDto"
-        "503":
-          description: Failed to save in search service
+        "423":
+          description: Create view resulted in an invalid query statement
           content:
             application/json:
               schema:
@@ -2176,8 +2169,8 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Create view query is malformed
+        "503":
+          description: Failed to save in search service
           content:
             application/json:
               schema:
@@ -2188,8 +2181,14 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database/user in metadata database.
+        "502":
+          description: Connection to search service failed
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "400":
+          description: Create view query is malformed
           content:
             application/json:
               schema:
@@ -2220,12 +2219,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Database could not be found
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: List tables
           content:
@@ -2234,6 +2227,12 @@ paths:
                 type: array
                 items:
                   $ref: "#/components/schemas/TableBriefDto"
+        "404":
+          description: Database could not be found
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -2257,24 +2256,12 @@ paths:
               $ref: "#/components/schemas/CreateTableDto"
         required: true
       responses:
-        "403":
-          description: Create table not permitted
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "502":
-          description: Connection to search service failed
+        "400":
+          description: Create table query is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "201":
-          description: Created a new table
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/TableBriefDto"
         "409":
           description: Create table conflicts with existing table name
           content:
@@ -2287,14 +2274,26 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "201":
+          description: Created a new table
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/TableBriefDto"
         "404":
           description: "Database, container or user could not be found"
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "400":
-          description: Create table query is malformed
+        "403":
+          description: Create table not permitted
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "502":
+          description: Connection to search service failed
           content:
             application/json:
               schema:
@@ -2338,6 +2337,12 @@ paths:
               $ref: "#/components/schemas/CreateContainerDto"
         required: true
       responses:
+        "409":
+          description: Container name already exists
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "403":
           description: "Create container not permitted, need authority `create-container`"
           content:
@@ -2356,12 +2361,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ContainerDto"
-        "409":
-          description: Container name already exists
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: Container image or user could not be found
           content:
@@ -2437,26 +2436,26 @@ paths:
         schema:
           type: string
       responses:
-        "400":
-          description: Filter params are invalid
+        "200":
+          description: Found entities
           content:
             application/json:
               schema:
-                $ref: "#/components/schemas/ApiErrorDto"
+                type: array
+                items:
+                  $ref: "#/components/schemas/EntityDto"
         "417":
           description: Generated query or uri is malformed
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "200":
-          description: Found entities
+        "400":
+          description: Filter params are invalid
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: "#/components/schemas/EntityDto"
+                $ref: "#/components/schemas/ApiErrorDto"
         "404":
           description: Could not find ontology
           content:
@@ -2506,18 +2505,18 @@ paths:
           type: string
           format: uuid
       responses:
-        "404":
-          description: Could not find message
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Get messages
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/BannerMessageDto"
+        "404":
+          description: Could not find message
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
   /api/license:
     get:
       tags:
@@ -2549,18 +2548,18 @@ paths:
         schema:
           type: string
       responses:
-        "404":
-          description: Failed to find metadata for identifier
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Retrieved metadata from identifier
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/IdentifierDto"
+        "404":
+          description: Failed to find metadata for identifier
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
   /api/database/{databaseId}:
     get:
       tags:
@@ -2576,18 +2575,6 @@ paths:
           type: string
           format: uuid
       responses:
-        "403":
-          description: Not allowed to view database
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Database could not be found
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Database found successfully
           headers:
@@ -2604,6 +2591,18 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/DatabaseBriefDto"
+        "404":
+          description: Database could not be found
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
+        "403":
+          description: Not allowed to view database
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -2635,12 +2634,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "417":
-          description: Generated query is malformed
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Suggested table semantics successfully
           content:
@@ -2649,8 +2642,8 @@ paths:
                 type: array
                 items:
                   $ref: "#/components/schemas/EntityDto"
-        "422":
-          description: Ontology does not have rdf or sparql endpoint
+        "417":
+          description: Generated query is malformed
           content:
             application/json:
               schema:
@@ -2667,6 +2660,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "422":
+          description: Ontology does not have rdf or sparql endpoint
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -2703,6 +2702,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "404":
+          description: Failed to find database/table in metadata database
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ApiErrorDto"
         "200":
           description: Suggested table column semantics successfully
           content:
@@ -2717,12 +2722,6 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "404":
-          description: Failed to find database/table in metadata database
-          content:
-            application/json:
-              schema:
-                $ref: "#/components/schemas/ApiErrorDto"
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -2773,14 +2772,14 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
+        "202":
+          description: Deleted container
         "403":
           description: "Create container not permitted, need authority `delete-container`"
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/ApiErrorDto"
-        "202":
-          description: Deleted container
       security:
       - bearerAuth: []
       - basicAuth: []
@@ -2802,59 +2801,6 @@ paths:
                   $ref: "#/components/schemas/ConceptDto"
 components:
   schemas:
-    UserAttributesDto:
-      required:
-      - language
-      - theme
-      type: object
-      properties:
-        theme:
-          type: string
-          example: light
-        orcid:
-          type: string
-          example: https://orcid.org/0000-0002-1825-0097
-        affiliation:
-          type: string
-          example: Brown University
-        language:
-          type: string
-          example: en
-    UserDto:
-      required:
-      - attributes
-      - id
-      - password
-      - username
-      type: object
-      properties:
-        id:
-          type: string
-          format: uuid
-          example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4
-        name:
-          type: string
-          example: Josiah Carberry
-        username:
-          type: string
-          example: username
-        password:
-          type: string
-          example: p4ssw0rd
-        attributes:
-          $ref: "#/components/schemas/UserAttributesDto"
-        last_retrieved:
-          type: string
-          format: date-time
-        qualified_name:
-          type: string
-          example: Josiah Carberry — @jcarberry
-        given_name:
-          type: string
-          example: Josiah
-        family_name:
-          type: string
-          example: Carberry
     ApiErrorDto:
       required:
       - code
@@ -2941,6 +2887,59 @@ components:
         code:
           type: string
           example: error.service.code
+    UserAttributesDto:
+      required:
+      - language
+      - theme
+      type: object
+      properties:
+        theme:
+          type: string
+          example: light
+        orcid:
+          type: string
+          example: https://orcid.org/0000-0002-1825-0097
+        affiliation:
+          type: string
+          example: Brown University
+        language:
+          type: string
+          example: en
+    UserDto:
+      required:
+      - attributes
+      - id
+      - password
+      - username
+      type: object
+      properties:
+        id:
+          type: string
+          format: uuid
+          example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4
+        name:
+          type: string
+          example: Josiah Carberry
+        username:
+          type: string
+          example: username
+        password:
+          type: string
+          example: p4ssw0rd
+        attributes:
+          $ref: "#/components/schemas/UserAttributesDto"
+        last_retrieved:
+          type: string
+          format: date-time
+        qualified_name:
+          type: string
+          example: Josiah Carberry — @jcarberry
+        given_name:
+          type: string
+          example: Josiah
+        family_name:
+          type: string
+          example: Carberry
     CreatorBriefDto:
       required:
       - creator_name
@@ -4750,6 +4749,7 @@ components:
       - id
       - language
       - licenses
+      - links
       - owner
       - publication_year
       - publisher
@@ -4765,6 +4765,8 @@ components:
           type: string
           format: uuid
           example: b97cd56b-66ca-4354-9e6c-f47210cfaaec
+        links:
+          $ref: "#/components/schemas/LinksDto"
         type:
           type: string
           example: database
@@ -5078,6 +5080,21 @@ components:
         award_title:
           type: string
           example: EOSC-Life
+    LinksDto:
+      required:
+      - self
+      - self_html
+      type: object
+      properties:
+        self:
+          type: string
+          example: http://example.com/api/
+        data:
+          type: string
+          example: http://example.com
+        self_html:
+          type: string
+          example: http://example.com
     RelatedIdentifierDto:
       required:
       - id
@@ -6371,14 +6388,14 @@ components:
           type: string
         resumptionToken:
           type: string
-        parametersString:
-          type: string
         fromDate:
           type: string
           format: date-time
         untilDate:
           type: string
           format: date-time
+        parametersString:
+          type: string
     BannerMessageDto:
       required:
       - id
diff --git a/.docs/.openapi/api.yaml b/.docs/.openapi/api.yaml
index 883a0efffe0d6959a2453e61f01e087e9bc0cf22..0fcd84503c6bd92530804d6e3e02242fe205d689 100644
--- a/.docs/.openapi/api.yaml
+++ b/.docs/.openapi/api.yaml
@@ -186,6 +186,11 @@ paths:
           schema:
             type: string
             format: date-time
+        - name: Accept
+          in: header
+          required: true
+          schema:
+            type: string
       responses:
         '200':
           description: Retrieved view data
@@ -202,6 +207,7 @@ paths:
             application/json:
               schema:
                 type: string
+            text/csv: {}
         '400':
           description: Request pagination is malformed
           content:
@@ -220,6 +226,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '409':
           description: View schema could not be mapped
           content:
@@ -274,6 +286,11 @@ paths:
           schema:
             type: string
             format: date-time
+        - name: Accept
+          in: header
+          required: true
+          schema:
+            type: string
       responses:
         '200':
           description: Retrieved view data
@@ -290,6 +307,7 @@ paths:
             application/json:
               schema:
                 type: string
+            text/csv: {}
         '400':
           description: Request pagination is malformed
           content:
@@ -308,6 +326,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '409':
           description: View schema could not be mapped
           content:
@@ -365,6 +389,11 @@ paths:
           schema:
             type: integer
             format: int64
+        - name: Accept
+          in: header
+          required: true
+          schema:
+            type: string
       responses:
         '200':
           description: Get table data
@@ -381,6 +410,7 @@ paths:
             application/json:
               schema:
                 type: string
+            text/csv: {}
         '400':
           description: Request pagination or table data select query is malformed
           content:
@@ -399,6 +429,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '503':
           description: Failed to establish connection with the metadata service
           content:
@@ -640,6 +676,11 @@ paths:
           schema:
             type: integer
             format: int64
+        - name: Accept
+          in: header
+          required: true
+          schema:
+            type: string
       responses:
         '200':
           description: Get table data
@@ -656,6 +697,7 @@ paths:
             application/json:
               schema:
                 type: string
+            text/csv: {}
         '400':
           description: Request pagination or table data select query is malformed
           content:
@@ -674,6 +716,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '503':
           description: Failed to establish connection with the metadata service
           content:
@@ -708,6 +756,11 @@ paths:
           schema:
             type: string
             format: uuid
+        - name: Accept
+          in: header
+          required: true
+          schema:
+            type: string
         - name: timestamp
           in: query
           required: false
@@ -748,6 +801,7 @@ paths:
             application/json:
               schema:
                 type: string
+            text/csv: {}
         '400':
           description: Invalid pagination
           content:
@@ -768,6 +822,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '503':
           description: Failed to communicate with database
           content:
@@ -801,6 +861,11 @@ paths:
           schema:
             type: string
             format: uuid
+        - name: Accept
+          in: header
+          required: true
+          schema:
+            type: string
         - name: timestamp
           in: query
           required: false
@@ -841,6 +906,7 @@ paths:
             application/json:
               schema:
                 type: string
+            text/csv: {}
         '400':
           description: Invalid pagination
           content:
@@ -861,6 +927,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '503':
           description: Failed to communicate with database
           content:
@@ -1164,6 +1236,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        '406':
+          description: Failed to format data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         '417':
           description: Failed to insert query into query store of data database
           content:
@@ -1185,70 +1263,6 @@ paths:
       security:
         - basicAuth: []
         - bearerAuth: []
-  '/api/database/{databaseId}/view/{viewId}/export':
-    get:
-      tags:
-        - view-endpoint
-      summary: Get view data
-      description: >-
-        Gets data from view with id as downloadable file. For tables in private
-        databases, the user needs to have at least *READ* access to the
-        associated database.
-      operationId: exportDataset
-      parameters:
-        - name: databaseId
-          in: path
-          required: true
-          schema:
-            type: string
-            format: uuid
-        - name: viewId
-          in: path
-          required: true
-          schema:
-            type: string
-            format: uuid
-        - name: timestamp
-          in: query
-          required: false
-          schema:
-            type: string
-            format: date-time
-      responses:
-        '200':
-          description: Exported view data
-          content:
-            application/json:
-              schema:
-                type: string
-                format: binary
-        '400':
-          description: Request pagination or view data select query is malformed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        '403':
-          description: Export view data not allowed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        '404':
-          description: Failed to find view in metadata database or export dataset
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        '503':
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-      security:
-        - basicAuth: []
-        - bearerAuth: []
   '/api/database/{databaseId}/table/{tableId}/history':
     get:
       tags:
@@ -1314,70 +1328,6 @@ paths:
       security:
         - basicAuth: []
         - bearerAuth: []
-  '/api/database/{databaseId}/table/{tableId}/export':
-    get:
-      tags:
-        - table-endpoint
-      summary: Get table data
-      description: >-
-        Gets data from table with id as downloadable file. For tables in private
-        databases, the user needs to have at least *READ* access to the
-        associated database.
-      operationId: exportDataset_1
-      parameters:
-        - name: databaseId
-          in: path
-          required: true
-          schema:
-            type: string
-            format: uuid
-        - name: tableId
-          in: path
-          required: true
-          schema:
-            type: string
-            format: uuid
-        - name: timestamp
-          in: query
-          required: false
-          schema:
-            type: string
-            format: date-time
-      responses:
-        '200':
-          description: Exported table data
-          content:
-            application/json:
-              schema:
-                type: string
-                format: binary
-        '400':
-          description: Request pagination or table data select query is malformed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        '403':
-          description: Export table data not allowed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        '404':
-          description: Failed to find table in metadata database
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        '503':
-          description: Failed to establish connection with the metadata service
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-      security:
-        - basicAuth: []
-        - bearerAuth: []
   '/api/database/{databaseId}/subset/{subsetId}':
     get:
       tags:
@@ -1403,11 +1353,6 @@ paths:
           schema:
             type: string
             format: uuid
-        - name: Accept
-          in: header
-          required: true
-          schema:
-            type: string
         - name: timestamp
           in: query
           required: false
@@ -2282,7 +2227,6 @@ paths:
             application/ld+json:
               schema:
                 $ref: '#/components/schemas/LdDatasetDto'
-            text/csv: {}
             text/xml: {}
             text/bibliography: {}
             text/bibliography; style=apa: {}
@@ -5332,6 +5276,7 @@ components:
         - id
         - language
         - licenses
+        - links
         - owner
         - publication_year
         - publisher
@@ -5347,6 +5292,8 @@ components:
           type: string
           format: uuid
           example: b97cd56b-66ca-4354-9e6c-f47210cfaaec
+        links:
+          $ref: '#/components/schemas/LinksDto'
         type:
           type: string
           example: database
@@ -5681,6 +5628,21 @@ components:
             preservation of copyright and license notices. Licensed works,
             modifications, and larger works may be distributed under different
             terms and without source code.
+    LinksDto:
+      required:
+        - self
+        - self_html
+      type: object
+      properties:
+        self:
+          type: string
+          example: 'http://example.com/api/'
+        data:
+          type: string
+          example: 'http://example.com'
+        self_html:
+          type: string
+          example: 'http://example.com'
     RelatedIdentifierDto:
       required:
         - id
@@ -8414,14 +8376,14 @@ components:
           type: string
         resumptionToken:
           type: string
-        parametersString:
-          type: string
         fromDate:
           type: string
           format: date-time
         untilDate:
           type: string
           format: date-time
+        parametersString:
+          type: string
     BannerMessageDto:
       required:
         - id
diff --git a/.docs/changelog.md b/.docs/changelog.md
index 8c114c004061347b51db487ddafdae19a57721fe..941b3ccc59758e4bf709514ac296b738e13158cc 100644
--- a/.docs/changelog.md
+++ b/.docs/changelog.md
@@ -2,18 +2,20 @@
 author: Martin Weise
 ---
 
-## v1.7.1 (2025-03-04)
-
-#### Fixes
-
-* Fixed a bug where quick interaction with the UI caused the user to trigger the brute-force login detection
-  in [#501](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/501).
+## v1.7.1 (2025-03-06)
 
 #### Features
 
+* Added support to download `pandas` DataFrame by PID
+  in [#503](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/503).
 * Added the possibility to create and fill a table from a `pandas` DataFrame (or optionally just create the schema)
   in [#496](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/496).
 
+#### Fixes
+
+* Fixed a bug where quick interaction with the UI caused the user to trigger the brute-force login detection
+  in [#501](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/501).
+
 ## v1.7.0 (2025-03-03)
 
 [:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.7.1)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8439dc1b4c2f24a8ca07f136b0afdd15fba26042..5dd7139b4565d5d70ebe3bf129429b064b47b074 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -232,7 +232,9 @@ build-images:
     - "apk add --no-cache make"
     - echo "$CI_REGISTRY_PASSWORD" | docker login --username "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY_URL
   script:
-    - "make build-images"
+    - docker build -q --network=host -t dbrepo-metadata-service:build --target build dbrepo-metadata-service
+    - docker build -q --network=host -t dbrepo-data-service:build --target build dbrepo-data-service
+    - docker compose build -q --parallel
 
 build-helm:
   image: docker.io/docker:${DOCKER_VERSION}-dind
diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock
index 94704d5c24469e8669f7037f90a622361f87a2cb..995400fd16e50f79ff7fe5b0b4114ef6c407041e 100644
--- a/dbrepo-analyse-service/Pipfile.lock
+++ b/dbrepo-analyse-service/Pipfile.lock
@@ -425,7 +425,7 @@
         },
         "dbrepo": {
             "hashes": [
-                "sha256:4f5ee48e9a68a44c2d1184923b90729d724553862742738d8f942273a586eb3d"
+                "sha256:e70ea4f7030191eb80116e5d0a4b17b041c94c80359d5d8e707d62218edd9a54"
             ],
             "path": "./lib/dbrepo-1.7.1.tar.gz"
         },
diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl b/dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl
index 8e77c6e1f6a01b3d9739280f29539985c359d2c8..61f52896c18ecbec8090177b38b8dbaeb0e1a95e 100644
Binary files a/dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl and b/dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl differ
diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz
index ede846d6168615c3e3bac49872362163b0a9f005..6708e1d892771d6cdf9293a6e9f5197f4dd9e304 100644
Binary files a/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz and b/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz differ
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
index 9fee9476c9ddbceeeaea54cf20763fdc6af3be9b..7bf598db0b878b619db6c04537da6084d7cb79eb 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
@@ -11,7 +11,6 @@ import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.exception.*;
 import at.tuwien.gateway.MetadataServiceGateway;
 import at.tuwien.mapper.MariaDbMapper;
-import at.tuwien.mapper.MetadataMapper;
 import at.tuwien.service.CacheService;
 import at.tuwien.service.DatabaseService;
 import at.tuwien.service.StorageService;
@@ -33,10 +32,7 @@ import lombok.extern.log4j.Log4j2;
 import org.apache.spark.sql.Dataset;
 import org.apache.spark.sql.Row;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
@@ -44,7 +40,6 @@ import java.security.Principal;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 @Log4j2
@@ -56,7 +51,6 @@ public class SubsetEndpoint extends RestEndpoint {
     private final CacheService cacheService;
     private final MariaDbMapper mariaDbMapper;
     private final SubsetService subsetService;
-    private final MetadataMapper metadataMapper;
     private final StorageService storageService;
     private final DatabaseService databaseService;
     private final EndpointValidator endpointValidator;
@@ -64,12 +58,11 @@ public class SubsetEndpoint extends RestEndpoint {
 
     @Autowired
     public SubsetEndpoint(CacheService cacheService, MariaDbMapper mariaDbMapper, SubsetService subsetService,
-                          MetadataMapper metadataMapper, StorageService storageService, DatabaseService databaseService,
+                          StorageService storageService, DatabaseService databaseService,
                           EndpointValidator endpointValidator, MetadataServiceGateway metadataServiceGateway) {
         this.cacheService = cacheService;
         this.mariaDbMapper = mariaDbMapper;
         this.subsetService = subsetService;
-        this.metadataMapper = metadataMapper;
         this.storageService = storageService;
         this.databaseService = databaseService;
         this.endpointValidator = endpointValidator;
@@ -115,7 +108,9 @@ public class SubsetEndpoint extends RestEndpoint {
                 log.error("Failed to list queries: no authentication found");
                 throw new NotAllowedException("Failed to list queries: no authentication found");
             }
-            endpointValidator.validateOnlyAccess(database, principal, false);
+            if (!isSystem(principal)) {
+                endpointValidator.validateOnlyAccess(database, principal, false);
+            }
         }
         final List<QueryDto> queries;
         try {
@@ -168,21 +163,21 @@ public class SubsetEndpoint extends RestEndpoint {
     })
     public ResponseEntity<?> findById(@NotNull @PathVariable("databaseId") UUID databaseId,
                                       @NotNull @PathVariable("subsetId") UUID subsetId,
-                                      @NotNull @RequestHeader("Accept") String accept,
                                       @RequestParam(required = false) Instant timestamp,
                                       Principal principal)
             throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException,
-            QueryNotFoundException, FormatNotAvailableException, StorageUnavailableException, UserNotFoundException,
-            MetadataServiceException, TableNotFoundException, QueryMalformedException, NotAllowedException {
-        log.debug("endpoint find subset in database, databaseId={}, subsetId={}, accept={}, timestamp={}", databaseId,
-                subsetId, accept, timestamp);
+            QueryNotFoundException, UserNotFoundException, MetadataServiceException, NotAllowedException {
+        log.debug("endpoint find subset in database, databaseId={}, subsetId={}, timestamp={}", databaseId,
+                subsetId, timestamp);
         final DatabaseDto database = cacheService.getDatabase(databaseId);
         if (!database.getIsPublic()) {
             if (principal == null) {
                 log.error("Failed to find query: no authentication found");
                 throw new NotAllowedException("Failed to find query: no authentication found");
             }
-            endpointValidator.validateOnlyAccess(database, principal, false);
+            if (!isSystem(principal)) {
+                endpointValidator.validateOnlyAccess(database, principal, false);
+            }
         }
         final QueryDto subset;
         try {
@@ -197,27 +192,7 @@ public class SubsetEndpoint extends RestEndpoint {
             timestamp = Instant.now();
             log.debug("timestamp not set: default to {}", timestamp);
         }
-        if (accept == null || accept.isBlank()) {
-            accept = MediaType.APPLICATION_JSON_VALUE;
-            log.debug("accept header not set: default to {}", accept);
-        }
-        switch (accept) {
-            case MediaType.APPLICATION_JSON_VALUE:
-                log.trace("accept header matches json");
-                return ResponseEntity.ok(subset);
-            case "text/csv":
-                log.trace("accept header matches csv");
-                final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp, null, null);
-                final Dataset<Row> dataset = subsetService.getData(database, query);
-                final ExportResourceDto resource = storageService.transformDataset(dataset);
-                final HttpHeaders headers = new HttpHeaders();
-                headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
-                log.trace("export table resulted in resource {}", resource);
-                return ResponseEntity.ok()
-                        .headers(headers)
-                        .body(resource.getResource());
-        }
-        throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': got " + accept + " instead");
+        return ResponseEntity.ok(subset);
     }
 
     @PostMapping
@@ -246,6 +221,11 @@ public class SubsetEndpoint extends RestEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "406",
+                    description = "Failed to format data",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "417",
                     description = "Failed to insert query into query store of data database",
                     content = {@Content(
@@ -262,18 +242,18 @@ public class SubsetEndpoint extends RestEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
-    public ResponseEntity<List<Map<String, Object>>> create(@NotNull @PathVariable("databaseId") UUID databaseId,
-                                                            @Valid @RequestBody SubsetDto data,
-                                                            Principal principal,
-                                                            @NotNull HttpServletRequest request,
-                                                            @RequestParam(required = false) Instant timestamp,
-                                                            @RequestParam(required = false) Long page,
-                                                            @RequestParam(required = false) Long size)
+    public ResponseEntity<?> create(@NotNull @PathVariable("databaseId") UUID databaseId,
+                                    @Valid @RequestBody SubsetDto data,
+                                    Principal principal,
+                                    @NotNull HttpServletRequest request,
+                                    @RequestParam(required = false) Instant timestamp,
+                                    @RequestParam(required = false) Long page,
+                                    @RequestParam(required = false) Long size)
             throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException,
             QueryNotFoundException, StorageUnavailableException, QueryMalformedException, StorageNotFoundException,
             QueryStoreInsertException, TableMalformedException, PaginationException, QueryNotSupportedException,
             NotAllowedException, UserNotFoundException, MetadataServiceException, TableNotFoundException,
-            ViewMalformedException, ViewNotFoundException, ImageNotFoundException {
+            ViewMalformedException, ViewNotFoundException, ImageNotFoundException, FormatNotAvailableException {
         log.debug("endpoint create subset in database, databaseId={}, page={}, size={}, timestamp={}", databaseId,
                 page, size, timestamp);
         /* check */
@@ -300,10 +280,18 @@ public class SubsetEndpoint extends RestEndpoint {
         }
         /* create */
         final DatabaseDto database = cacheService.getDatabase(databaseId);
-        endpointValidator.validateOnlyPrivateSchemaAccess(database, principal);
+        if (!database.getIsSchemaPublic()) {
+            if (principal == null) {
+                log.error("Failed to create subset: no authentication found");
+                throw new NotAllowedException("Failed to create subset: no authentication found");
+            }
+            if (!isSystem(principal)) {
+                endpointValidator.validateOnlyAccess(database, principal, false);
+            }
+        }
         try {
             final UUID subsetId = subsetService.create(database, data, timestamp, userId);
-            return getData(databaseId, subsetId, principal, request, timestamp, page, size);
+            return getData(databaseId, subsetId, principal, "application/json", request, timestamp, page, size);
         } catch (SQLException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
@@ -324,7 +312,8 @@ public class SubsetEndpoint extends RestEndpoint {
                             @Header(name = "Access-Control-Expose-Headers", description = "Reverse proxy exposing of custom headers", schema = @Schema(implementation = String.class), required = true)},
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = List.class))}),
+                            schema = @Schema(implementation = List.class)),
+                            @Content(mediaType = "text/csv")}),
             @ApiResponse(responseCode = "400",
                     description = "Invalid pagination",
                     content = {@Content(
@@ -340,24 +329,31 @@ public class SubsetEndpoint extends RestEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "406",
+                    description = "Failed to format data",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "503",
                     description = "Failed to communicate with database",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
-    public ResponseEntity<List<Map<String, Object>>> getData(@NotNull @PathVariable("databaseId") UUID databaseId,
-                                                             @NotNull @PathVariable("subsetId") UUID subsetId,
-                                                             Principal principal,
-                                                             @NotNull HttpServletRequest request,
-                                                             @RequestParam(required = false) Instant timestamp,
-                                                             @RequestParam(required = false) Long page,
-                                                             @RequestParam(required = false) Long size)
+    public ResponseEntity<?> getData(@NotNull @PathVariable("databaseId") UUID databaseId,
+                                     @NotNull @PathVariable("subsetId") UUID subsetId,
+                                     Principal principal,
+                                     @NotNull @RequestHeader("Accept") String accept,
+                                     @NotNull HttpServletRequest request,
+                                     @RequestParam(required = false) Instant timestamp,
+                                     @RequestParam(required = false) Long page,
+                                     @RequestParam(required = false) Long size)
             throws PaginationException, DatabaseNotFoundException, RemoteUnavailableException, NotAllowedException,
             QueryNotFoundException, DatabaseUnavailableException, QueryMalformedException, UserNotFoundException,
-            MetadataServiceException, TableNotFoundException, ViewNotFoundException, ViewMalformedException {
-        log.debug("endpoint get subset data, databaseId={}, subsetId={}, principal.name={} page={}, size={}",
-                databaseId, subsetId, principal != null ? principal.getName() : null, page, size);
+            MetadataServiceException, TableNotFoundException, ViewNotFoundException, ViewMalformedException,
+            FormatNotAvailableException, StorageUnavailableException {
+        log.debug("endpoint get subset data, databaseId={}, subsetId={}, accept={} page={}, size={}", databaseId,
+                subsetId, accept, page, size);
         endpointValidator.validateDataParams(page, size);
         final DatabaseDto database = cacheService.getDatabase(databaseId);
         if (!database.getIsPublic()) {
@@ -365,7 +361,9 @@ public class SubsetEndpoint extends RestEndpoint {
                 log.error("Failed to re-execute query: no authentication found");
                 throw new NotAllowedException("Failed to re-execute query: no authentication found");
             }
-            cacheService.getAccess(databaseId, getId(principal));
+            if (!isSystem(principal)) {
+                cacheService.getAccess(databaseId, getId(principal));
+            }
         }
         log.trace("visibility for database: is_public={}, is_schema_public={}", database.getIsPublic(), database.getIsSchemaPublic());
         /* parameters */
@@ -381,6 +379,10 @@ public class SubsetEndpoint extends RestEndpoint {
             timestamp = Instant.now();
             log.debug("timestamp not set: default to {}", timestamp);
         }
+        if (accept == null || accept.isBlank()) {
+            accept = MediaType.APPLICATION_JSON_VALUE;
+            log.debug("accept header not set: default to {}", accept);
+        }
         try {
             final HttpHeaders headers = new HttpHeaders();
             headers.set("X-Id", "" + subsetId);
@@ -394,16 +396,32 @@ public class SubsetEndpoint extends RestEndpoint {
                         .build();
             }
             subset.setIdentifiers(metadataServiceGateway.getIdentifiers(database.getId(), subset.getId()));
-            final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp, page, size);
+            final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp,
+                    accept.equals("text/csv") ? null : page,
+                    accept.equals("text/csv") ? null : size);
             final Dataset<Row> dataset = subsetService.getData(database, query);
-            final String viewName = metadataMapper.queryDtoToViewName(subset);
+            final String viewName = subset.getQueryHash();
             databaseService.createView(database, viewName, subset.getQuery());
             final ViewDto view = databaseService.inspectView(database, viewName);
             headers.set("Access-Control-Expose-Headers", "X-Id X-Headers");
             headers.set("X-Headers", String.join(",", view.getColumns().stream().map(ViewColumnDto::getInternalName).toList()));
-            return ResponseEntity.status(request.getMethod().equals("POST") ? HttpStatus.CREATED : HttpStatus.OK)
-                    .headers(headers)
-                    .body(transform(dataset));
+            final HttpStatusCode statusCode = request.getMethod().equals("POST") ? HttpStatus.CREATED : HttpStatus.OK;
+            switch (accept) {
+                case MediaType.APPLICATION_JSON_VALUE:
+                    log.trace("accept header matches json");
+                    return ResponseEntity.status(statusCode)
+                            .headers(headers)
+                            .body(transform(dataset));
+                case "text/csv":
+                    log.trace("accept header matches csv");
+                    final ExportResourceDto resource = storageService.transformDataset(dataset);
+                    headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
+                    return ResponseEntity.status(statusCode)
+                            .headers(headers)
+                            .body(storageService.transformDataset(dataset)
+                                    .getResource());
+            }
+            throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': provided " + accept + " instead");
         } catch (SQLException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
@@ -457,7 +475,9 @@ public class SubsetEndpoint extends RestEndpoint {
         log.debug("endpoint persist query, databaseId={}, queryId={}, data.persist={}, principal.name={}", databaseId,
                 queryId, data.getPersist(), principal.getName());
         final DatabaseDto database = cacheService.getDatabase(databaseId);
-        cacheService.getAccess(databaseId, getId(principal));
+        if (!isSystem(principal)) {
+            cacheService.getAccess(databaseId, getId(principal));
+        }
         try {
             subsetService.persist(database, queryId, data.getPersist());
             final QueryDto dto = subsetService.findById(database, queryId);
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
index 6914726cb84a886d97210dce9f1f60ac19db53b5..8e1fef5bac3d5451b0938f337e623d7e0e39ab56 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
@@ -29,9 +29,9 @@ import lombok.extern.log4j.Log4j2;
 import org.apache.spark.sql.Dataset;
 import org.apache.spark.sql.Row;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.InputStreamResource;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -40,7 +40,6 @@ import java.security.Principal;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 @Log4j2
@@ -228,7 +227,8 @@ public class TableEndpoint extends RestEndpoint {
                             @Header(name = "Access-Control-Expose-Headers", description = "Expose `X-Count` custom header", schema = @Schema(implementation = String.class), required = true)},
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = List.class))}),
+                            schema = @Schema(implementation = List.class)),
+                            @Content(mediaType = "text/csv")}),
             @ApiResponse(responseCode = "400",
                     description = "Request pagination or table data select query is malformed",
                     content = {@Content(
@@ -244,23 +244,30 @@ public class TableEndpoint extends RestEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "406",
+                    description = "Failed to format data",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "503",
                     description = "Failed to establish connection with the metadata service",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
-    public ResponseEntity<List<Map<String, Object>>> getData(@NotNull @PathVariable("databaseId") UUID databaseId,
-                                                             @NotNull @PathVariable("tableId") UUID tableId,
-                                                             @RequestParam(required = false) Instant timestamp,
-                                                             @RequestParam(required = false) Long page,
-                                                             @RequestParam(required = false) Long size,
-                                                             @NotNull HttpServletRequest request,
-                                                             Principal principal)
+    public ResponseEntity<?> getData(@NotNull @PathVariable("databaseId") UUID databaseId,
+                                     @NotNull @PathVariable("tableId") UUID tableId,
+                                     @RequestParam(required = false) Instant timestamp,
+                                     @RequestParam(required = false) Long page,
+                                     @RequestParam(required = false) Long size,
+                                     @NotNull @RequestHeader("Accept") String accept,
+                                     @NotNull HttpServletRequest request,
+                                     Principal principal)
             throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException,
-            PaginationException, MetadataServiceException, NotAllowedException, DatabaseNotFoundException {
-        log.debug("endpoint get table data, databaseId={}, tableId={}, timestamp={}, page={}, size={}", databaseId,
-                tableId, timestamp, page, size);
+            PaginationException, MetadataServiceException, NotAllowedException, DatabaseNotFoundException,
+            FormatNotAvailableException, StorageUnavailableException {
+        log.debug("endpoint get table data, databaseId={}, tableId={}, timestamp={}, page={}, size={}, accept={}",
+                databaseId, tableId, timestamp, page, size, accept);
         endpointValidator.validateDataParams(page, size);
         /* parameters */
         if (page == null) {
@@ -281,7 +288,9 @@ public class TableEndpoint extends RestEndpoint {
                 log.error("Failed find table data: authentication required");
                 throw new NotAllowedException("Failed to find table data: authentication required");
             }
-            cacheService.getAccess(databaseId, getId(principal));
+            if (!isSystem(principal)) {
+                cacheService.getAccess(databaseId, getId(principal));
+            }
         }
         final DatabaseDto database = cacheService.getDatabase(databaseId);
         try {
@@ -296,11 +305,26 @@ public class TableEndpoint extends RestEndpoint {
             headers.set("Access-Control-Expose-Headers", "X-Headers");
             headers.set("X-Headers", String.join(",", table.getColumns().stream().map(ColumnDto::getInternalName).toList()));
             final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(),
-                    table.getInternalName(), timestamp, page, size);
+                    table.getInternalName(), timestamp,
+                    accept.equals("text/csv") ? null : page,
+                    accept.equals("text/csv") ? null : size);
             final Dataset<Row> dataset = subsetService.getData(database, query);
-            return ResponseEntity.ok()
-                    .headers(headers)
-                    .body(transform(dataset));
+            switch (accept) {
+                case MediaType.APPLICATION_JSON_VALUE:
+                    log.trace("accept header matches json");
+                    return ResponseEntity.ok()
+                            .headers(headers)
+                            .body(transform(dataset));
+                case "text/csv":
+                    log.trace("accept header matches csv");
+                    final ExportResourceDto resource = storageService.transformDataset(dataset);
+                    headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
+                    return ResponseEntity.status(HttpStatus.OK)
+                            .headers(headers)
+                            .body(storageService.transformDataset(dataset)
+                                    .getResource());
+            }
+            throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': provided " + accept + " instead");
         } catch (SQLException | QueryMalformedException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
@@ -586,72 +610,6 @@ public class TableEndpoint extends RestEndpoint {
         }
     }
 
-    @GetMapping("/{tableId}/export")
-    @Observed(name = "dbrepo_table_data_export")
-    @Operation(summary = "Get table data",
-            description = "Gets data from table with id as downloadable file. For tables in private databases, the user needs to have at least *READ* access to the associated database.",
-            security = {@SecurityRequirement(name = "basicAuth"), @SecurityRequirement(name = "bearerAuth")})
-    @ApiResponses(value = {
-            @ApiResponse(responseCode = "200",
-                    description = "Exported table data",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = InputStreamResource.class))}),
-            @ApiResponse(responseCode = "400",
-                    description = "Request pagination or table data select query is malformed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "403",
-                    description = "Export table data not allowed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Failed to find table in metadata database",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "503",
-                    description = "Failed to establish connection with the metadata service",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-    })
-    public ResponseEntity<InputStreamResource> exportDataset(@NotNull @PathVariable("databaseId") UUID databaseId,
-                                                             @NotNull @PathVariable("tableId") UUID tableId,
-                                                             @RequestParam(required = false) Instant timestamp,
-                                                             Principal principal)
-            throws RemoteUnavailableException, TableNotFoundException, NotAllowedException, StorageUnavailableException,
-            QueryMalformedException, MetadataServiceException, DatabaseNotFoundException {
-        log.debug("endpoint export table data, databaseId={}, tableId={}, timestamp={}", databaseId, tableId, timestamp);
-        /* parameters */
-        if (timestamp == null) {
-            timestamp = Instant.now();
-            log.debug("timestamp not set: default to {}", timestamp);
-        }
-        final TableDto table = cacheService.getTable(databaseId, tableId);
-        if (!table.getIsPublic()) {
-            if (principal == null) {
-                log.error("Failed to export private table: principal is null");
-                throw new NotAllowedException("Failed to export private table: principal is null");
-            }
-            cacheService.getAccess(databaseId, getId(principal));
-        }
-        final DatabaseDto database = cacheService.getDatabase(databaseId);
-        final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(),
-                table.getInternalName(), timestamp, null, null);
-        final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(table.getDatabaseId()),
-                query);
-        final ExportResourceDto resource = storageService.transformDataset(dataset);
-        final HttpHeaders headers = new HttpHeaders();
-        headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
-        log.trace("export table resulted in resource {}", resource);
-        return ResponseEntity.ok()
-                .headers(headers)
-                .body(resource.getResource());
-    }
-
     @PostMapping("/{tableId}/data/import")
     @Observed(name = "dbrepo_table_data_import")
     @PreAuthorize("hasAuthority('insert-table-data')")
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
index 5c1fdb57dbc30b428d104e4c145f4a0064105f78..b4c7fa715f667d7edf2727e7248af696266bf5e5 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
@@ -25,9 +25,9 @@ import lombok.extern.log4j.Log4j2;
 import org.apache.spark.sql.Dataset;
 import org.apache.spark.sql.Row;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.InputStreamResource;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -36,7 +36,6 @@ import java.security.Principal;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 @Log4j2
@@ -225,7 +224,8 @@ public class ViewEndpoint extends RestEndpoint {
                             @Header(name = "Access-Control-Expose-Headers", description = "Expose `X-Count` custom header", schema = @Schema(implementation = String.class), required = true)},
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = List.class))}),
+                            schema = @Schema(implementation = List.class)),
+                            @Content(mediaType = "text/csv")}),
             @ApiResponse(responseCode = "400",
                     description = "Request pagination is malformed",
                     content = {@Content(
@@ -241,6 +241,11 @@ public class ViewEndpoint extends RestEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "406",
+                    description = "Failed to format data",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "409",
                     description = "View schema could not be mapped",
                     content = {@Content(
@@ -252,17 +257,20 @@ public class ViewEndpoint extends RestEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
-    public ResponseEntity<List<Map<String, Object>>> getData(@NotNull @PathVariable("databaseId") UUID databaseId,
-                                                             @NotNull @PathVariable("viewId") UUID viewId,
-                                                             @RequestParam(required = false) Long page,
-                                                             @RequestParam(required = false) Long size,
-                                                             @RequestParam(required = false) Instant timestamp,
-                                                             @NotNull HttpServletRequest request,
-                                                             Principal principal)
+    public ResponseEntity<?> getData(@NotNull @PathVariable("databaseId") UUID databaseId,
+                                     @NotNull @PathVariable("viewId") UUID viewId,
+                                     @RequestParam(required = false) Long page,
+                                     @RequestParam(required = false) Long size,
+                                     @RequestParam(required = false) Instant timestamp,
+                                     @NotNull HttpServletRequest request,
+                                     @NotNull @RequestHeader("Accept") String accept,
+                                     Principal principal)
             throws DatabaseUnavailableException, RemoteUnavailableException, ViewNotFoundException, PaginationException,
-            QueryMalformedException, NotAllowedException, MetadataServiceException, TableNotFoundException, DatabaseNotFoundException {
-        log.debug("endpoint get view data, databaseId={}, viewId={}, page={}, size={}, timestamp={}", databaseId,
-                viewId, page, size, timestamp);
+            QueryMalformedException, NotAllowedException, MetadataServiceException, TableNotFoundException,
+            DatabaseNotFoundException, ViewMalformedException, StorageUnavailableException,
+            FormatNotAvailableException {
+        log.debug("endpoint get view data, databaseId={}, viewId={}, page={}, size={}, accept={}, timestamp={}",
+                databaseId, viewId, page, size, accept, timestamp);
         endpointValidator.validateDataParams(page, size);
         /* parameters */
         if (page == null) {
@@ -283,7 +291,9 @@ public class ViewEndpoint extends RestEndpoint {
                 log.error("Failed to get data from view: unauthorized");
                 throw new NotAllowedException("Failed to get data from view: unauthorized");
             }
-            cacheService.getAccess(databaseId, getId(principal));
+            if (!isSystem(principal)) {
+                cacheService.getAccess(databaseId, getId(principal));
+            }
         }
         final DatabaseDto database = cacheService.getDatabase(databaseId);
         try {
@@ -297,84 +307,32 @@ public class ViewEndpoint extends RestEndpoint {
             }
             headers.set("Access-Control-Expose-Headers", "X-Headers");
             headers.set("X-Headers", String.join(",", view.getColumns().stream().map(ViewColumnDto::getInternalName).toList()));
-            final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(),
-                    view.getInternalName(), timestamp, page, size);
-            final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(databaseId),
-                    query);
-            return ResponseEntity.ok()
-                    .headers(headers)
-                    .body(transform(dataset));
+            final String query = mariaDbMapper.rawSelectQuery(view.getQuery(), timestamp,
+                    accept.equals("text/csv") ? null : page,
+                    accept.equals("text/csv") ? null : size);
+            final Dataset<Row> dataset = subsetService.getData(database, query);
+            final String viewName = view.getQueryHash();
+            databaseService.createView(database, viewName, view.getQuery());
+            switch (accept) {
+                case MediaType.APPLICATION_JSON_VALUE:
+                    log.trace("accept header matches json");
+                    return ResponseEntity.ok()
+                            .headers(headers)
+                            .body(transform(dataset));
+                case "text/csv":
+                    log.trace("accept header matches csv");
+                    final ExportResourceDto resource = storageService.transformDataset(dataset);
+                    headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
+                    return ResponseEntity.ok()
+                            .headers(headers)
+                            .body(storageService.transformDataset(dataset)
+                                    .getResource());
+            }
+            throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': provided " + accept + " instead");
         } catch (SQLException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
         }
     }
 
-    @GetMapping("/{viewId}/export")
-    @Observed(name = "dbrepo_view_data_export")
-    @Operation(summary = "Get view data",
-            description = "Gets data from view with id as downloadable file. For tables in private databases, the user needs to have at least *READ* access to the associated database.",
-            security = {@SecurityRequirement(name = "basicAuth"), @SecurityRequirement(name = "bearerAuth")})
-    @ApiResponses(value = {
-            @ApiResponse(responseCode = "200",
-                    description = "Exported view data",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = InputStreamResource.class))}),
-            @ApiResponse(responseCode = "400",
-                    description = "Request pagination or view data select query is malformed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "403",
-                    description = "Export view data not allowed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Failed to find view in metadata database or export dataset",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "503",
-                    description = "Failed to establish connection with the metadata service",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-    })
-    public ResponseEntity<InputStreamResource> exportDataset(@NotNull @PathVariable("databaseId") UUID databaseId,
-                                                             @NotNull @PathVariable("viewId") UUID viewId,
-                                                             @RequestParam(required = false) Instant timestamp,
-                                                             Principal principal)
-            throws RemoteUnavailableException, ViewNotFoundException, NotAllowedException, MetadataServiceException,
-            StorageUnavailableException, QueryMalformedException, TableNotFoundException, DatabaseNotFoundException {
-        log.debug("endpoint export view data, databaseId={}, viewId={}", databaseId, viewId);
-        /* parameters */
-        if (timestamp == null) {
-            timestamp = Instant.now();
-            log.debug("timestamp not set: default to {}", timestamp);
-        }
-        /* parameters */
-        final ViewDto view = cacheService.getView(databaseId, viewId);
-        if (!view.getIsPublic()) {
-            if (principal == null) {
-                log.error("Failed to export private view: principal is null");
-                throw new NotAllowedException("Failed to export private view: principal is null");
-            }
-            cacheService.getAccess(databaseId, getId(principal));
-        }
-        final DatabaseDto database = cacheService.getDatabase(databaseId);
-        final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(),
-                view.getInternalName(), timestamp, null, null);
-        final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(databaseId),
-                query);
-        final ExportResourceDto resource = storageService.transformDataset(dataset);
-        final HttpHeaders headers = new HttpHeaders();
-        headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
-        log.trace("export table resulted in resource {}", resource);
-        return ResponseEntity.ok()
-                .headers(headers)
-                .body(resource.getResource());
-    }
-
 }
diff --git a/dbrepo-data-service/rest-service/src/main/resources/application.yml b/dbrepo-data-service/rest-service/src/main/resources/application.yml
index b5f592d570cb73677baaa00666af945901e1d256..53c0858bbd98acd3bb250b0def751534bc920548 100644
--- a/dbrepo-data-service/rest-service/src/main/resources/application.yml
+++ b/dbrepo-data-service/rest-service/src/main/resources/application.yml
@@ -74,6 +74,7 @@ dbrepo:
     default:
       read: "${GRANT_DEFAULT_READ:SELECT}"
       write: "${GRANT_DEFAULT_WRITE:SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE}"
+  website: "${BASE_URL:http://localhost}"
   credentialCacheTimeout: "${CREDENTIAL_CACHE_TIMEOUT:60}"
   minConcurrent: "${MIN_CONCURRENT_CONSUMERS:2}"
   maxConcurrent: "${MAX_CONCURRENT_CONSUMERS:6}"
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
index 9cdb0d99c82e399c1d8297c1c71dd1f6dd963a31..b034b791242dd92c640b0b721afa86a8197a7afd 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
@@ -33,7 +33,6 @@ import java.security.Principal;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 import static org.junit.jupiter.api.Assertions.*;
@@ -145,16 +144,15 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            generic_findById(DATABASE_1_ID, QUERY_1_ID, "application/json", null, null);
+            generic_findById(DATABASE_1_ID, QUERY_1_ID, null, null);
         });
     }
 
     @Test
     @WithMockUser(username = USER_1_USERNAME)
     public void findById_privateDataPrivateSchema_succeeds() throws DatabaseNotFoundException, SQLException,
-            RemoteUnavailableException, UserNotFoundException, QueryNotFoundException, MetadataServiceException,
-            DatabaseUnavailableException, TableNotFoundException, StorageUnavailableException, NotAllowedException,
-            QueryMalformedException, FormatNotAvailableException {
+            RemoteUnavailableException, UserNotFoundException, DatabaseUnavailableException, NotAllowedException,
+            QueryNotFoundException, MetadataServiceException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_1_ID))
@@ -163,15 +161,14 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(QUERY_1_DTO);
 
         /* test */
-        generic_findById(DATABASE_1_ID, QUERY_1_ID, "application/json", null, USER_1_PRINCIPAL);
+        generic_findById(DATABASE_1_ID, QUERY_1_ID, null, USER_1_PRINCIPAL);
     }
 
     @Test
     @WithMockUser(username = USER_1_USERNAME)
     public void findById_privateDataPrivateSchemaAcceptEmpty_succeeds() throws DatabaseNotFoundException, SQLException,
-            RemoteUnavailableException, UserNotFoundException, QueryNotFoundException, MetadataServiceException,
-            DatabaseUnavailableException, TableNotFoundException, StorageUnavailableException, NotAllowedException,
-            QueryMalformedException, FormatNotAvailableException {
+            RemoteUnavailableException, UserNotFoundException, DatabaseUnavailableException, NotAllowedException,
+            QueryNotFoundException, MetadataServiceException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_1_ID))
@@ -180,15 +177,14 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(QUERY_1_DTO);
 
         /* test */
-        generic_findById(DATABASE_1_ID, QUERY_1_ID, null, null, USER_1_PRINCIPAL);
+        generic_findById(DATABASE_1_ID, QUERY_1_ID, null, USER_1_PRINCIPAL);
     }
 
     @Test
     @WithMockUser(username = USER_3_USERNAME)
     public void findById_publicDataPrivateSchema_succeeds() throws DatabaseNotFoundException, SQLException,
             RemoteUnavailableException, UserNotFoundException, DatabaseUnavailableException, NotAllowedException,
-            StorageUnavailableException, QueryMalformedException, QueryNotFoundException,
-            FormatNotAvailableException, TableNotFoundException, MetadataServiceException {
+            QueryNotFoundException, MetadataServiceException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_3_ID))
@@ -197,32 +193,15 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(QUERY_5_DTO);
 
         /* test */
-        generic_findById(DATABASE_3_ID, QUERY_5_ID, "application/json", null, USER_3_PRINCIPAL);
-    }
-
-    @Test
-    @WithAnonymousUser
-    public void findById_format_fails() throws DatabaseNotFoundException, RemoteUnavailableException, SQLException,
-            UserNotFoundException, QueryNotFoundException, MetadataServiceException {
-
-        /* mock */
-        when(credentialService.getDatabase(DATABASE_4_ID))
-                .thenReturn(DATABASE_4_PRIVILEGED_DTO);
-        when(subsetService.findById(DATABASE_4_PRIVILEGED_DTO, QUERY_7_ID))
-                .thenReturn(QUERY_7_DTO);
-
-        /* test */
-        assertThrows(FormatNotAvailableException.class, () -> {
-            generic_findById(DATABASE_4_ID, QUERY_7_ID, "application/pdf", null, null);
-        });
+        generic_findById(DATABASE_3_ID, QUERY_5_ID, null, USER_3_PRINCIPAL);
     }
 
     @Test
     @WithMockUser(username = USER_1_USERNAME)
-    public void findById_privateDataPrivateSchemaAcceptCsv_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
-            UserNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException,
-            QueryNotFoundException, FormatNotAvailableException, SQLException, MetadataServiceException,
-            TableNotFoundException, NotAllowedException {
+    public void findById_privateDataPrivateSchemaAcceptCsv_succeeds() throws DatabaseNotFoundException,
+            RemoteUnavailableException, UserNotFoundException, DatabaseUnavailableException,
+            StorageUnavailableException, QueryMalformedException, QueryNotFoundException, SQLException,
+            MetadataServiceException, TableNotFoundException, NotAllowedException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -236,7 +215,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(EXPORT_RESOURCE_DTO);
 
         /* test */
-        generic_findById(DATABASE_1_ID, QUERY_1_ID, "text/csv", null, USER_1_PRINCIPAL);
+        generic_findById(DATABASE_1_ID, QUERY_1_ID, null, USER_1_PRINCIPAL);
     }
 
     @Test
@@ -250,7 +229,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            generic_findById(DATABASE_3_ID, QUERY_5_ID, "text/csv", Instant.now(), null);
+            generic_findById(DATABASE_3_ID, QUERY_5_ID, Instant.now(), null);
         });
     }
 
@@ -273,7 +252,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            generic_findById(DATABASE_3_ID, QUERY_5_ID, "text/csv", Instant.now(), null);
+            generic_findById(DATABASE_3_ID, QUERY_5_ID, Instant.now(), null);
         });
     }
 
@@ -289,7 +268,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(DatabaseNotFoundException.class, () -> {
-            generic_findById(DATABASE_3_ID, QUERY_5_ID, "application/json", null, null);
+            generic_findById(DATABASE_3_ID, QUERY_5_ID, null, null);
         });
     }
 
@@ -307,7 +286,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(DatabaseUnavailableException.class, () -> {
-            generic_findById(DATABASE_3_ID, QUERY_5_ID, "application/json", null, USER_3_PRINCIPAL);
+            generic_findById(DATABASE_3_ID, QUERY_5_ID, null, USER_3_PRINCIPAL);
         });
     }
 
@@ -318,7 +297,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
             StorageNotFoundException, DatabaseUnavailableException, StorageUnavailableException, SQLException,
             QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException, RemoteUnavailableException,
             MetadataServiceException, TableNotFoundException, ViewMalformedException, ViewNotFoundException,
-            ImageNotFoundException {
+            ImageNotFoundException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -348,7 +327,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
             PaginationException, StorageNotFoundException, DatabaseUnavailableException, StorageUnavailableException,
             QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException, RemoteUnavailableException,
             SQLException, MetadataServiceException, TableNotFoundException, ViewMalformedException,
-            ViewNotFoundException, ImageNotFoundException {
+            ViewNotFoundException, ImageNotFoundException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -398,7 +377,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
             TableMalformedException, NotAllowedException, SQLException, QueryNotFoundException, PaginationException,
             DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException,
             QueryNotSupportedException, StorageNotFoundException, TableNotFoundException, ViewMalformedException,
-            ViewNotFoundException, ImageNotFoundException {
+            ViewNotFoundException, ImageNotFoundException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -426,7 +405,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
             NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException,
             StorageUnavailableException, QueryMalformedException, QueryNotSupportedException, PaginationException,
             StorageNotFoundException, TableNotFoundException, ViewMalformedException, ViewNotFoundException,
-            ImageNotFoundException {
+            ImageNotFoundException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -478,7 +457,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException,
             NotAllowedException, SQLException, QueryNotFoundException, QueryMalformedException,
             DatabaseUnavailableException, PaginationException, MetadataServiceException, TableNotFoundException,
-            ViewNotFoundException, ViewMalformedException {
+            ViewNotFoundException, ViewMalformedException, StorageUnavailableException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -498,16 +477,17 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null, null);
+        final ResponseEntity<?> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID,
+                null, "application/json", httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
 
     @Test
     public void getData_head_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
-            UserNotFoundException, NotAllowedException, SQLException, QueryNotFoundException, TableMalformedException,
-            QueryMalformedException, DatabaseUnavailableException, PaginationException, MetadataServiceException,
-            TableNotFoundException, ViewNotFoundException, ViewMalformedException {
+            UserNotFoundException, NotAllowedException, SQLException, QueryNotFoundException, QueryMalformedException,
+            DatabaseUnavailableException, PaginationException, MetadataServiceException, TableNotFoundException,
+            ViewNotFoundException, ViewMalformedException, StorageUnavailableException, FormatNotAvailableException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_3_ID))
@@ -520,7 +500,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("HEAD");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null, null);
+        final ResponseEntity<?> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID,
+                null, "application/json", httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getHeaders().get("X-Count"));
         assertEquals(1, response.getHeaders().get("X-Count").size());
@@ -532,7 +513,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_private_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
             UserNotFoundException, DatabaseUnavailableException, NotAllowedException, QueryMalformedException,
             QueryNotFoundException, PaginationException, SQLException, MetadataServiceException,
-            TableNotFoundException, ViewNotFoundException, ViewMalformedException {
+            TableNotFoundException, ViewNotFoundException, ViewMalformedException, StorageUnavailableException,
+            FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -552,7 +534,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
+        final ResponseEntity<?> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID,
+                USER_1_PRINCIPAL, "application/json", httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
@@ -568,7 +551,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, null, httpServletRequest, null, null, null);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, null, "application/json", httpServletRequest, null, null, null);
         });
     }
 
@@ -586,7 +569,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, "application/json", httpServletRequest, null, null, null);
         });
     }
 
@@ -595,7 +578,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_privateHead_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
             UserNotFoundException, DatabaseUnavailableException, NotAllowedException, QueryMalformedException,
             QueryNotFoundException, PaginationException, SQLException, MetadataServiceException,
-            TableNotFoundException, ViewNotFoundException, ViewMalformedException {
+            TableNotFoundException, ViewNotFoundException, ViewMalformedException, StorageUnavailableException,
+            FormatNotAvailableException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_1_ID))
@@ -608,7 +592,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("HEAD");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
+        final ResponseEntity<?> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID,
+                USER_1_PRINCIPAL, "GET", httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getHeaders().get("X-Count"));
         assertEquals(1, response.getHeaders().get("X-Count").size());
@@ -734,14 +719,12 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         return response.getBody();
     }
 
-    protected void generic_findById(UUID databaseId, UUID subsetId, String accept, Instant timestamp,
-                                    Principal principal) throws UserNotFoundException, DatabaseUnavailableException,
-            StorageUnavailableException, NotAllowedException, QueryMalformedException, QueryNotFoundException,
-            DatabaseNotFoundException, RemoteUnavailableException, FormatNotAvailableException,
-            MetadataServiceException, TableNotFoundException {
+    protected void generic_findById(UUID databaseId, UUID subsetId, Instant timestamp, Principal principal)
+            throws UserNotFoundException, DatabaseUnavailableException, NotAllowedException, QueryNotFoundException,
+            DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException {
 
         /* test */
-        final ResponseEntity<?> response = subsetEndpoint.findById(databaseId, subsetId, accept, timestamp, principal);
+        final ResponseEntity<?> response = subsetEndpoint.findById(databaseId, subsetId, timestamp, principal);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
index 25f3b60ceac1f47225e73c237cefc215c21f1696..3a5a62731bc595c2e971a382cf6c3a1c1b5791aa 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
@@ -39,7 +39,6 @@ import java.sql.SQLException;
 import java.time.Instant;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Stream;
 
 import static org.junit.jupiter.api.Assertions.*;
@@ -292,7 +291,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void getData_publicDataPrivateSchema_succeeds() throws DatabaseUnavailableException, TableNotFoundException, QueryMalformedException,
             RemoteUnavailableException, PaginationException, MetadataServiceException, NotAllowedException,
-            DatabaseNotFoundException {
+            DatabaseNotFoundException, StorageUnavailableException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -306,7 +305,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_4_ID, null, null, null, httpServletRequest, null);
+        final ResponseEntity<?> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_4_ID, null, null, null, "application/json", httpServletRequest, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
 
     }
@@ -315,7 +314,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void getData_head_succeeds() throws DatabaseUnavailableException, TableNotFoundException,
             SQLException, QueryMalformedException, RemoteUnavailableException, PaginationException,
-            MetadataServiceException, NotAllowedException, DatabaseNotFoundException {
+            MetadataServiceException, NotAllowedException, DatabaseNotFoundException, StorageUnavailableException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -331,7 +330,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("HEAD");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_2_ID, TABLE_5_ID, null, null, null, httpServletRequest, null);
+        final ResponseEntity<?> response = tableEndpoint.getData(DATABASE_2_ID, TABLE_5_ID, null, null, null, "application/json", httpServletRequest, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getHeaders().get("Access-Control-Expose-Headers"));
         assertEquals("X-Count", response.getHeaders().get("Access-Control-Expose-Headers").get(0));
@@ -351,7 +350,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, httpServletRequest, null);
+            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "application/json", httpServletRequest, null);
         });
     }
 
@@ -369,14 +368,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, httpServletRequest, USER_2_PRINCIPAL);
+            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "application/json", httpServletRequest, USER_2_PRINCIPAL);
         });
     }
 
     @Test
     @WithAnonymousUser
     public void getData_notAllowed_fails() throws TableNotFoundException, RemoteUnavailableException,
-            MetadataServiceException{
+            MetadataServiceException {
 
         /* mock */
         when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID))
@@ -386,7 +385,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null);
+            tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, "application/json", httpServletRequest, null);
         });
     }
 
@@ -408,7 +407,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(DatabaseUnavailableException.class, () -> {
-            tableEndpoint.getData(DATABASE_2_ID, TABLE_5_ID, null, null, null, httpServletRequest, null);
+            tableEndpoint.getData(DATABASE_2_ID, TABLE_5_ID, null, null, null, "application/json", httpServletRequest, null);
         });
     }
 
@@ -426,7 +425,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(RemoteUnavailableException.class, () -> {
-            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, httpServletRequest, USER_2_PRINCIPAL);
+            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "application/json", httpServletRequest, USER_2_PRINCIPAL);
         });
     }
 
@@ -435,7 +434,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
     @MethodSource("anyAccess_parameters")
     public void getData_private_succeeds(String name, DatabaseAccessDto access) throws DatabaseUnavailableException,
             TableNotFoundException, QueryMalformedException, RemoteUnavailableException, PaginationException,
-            MetadataServiceException, NotAllowedException, DatabaseNotFoundException {
+            MetadataServiceException, NotAllowedException, DatabaseNotFoundException, StorageUnavailableException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -451,7 +450,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, httpServletRequest, USER_2_PRINCIPAL);
+        final ResponseEntity<?> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "application/json", httpServletRequest, USER_2_PRINCIPAL);
         assertEquals(HttpStatus.OK, response.getStatusCode());
     }
 
@@ -467,7 +466,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(TableNotFoundException.class, () -> {
-            tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null);
+            tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, "application/json", httpServletRequest, null);
         });
     }
 
@@ -1323,8 +1322,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithAnonymousUser
-    public void exportData_publicDataPrivateSchema_succeeds() throws TableNotFoundException, NotAllowedException, StorageUnavailableException,
-            QueryMalformedException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException {
+    public void getData_publicDataPrivateSchemaTextCsv_succeeds() throws TableNotFoundException, NotAllowedException,
+            StorageUnavailableException, QueryMalformedException, RemoteUnavailableException, MetadataServiceException,
+            DatabaseNotFoundException, DatabaseUnavailableException, FormatNotAvailableException, PaginationException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -1334,18 +1334,21 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_1_PRIVILEGED_DTO);
         when(subsetService.getData(any(DatabaseDto.class), anyString()))
                 .thenReturn(mock);
+        when(httpServletRequest.getMethod())
+                .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<InputStreamResource> response = tableEndpoint.exportDataset(DATABASE_1_ID, TABLE_4_ID, null, null);
+        final ResponseEntity<?> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_4_ID, null, null, null, "text/csv", httpServletRequest, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
     }
 
     @ParameterizedTest
     @WithMockUser(username = USER_2_USERNAME)
     @MethodSource("anyAccess_parameters")
-    public void exportData_privateDataPrivateSchema_succeeds(String name, DatabaseAccessDto access)
+    public void getData_privateDataPrivateSchemaTextCsv_succeeds(String name, DatabaseAccessDto access)
             throws TableNotFoundException, NotAllowedException, StorageUnavailableException, QueryMalformedException,
-            RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException {
+            RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException,
+            DatabaseUnavailableException, FormatNotAvailableException, PaginationException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -1359,9 +1362,11 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_1_DTO);
         when(subsetService.getData(any(DatabaseDto.class), anyString()))
                 .thenReturn(mock);
+        when(httpServletRequest.getMethod())
+                .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<InputStreamResource> response = tableEndpoint.exportDataset(DATABASE_1_ID, TABLE_1_ID, null, USER_2_PRINCIPAL);
+        final ResponseEntity<?> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "text/csv", httpServletRequest, USER_2_PRINCIPAL);
         assertEquals(HttpStatus.OK, response.getStatusCode());
     }
 
@@ -1381,7 +1386,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            tableEndpoint.exportDataset(DATABASE_1_ID, TABLE_1_ID, null, null);
+            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "text/csv", httpServletRequest, null);
         });
     }
 
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
index 0393be3dad8da280f29cc1be9133ffa42c9f6cb2..23ad1b73e3db99c355d08aa8011ab658fb48e728 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
@@ -29,7 +29,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.util.List;
-import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -253,7 +252,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_1_PRIVILEGED_DTO);
         doNothing()
                 .when(viewService)
-                .delete(DATABASE_1_PRIVILEGED_DTO,VIEW_1_DTO);
+                .delete(DATABASE_1_PRIVILEGED_DTO, VIEW_1_DTO);
 
         /* test */
         assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> {
@@ -281,7 +280,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"})
     public void getData_privateDataPrivateSchema_succeeds() throws RemoteUnavailableException, ViewNotFoundException,
             DatabaseUnavailableException, QueryMalformedException, PaginationException, NotAllowedException,
-            MetadataServiceException, TableNotFoundException, DatabaseNotFoundException {
+            MetadataServiceException, TableNotFoundException, DatabaseNotFoundException, ViewMalformedException, StorageUnavailableException, FormatNotAvailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -297,7 +296,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, USER_1_PRINCIPAL);
+        final ResponseEntity<?> response = viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "application/json", USER_1_PRINCIPAL);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
@@ -323,7 +322,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, null);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "application/json", null);
         });
     }
 
@@ -331,7 +330,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"})
     public void getData_privateHead_succeeds() throws RemoteUnavailableException, ViewNotFoundException,
             SQLException, DatabaseUnavailableException, QueryMalformedException, PaginationException,
-            NotAllowedException, MetadataServiceException, TableNotFoundException, DatabaseNotFoundException {
+            NotAllowedException, MetadataServiceException, TableNotFoundException, DatabaseNotFoundException, ViewMalformedException, StorageUnavailableException, FormatNotAvailableException {
 
         /* mock */
         when(credentialService.getView(DATABASE_1_ID, VIEW_3_ID))
@@ -346,7 +345,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(VIEW_3_DATA_COUNT);
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = viewEndpoint.getData(DATABASE_1_ID, VIEW_3_ID, null, null, null, httpServletRequest, USER_1_PRINCIPAL);
+        final ResponseEntity<?> response = viewEndpoint.getData(DATABASE_1_ID, VIEW_3_ID, null, null, null, httpServletRequest, "application/json", USER_1_PRINCIPAL);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getHeaders().get("X-Count"));
         assertEquals(1, response.getHeaders().get("X-Count").size());
@@ -373,13 +372,13 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, USER_4_PRINCIPAL);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "application/json", USER_4_PRINCIPAL);
         });
     }
 
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"})
-    public void getData_viewNotFound_fails() throws RemoteUnavailableException, ViewNotFoundException,
+    public void getData_viewNotFoundTextCsv_fails() throws RemoteUnavailableException, ViewNotFoundException,
             MetadataServiceException {
 
         /* mock */
@@ -389,7 +388,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(ViewNotFoundException.class, () -> {
-            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, USER_4_PRINCIPAL);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "text/csv", USER_4_PRINCIPAL);
         });
     }
 
@@ -407,13 +406,13 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, USER_4_PRINCIPAL);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "application/json", USER_4_PRINCIPAL);
         });
     }
 
     @Test
     @WithMockUser(username = USER_3_USERNAME, authorities = {"view-database-view-data"})
-    public void exportDataset_privateNoAccess_fails() throws RemoteUnavailableException, ViewNotFoundException,
+    public void getData_privateNoAccessTextCsv_fails() throws RemoteUnavailableException, ViewNotFoundException,
             NotAllowedException, MetadataServiceException {
 
         /* mock */
@@ -425,13 +424,13 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            viewEndpoint.exportDataset(DATABASE_1_ID, VIEW_1_ID, null, USER_4_PRINCIPAL);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "text/csv", USER_4_PRINCIPAL);
         });
     }
 
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"})
-    public void exportDataset_viewNotFound_fails() throws RemoteUnavailableException, ViewNotFoundException,
+    public void getData_viewNotFound_fails() throws RemoteUnavailableException, ViewNotFoundException,
             MetadataServiceException {
 
         /* mock */
@@ -441,25 +440,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(ViewNotFoundException.class, () -> {
-            viewEndpoint.exportDataset(DATABASE_1_ID, VIEW_1_ID, null, USER_4_PRINCIPAL);
-        });
-    }
-
-    @Test
-    @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"})
-    public void exportDataset_privateNoAccess_succeeds() throws RemoteUnavailableException, ViewNotFoundException,
-            NotAllowedException, MetadataServiceException {
-
-        /* mock */
-        when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID))
-                .thenReturn(VIEW_1_DTO);
-        doThrow(NotAllowedException.class)
-                .when(credentialService)
-                .getAccess(DATABASE_1_ID, USER_4_ID);
-
-        /* test */
-        assertThrows(NotAllowedException.class, () -> {
-            viewEndpoint.exportDataset(DATABASE_1_ID, VIEW_1_ID, null, USER_4_PRINCIPAL);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, "application/json", USER_4_PRINCIPAL);
         });
     }
 
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
index ae03fdbf68cefc1db05455d0ec228ea00be1c12f..de1c875e0aef96a54f283e31a8ef90d9e8468de0 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
@@ -1,8 +1,6 @@
 package at.tuwien.mvc;
 
-import at.tuwien.api.database.query.ExecuteStatementDto;
 import at.tuwien.api.database.query.ImportDto;
-import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.database.query.QueryPersistDto;
 import at.tuwien.api.database.table.TupleDeleteDto;
 import at.tuwien.api.database.table.TupleDto;
@@ -116,7 +114,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
             /* ignore */
         }
         try {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, "application/json", httpServletRequest, null, 0L, 10L);
         } catch (Exception e) {
             /* ignore */
         }
@@ -126,7 +124,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
             /* ignore */
         }
         try {
-            subsetEndpoint.findById(DATABASE_1_ID, QUERY_1_ID, "application/json", null, USER_1_PRINCIPAL);
+            subsetEndpoint.findById(DATABASE_1_ID, QUERY_1_ID, null, USER_1_PRINCIPAL);
         } catch (Exception e) {
             /* ignore */
         }
@@ -145,7 +143,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
 
         /* mock */
         try {
-            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, httpServletRequest, null);
+            tableEndpoint.getData(DATABASE_1_ID, TABLE_1_ID, null, null, null, "application/json", httpServletRequest, null);
         } catch (Exception e) {
             /* ignore */
         }
@@ -169,11 +167,6 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
         } catch (Exception e) {
             /* ignore */
         }
-        try {
-            tableEndpoint.exportDataset(DATABASE_1_ID, TABLE_1_ID, null, USER_1_PRINCIPAL);
-        } catch (Exception e) {
-            /* ignore */
-        }
         try {
             tableEndpoint.importDataset(DATABASE_1_ID, TABLE_1_ID, ImportDto.builder().build(), USER_1_PRINCIPAL, TOKEN_ACCESS_TOKEN);
         } catch (Exception e) {
@@ -182,8 +175,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
 
         /* test */
         for (String metric : List.of("dbrepo_table_data_list", "dbrepo_table_data_create", "dbrepo_table_data_update",
-                "dbrepo_table_data_delete", "dbrepo_table_data_history", "dbrepo_table_data_export",
-                "dbrepo_table_data_import")) {
+                "dbrepo_table_data_delete", "dbrepo_table_data_history", "dbrepo_table_data_import")) {
             assertThat(registry)
                     .hasObservationWithNameEqualTo(metric);
         }
@@ -195,7 +187,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
 
         /* mock */
         try {
-            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, 0L, 10L, null, httpServletRequest, USER_1_PRINCIPAL);
+            viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, 0L, 10L, null, httpServletRequest, "application/json", USER_1_PRINCIPAL);
         } catch (Exception e) {
             /* ignore */
         }
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/SubsetEndpointMvcTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/SubsetEndpointMvcTest.java
index 158c6743a4e7bac049cae0211fe764030ab4a3f0..37f6d367dc125a155dcdb7ae85c9bdf30cc8c6a2 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/SubsetEndpointMvcTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/SubsetEndpointMvcTest.java
@@ -36,21 +36,6 @@ public class SubsetEndpointMvcTest extends AbstractUnitTest {
     @Autowired
     private MockMvc mockMvc;
 
-    @Test
-    public void findById_noAcceptHeader_fails() throws Exception {
-
-        /* mock */
-        when(metadataServiceGateway.getDatabaseById(DATABASE_3_ID))
-                .thenReturn(DATABASE_3_PRIVILEGED_DTO);
-        when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID))
-                .thenReturn(QUERY_5_DTO);
-
-        /* test */
-        this.mockMvc.perform(get("/api/database/" + DATABASE_3_ID + "/subset/" + QUERY_5_ID))
-                .andDo(print())
-                .andExpect(status().isBadRequest());
-    }
-
     @Test
     public void findById_privateDataPublicSchema_jsonAcceptHeader_fails() throws Exception {
 
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java
index 7bdf8fa14118f7f6cca621cf01e7567ce608dfdc..0bd399d454d4427440684a57d3f2611079279bca 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java
@@ -6,7 +6,6 @@ import at.tuwien.api.database.DatabaseBriefDto;
 import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.ViewColumnDto;
 import at.tuwien.api.database.ViewDto;
-import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.database.table.TableBriefDto;
 import at.tuwien.api.database.table.TableDto;
 import at.tuwien.api.database.table.columns.ColumnDto;
@@ -27,10 +26,6 @@ public interface MetadataMapper {
 
     org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MetadataMapper.class);
 
-    default String queryDtoToViewName(QueryDto subset) {
-        return subset.getQueryHash();
-    }
-
     ContainerDto containerDtoToContainerDto(ContainerDto data);
 
     DatabaseBriefDto databaseDtoToDatabaseBriefDto(DatabaseDto data);
diff --git a/dbrepo-gateway-service/dbrepo.conf b/dbrepo-gateway-service/dbrepo.conf
index 165aba7643fcda32b94784d757d93e253814a1e0..f181fdf7a70945280453f345f6a639921967abca 100644
--- a/dbrepo-gateway-service/dbrepo.conf
+++ b/dbrepo-gateway-service/dbrepo.conf
@@ -123,7 +123,7 @@ server {
         proxy_read_timeout      90;
     }
 
-    location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/table/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/(data|history|export)" {
+    location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/table/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/(data|history)" {
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -132,7 +132,7 @@ server {
         proxy_read_timeout      90;
     }
 
-    location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/view/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/(data|export)" {
+    location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/view/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/data" {
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -168,6 +168,15 @@ server {
         proxy_read_timeout      90;
     }
 
+    location ~ "/api/identifier/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})" {
+        proxy_set_header        Host $host;
+        proxy_set_header        X-Real-IP $remote_addr;
+        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header        X-Forwarded-Proto $scheme;
+        proxy_pass              http://metadata;
+        proxy_read_timeout      90;
+    }
+
     location ~ "/pid/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})" {
         rewrite /pid/(.*) /api/identifier/$1 break;
         proxy_set_header        Host $host;
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java
index 57ecb5ad625017fec1571a1da53a83cbd5fcf852..0bc16d61cd9a1dc45c129184ec18cfb49ed0d754 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java
@@ -46,6 +46,9 @@ public class IdentifierDto {
     @Schema(example = "null")
     private UUID viewId;
 
+    @NotNull
+    private LinksDto links;
+
     @NotNull
     @Schema(example = "database")
     private IdentifierTypeDto type;
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/LinksDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/LinksDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..fcef2a659750d9cf6b78bdc54b4a627dbcc0935d
--- /dev/null
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/LinksDto.java
@@ -0,0 +1,32 @@
+package at.tuwien.api.identifier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.*;
+import lombok.extern.jackson.Jacksonized;
+
+
+@Getter
+@Setter
+@Builder
+@EqualsAndHashCode
+@NoArgsConstructor
+@AllArgsConstructor
+@Jacksonized
+@ToString
+public class LinksDto {
+
+    @NotNull
+    @Schema(example = "http://example.com/api/")
+    private String self;
+
+    @NotNull
+    @JsonProperty("self_html")
+    @Schema(example = "http://example.com")
+    private String selfHtml;
+
+    @Schema(example = "http://example.com")
+    private String data;
+
+}
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java
index 2d18ca0c49124539a6b9aa6072396aa247eb8167..74284789247ee20deac7df99c49a4f60e8cfa765 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java
@@ -318,10 +318,27 @@ public interface MetadataMapper {
     Identifier identifierDtoToIdentifier(IdentifierDto data);
 
     @Mappings({
-            @Mapping(target = "databaseId", source = "database.id")
+            @Mapping(target = "databaseId", source = "database.id"),
+            @Mapping(target = "links", expression = "java(identifierToLinksDto(data))"),
     })
     IdentifierDto identifierToIdentifierDto(Identifier data);
 
+    default LinksDto identifierToLinksDto(Identifier data) {
+        final LinksDto links = LinksDto.builder()
+                .self("/api/identifier/" + data.getId())
+                .selfHtml("/pid/" + data.getId())
+                .build();
+        switch (data.getType()) {
+            case VIEW ->
+                    links.setData("/api/database/" + data.getDatabase().getId() + "/view/" + data.getViewId() + "/data");
+            case TABLE ->
+                    links.setData("/api/database/" + data.getDatabase().getId() + "/table/" + data.getTableId() + "/data");
+            case SUBSET ->
+                    links.setData("/api/database/" + data.getDatabase().getId() + "/subset/" + data.getQueryId() + "/data");
+        }
+        return links;
+    }
+
     @Mappings({
             @Mapping(target = "databaseId", source = "database.id"),
             @Mapping(target = "ownedBy", source = "owner.id")
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
index 31dd1e542d53112ff42b49a6e5f6269255088ac6..96deaea775defd1562aba3601d9ba513b771f401 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
@@ -9,7 +9,6 @@ import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.entities.identifier.Identifier;
 import at.tuwien.entities.identifier.IdentifierStatusType;
-import at.tuwien.entities.identifier.IdentifierType;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.MetadataMapper;
@@ -126,7 +125,7 @@ public class IdentifierEndpoint extends AbstractEndpoint {
     }
 
     @GetMapping(value = "/{identifierId}", produces = {MediaType.APPLICATION_JSON_VALUE, "application/ld+json",
-            MediaType.TEXT_XML_VALUE, "text/csv", "text/bibliography", "text/bibliography; style=apa",
+            MediaType.TEXT_XML_VALUE, "text/bibliography", "text/bibliography; style=apa",
             "text/bibliography; style=ieee", "text/bibliography; style=bibtex"})
     @Transactional(readOnly = true)
     @Observed(name = "dbrepo_identifier_find")
@@ -138,7 +137,6 @@ public class IdentifierEndpoint extends AbstractEndpoint {
                     content = {
                             @Content(mediaType = "application/json", schema = @Schema(implementation = IdentifierDto.class)),
                             @Content(mediaType = "application/ld+json", schema = @Schema(implementation = LdDatasetDto.class)),
-                            @Content(mediaType = "text/csv"),
                             @Content(mediaType = "text/xml"),
                             @Content(mediaType = "text/bibliography"),
                             @Content(mediaType = "text/bibliography; style=apa"),
@@ -190,7 +188,7 @@ public class IdentifierEndpoint extends AbstractEndpoint {
                                   @RequestHeader(HttpHeaders.ACCEPT) String accept,
                                   Principal principal) throws IdentifierNotFoundException,
             DataServiceException, DataServiceConnectionException, MalformedException, FormatNotAvailableException,
-            QueryNotFoundException, NotAllowedException {
+            QueryNotFoundException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         log.debug("endpoint find identifier, identifierId={}, accept={}", identifierId, accept);
         if (accept == null) {
             accept = "";
@@ -212,13 +210,6 @@ public class IdentifierEndpoint extends AbstractEndpoint {
             case "application/ld+json":
                 log.trace("accept header matches json-ld");
                 return ResponseEntity.ok(metadataMapper.identifierToLdDatasetDto(identifier, endpointConfig.getWebsiteUrl()));
-            case "text/csv":
-                log.trace("accept header matches csv");
-                if (identifier.getType().equals(IdentifierType.DATABASE)) {
-                    log.error("Failed to export dataset: identifier type is database");
-                    throw new FormatNotAvailableException("Failed to export dataset: identifier type is database");
-                }
-                return ResponseEntity.ok(identifierService.exportResource(identifier));
             case "text/xml":
                 log.trace("accept header matches xml");
                 return ResponseEntity.ok(identifierService.exportMetadata(identifier));
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java
index 1e003041027ed22072d167eae81fab3a5d32c813..59aca6a405cf0086fb1cc39e033d4865a33df082 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java
@@ -365,20 +365,6 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
         assertEquals(1, identifiers.size());
     }
 
-    @Test
-    @WithAnonymousUser
-    public void find_textCsvDatabase_fails() throws IdentifierNotFoundException {
-
-        /* mock */
-        when(identifierService.find(IDENTIFIER_1_ID))
-                .thenReturn(IDENTIFIER_1);
-
-        /* test */
-        assertThrows(FormatNotAvailableException.class, () -> {
-            identifierEndpoint.find(IDENTIFIER_1_ID, "text/csv", null);
-        });
-    }
-
     @Test
     @WithAnonymousUser
     public void find_draft_fails() throws IdentifierNotFoundException {
@@ -410,7 +396,8 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @Test
     @WithMockUser(username = USER_2_USERNAME)
     public void find_draft_succeeds() throws IdentifierNotFoundException, MalformedException, NotAllowedException,
-            DataServiceException, QueryNotFoundException, DataServiceConnectionException, FormatNotAvailableException {
+            DataServiceException, QueryNotFoundException, DataServiceConnectionException, FormatNotAvailableException,
+            TableNotFoundException, ViewNotFoundException {
 
         /* mock */
         when(identifierService.find(IDENTIFIER_5_ID))
@@ -424,7 +411,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_defaultHtmlRespondsJson_succeeds() throws IdentifierNotFoundException, MalformedException,
             NotAllowedException, DataServiceException, QueryNotFoundException, DataServiceConnectionException,
-            FormatNotAvailableException {
+            FormatNotAvailableException, TableNotFoundException, ViewNotFoundException {
 
         /* mock */
         when(identifierService.find(IDENTIFIER_1_ID))
@@ -438,7 +425,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_4_USERNAME)
     public void find_json0_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "application/json";
         final IdentifierDto compare = objectMapper.readValue(FileUtils.readFileToString(new File("src/test/resources/json/metadata0.json"), StandardCharsets.UTF_8), IdentifierDto.class);
 
@@ -468,7 +455,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_json1_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "application/json";
         final IdentifierDto compare = objectMapper.readValue(FileUtils.readFileToString(new File("src/test/resources/json/metadata1.json"), StandardCharsets.UTF_8), IdentifierDto.class);
 
@@ -514,34 +501,11 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
         assertEquals(compare.getCreators().get(0).getNameIdentifierScheme(), creator0.getNameIdentifierScheme());
     }
 
-    @Test
-    @WithAnonymousUser
-    public void find_csv_succeeds() throws IOException, MalformedException, DataServiceException,
-            DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
-        final String accept = "text/csv";
-        final InputStreamResource compare = new InputStreamResource(FileUtils.openInputStream(new File("src/test/resources/csv/keyboard.csv")));
-        final InputStreamResource mock = new InputStreamResource(FileUtils.openInputStream(new File("src/test/resources/csv/keyboard.csv")));
-
-        /* mock */
-        when(identifierService.find(IDENTIFIER_2_ID))
-                .thenReturn(IDENTIFIER_2);
-        when(identifierService.exportResource(IDENTIFIER_2))
-                .thenReturn(mock);
-
-        /* test */
-        final ResponseEntity<?> response = identifierEndpoint.find(IDENTIFIER_2_ID, accept, null);
-        assertEquals(HttpStatus.OK, response.getStatusCode());
-        final InputStreamResource body = (InputStreamResource) response.getBody();
-        assertNotNull(body);
-        assertEquals(inputStreamToString(compare.getInputStream()), inputStreamToString(body.getInputStream()));
-    }
-
     @Test
     @WithAnonymousUser
     public void find_bibliography_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_apa1.txt"),
                 StandardCharsets.UTF_8);
@@ -584,7 +548,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_4_USERNAME)
     public void find_bibliographyApa0_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=apa";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_apa0.txt"),
                 StandardCharsets.UTF_8);
@@ -607,7 +571,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyApa1_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=apa";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_apa1.txt"),
                 StandardCharsets.UTF_8);
@@ -630,7 +594,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_2_USERNAME)
     public void find_draftBibliographyApa2_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=apa";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_apa2.txt"),
                 StandardCharsets.UTF_8);
@@ -653,7 +617,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyApa3_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=apa";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_apa3.txt"),
                 StandardCharsets.UTF_8);
@@ -676,7 +640,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyApa4_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=apa";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_apa4.txt"),
                 StandardCharsets.UTF_8);
@@ -699,7 +663,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_4_USERNAME)
     public void find_bibliographyIeee0_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=ieee";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_ieee0.txt"),
                 StandardCharsets.UTF_8);
@@ -722,7 +686,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyIeee1_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=ieee";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_ieee1.txt"),
                 StandardCharsets.UTF_8);
@@ -745,7 +709,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_2_USERNAME)
     public void find_bibliographyIeee2_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=ieee";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_ieee2.txt"),
                 StandardCharsets.UTF_8);
@@ -768,7 +732,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyIeee3_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=ieee";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_ieee3.txt"),
                 StandardCharsets.UTF_8);
@@ -791,7 +755,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_4_USERNAME)
     public void find_bibliographyBibtex0_succeeds() throws IOException, MalformedException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=bibtex";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_bibtex0.txt"),
                 StandardCharsets.UTF_8);
@@ -814,7 +778,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyBibtex1_succeeds() throws MalformedException, IOException, DataServiceException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=bibtex";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_bibtex1.txt"),
                 StandardCharsets.UTF_8);
@@ -837,7 +801,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_2_USERNAME)
     public void find_bibliographyBibtex2_succeeds() throws MalformedException, DataServiceException, IOException,
             DataServiceConnectionException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=bibtex";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_bibtex2.txt"),
                 StandardCharsets.UTF_8);
@@ -860,7 +824,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_bibliographyBibtex3_succeeds() throws MalformedException, DataServiceException,
             DataServiceConnectionException, IOException, QueryNotFoundException, IdentifierNotFoundException,
-            FormatNotAvailableException, NotAllowedException {
+            FormatNotAvailableException, NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final String accept = "text/bibliography; style=bibtex";
         final String compare = FileUtils.readFileToString(new File("src/test/resources/bibliography/style_bibtex3.txt"),
                 StandardCharsets.UTF_8);
@@ -882,7 +846,8 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @Test
     @WithAnonymousUser
     public void find_jsonLd_succeeds() throws MalformedException, DataServiceException, DataServiceConnectionException,
-            QueryNotFoundException, IdentifierNotFoundException, FormatNotAvailableException, NotAllowedException {
+            QueryNotFoundException, IdentifierNotFoundException, FormatNotAvailableException, NotAllowedException,
+            TableNotFoundException, ViewNotFoundException {
         final String accept = "application/ld+json";
 
         /* mock */
@@ -914,7 +879,8 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @Test
     @WithAnonymousUser
     public void find_move_succeeds() throws MalformedException, DataServiceException, DataServiceConnectionException,
-            QueryNotFoundException, IdentifierNotFoundException, FormatNotAvailableException, NotAllowedException {
+            QueryNotFoundException, IdentifierNotFoundException, FormatNotAvailableException, NotAllowedException,
+            TableNotFoundException, ViewNotFoundException {
 
         /* mock */
         when(identifierService.find(IDENTIFIER_1_ID))
@@ -1065,7 +1031,8 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @Test
     @WithAnonymousUser
     public void find_json_succeeds() throws MalformedException, DataServiceException, DataServiceConnectionException,
-            FormatNotAvailableException, QueryNotFoundException, IdentifierNotFoundException, NotAllowedException {
+            FormatNotAvailableException, QueryNotFoundException, IdentifierNotFoundException, NotAllowedException,
+            TableNotFoundException, ViewNotFoundException {
         final String accept = "application/json";
 
         /* mock */
@@ -1093,7 +1060,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void find_xml_succeeds() throws MalformedException, DataServiceException, DataServiceConnectionException,
             IOException, QueryNotFoundException, IdentifierNotFoundException, FormatNotAvailableException,
-            NotAllowedException {
+            NotAllowedException, TableNotFoundException, ViewNotFoundException {
         final InputStreamResource resource = new InputStreamResource(FileUtils.openInputStream(
                 new File("src/test/resources/xml/datacite-example-dataset-v4.xml")));
 
@@ -1108,9 +1075,9 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithAnonymousUser
-    public void find_httpRedirect_succeeds() throws MalformedException, DataServiceException,
-            DataServiceConnectionException, FormatNotAvailableException, QueryNotFoundException,
-            IdentifierNotFoundException, NotAllowedException {
+    public void find_httpRedirect_succeeds() throws MalformedException, DataServiceException, QueryNotFoundException,
+            DataServiceConnectionException, FormatNotAvailableException, IdentifierNotFoundException,
+            NotAllowedException, TableNotFoundException, ViewNotFoundException {
 
         /* test */
         final ResponseEntity<?> response = generic_find(null, null);
@@ -1509,14 +1476,13 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
 
     protected ResponseEntity<?> generic_find(String accept, InputStreamResource resource)
             throws MalformedException, DataServiceException, DataServiceConnectionException, FormatNotAvailableException,
-            QueryNotFoundException, IdentifierNotFoundException, NotAllowedException {
+            QueryNotFoundException, IdentifierNotFoundException, NotAllowedException, TableNotFoundException,
+            ViewNotFoundException {
 
         /* mock */
         when(identifierService.find(IDENTIFIER_1_ID))
                 .thenReturn(IDENTIFIER_1);
         if (resource != null) {
-            when(identifierService.exportResource(IDENTIFIER_1))
-                    .thenReturn(resource);
             when(identifierService.exportMetadata(IDENTIFIER_1))
                     .thenReturn(resource);
         }
@@ -1525,10 +1491,6 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest {
         return identifierEndpoint.find(IDENTIFIER_1_ID, accept, null);
     }
 
-    protected static String inputStreamToString(InputStream inputStream) throws IOException {
-        return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
-    }
-
     protected void generic_delete() throws NotAllowedException, DataServiceException, DataServiceConnectionException,
             DatabaseNotFoundException, IdentifierNotFoundException, SearchServiceException,
             SearchServiceConnectionException {
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/DataServiceGatewayUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/DataServiceGatewayUnitTest.java
index 5508a6245e40021cf307d474bc056dfc64861920..af1ecc9f1c69b6f2acaf3176575045bf14ad8322 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/DataServiceGatewayUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/DataServiceGatewayUnitTest.java
@@ -1,6 +1,5 @@
 package at.tuwien.gateway;
 
-import at.tuwien.ExportResourceDto;
 import at.tuwien.api.database.AccessTypeDto;
 import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.ViewDto;
@@ -812,75 +811,6 @@ public class DataServiceGatewayUnitTest extends AbstractUnitTest {
         });
     }
 
-    @Test
-    public void exportQuery_succeeds() throws DataServiceException, DataServiceConnectionException,
-            QueryNotFoundException {
-
-        /* mock */
-        when(dataServiceRestTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(ExportResourceDto.class)))
-                .thenReturn(ResponseEntity.status(HttpStatus.OK)
-                        .build());
-
-        /* test */
-        dataServiceGateway.exportQuery(DATABASE_1_ID, QUERY_1_ID);
-    }
-
-    @Test
-    public void exportQuery_connection_fails() {
-
-        /* mock */
-        doThrow(HttpServerErrorException.class)
-                .when(dataServiceRestTemplate)
-                .exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(ExportResourceDto.class));
-
-        /* test */
-        assertThrows(DataServiceConnectionException.class, () -> {
-            dataServiceGateway.exportQuery(DATABASE_1_ID, QUERY_1_ID);
-        });
-    }
-
-    @Test
-    public void exportQuery_unauthorized_fails() {
-
-        /* mock */
-        doThrow(HttpClientErrorException.Unauthorized.class)
-                .when(dataServiceRestTemplate)
-                .exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(ExportResourceDto.class));
-
-        /* test */
-        assertThrows(DataServiceException.class, () -> {
-            dataServiceGateway.exportQuery(DATABASE_1_ID, QUERY_1_ID);
-        });
-    }
-
-    @Test
-    public void exportQuery_notFound_fails() {
-
-        /* mock */
-        doThrow(HttpClientErrorException.NotFound.class)
-                .when(dataServiceRestTemplate)
-                .exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(ExportResourceDto.class));
-
-        /* test */
-        assertThrows(QueryNotFoundException.class, () -> {
-            dataServiceGateway.exportQuery(DATABASE_1_ID, QUERY_1_ID);
-        });
-    }
-
-    @Test
-    public void exportQuery_responseCode_fails() {
-
-        /* mock */
-        when(dataServiceRestTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(ExportResourceDto.class)))
-                .thenReturn(ResponseEntity.status(HttpStatus.NO_CONTENT)
-                        .build());
-
-        /* test */
-        assertThrows(DataServiceException.class, () -> {
-            dataServiceGateway.exportQuery(DATABASE_1_ID, QUERY_1_ID);
-        });
-    }
-
     @Test
     public void getTableSchemas_succeeds() throws DataServiceException, DataServiceConnectionException, TableNotFoundException {
 
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java
index d6b5da373cd08436c1ab1a42031952f05faf6d12..6d7480ba8034a9108492ab0816005f4a92f8046c 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java
@@ -29,7 +29,9 @@ public class InternalRequestInterceptor implements ClientHttpRequestInterceptor
     public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
             throws IOException {
         final HttpHeaders headers = request.getHeaders();
-        headers.setAccept(List.of(MediaType.APPLICATION_JSON));
+        if (headers.get("Accept") == null) {
+            headers.setAccept(List.of(MediaType.APPLICATION_JSON));
+        }
         final TokenDto token = credentialService.getAccessToken(gatewayConfig.getSystemUsername(),
                 gatewayConfig.getSystemPassword());
         headers.setBearerAuth(token.getAccessToken());
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/DataServiceGateway.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/DataServiceGateway.java
index 5bb0303e16c14145f1e08ee913b4c4dcabdead61..3996448d212bed80364bdc2ac4d5ab62da3e1863 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/DataServiceGateway.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/DataServiceGateway.java
@@ -1,9 +1,8 @@
 package at.tuwien.gateway;
 
-import at.tuwien.ExportResourceDto;
 import at.tuwien.api.database.AccessTypeDto;
-import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.CreateViewDto;
+import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.ViewDto;
 import at.tuwien.api.database.internal.CreateDatabaseDto;
 import at.tuwien.api.database.query.QueryDto;
@@ -145,19 +144,6 @@ public interface DataServiceGateway {
     QueryDto findQuery(UUID databaseId, UUID queryId) throws DataServiceConnectionException, DataServiceException,
             QueryNotFoundException;
 
-    /**
-     * Exports a given query.
-     *
-     * @param databaseId The database id.
-     * @param queryId    The query id.
-     * @return The exported resource, if successful.
-     * @throws DataServiceConnectionException The connection to the data service could not be established.
-     * @throws DataServiceException           The data service responded unexpectedly.
-     * @throws QueryNotFoundException         The given query was not found in the query store.
-     */
-    ExportResourceDto exportQuery(UUID databaseId, UUID queryId) throws DataServiceConnectionException,
-            DataServiceException, QueryNotFoundException;
-
     /**
      * Obtain table schemas from a given database.
      *
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java
index 8feed3b291444ea674317673d74fa59bba4b5cad..ba855feda32000f1c4f0265c2b194c7e9e4e8237 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java
@@ -1,6 +1,5 @@
 package at.tuwien.gateway.impl;
 
-import at.tuwien.ExportResourceDto;
 import at.tuwien.api.database.*;
 import at.tuwien.api.database.internal.CreateDatabaseDto;
 import at.tuwien.api.database.query.QueryDto;
@@ -315,31 +314,6 @@ public class DataServiceGatewayImpl implements DataServiceGateway {
         return response.getBody();
     }
 
-    @Override
-    public ExportResourceDto exportQuery(UUID databaseId, UUID queryId) throws DataServiceConnectionException,
-            DataServiceException, QueryNotFoundException {
-        final ResponseEntity<ExportResourceDto> response;
-        final String path = "/api/database/" + databaseId + "/subset/" + queryId;
-        log.trace("export subset at endpoint {} with path {}", gatewayConfig.getDataEndpoint(), path);
-        try {
-            response = restTemplate.exchange(path, HttpMethod.GET, HttpEntity.EMPTY, ExportResourceDto.class);
-        } catch (HttpServerErrorException e) {
-            log.error("Failed to export query: {}", e.getMessage());
-            throw new DataServiceConnectionException("Failed to export query: " + e.getMessage(), e);
-        } catch (HttpClientErrorException.NotFound e) {
-            log.error("Failed to export query: not found: {}", e.getMessage());
-            throw new QueryNotFoundException("Failed to export query: not found: " + e.getMessage(), e);
-        } catch (HttpClientErrorException.Unauthorized e) {
-            log.error("Failed to export query: {}", e.getMessage());
-            throw new DataServiceException("Failed to export query: " + e.getMessage(), e);
-        }
-        if (!response.getStatusCode().equals(HttpStatus.OK)) {
-            log.error("Failed to export query: wrong http code: {}", response.getStatusCode());
-            throw new DataServiceException("Failed to export query: wrong http code: " + response.getStatusCode());
-        }
-        return response.getBody();
-    }
-
     @Override
     public List<TableDto> getTableSchemas(UUID databaseId) throws DataServiceConnectionException, DataServiceException,
             TableNotFoundException {
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java
index 605ded7d37faad52fc7119f4dd0a958c199b68b8..8c9a3088fe96844df0628ba95d71c0356ebc2b33 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java
@@ -161,19 +161,6 @@ public interface IdentifierService {
      */
     String exportBibliography(Identifier identifier, BibliographyTypeDto style) throws MalformedException;
 
-    /**
-     * Exports an identifier to XML
-     *
-     * @param identifier The identifier.
-     * @return The XML resource, if successful.
-     * @throws DataServiceException
-     * @throws DataServiceConnectionException
-     * @throws IdentifierNotFoundException
-     * @throws QueryNotFoundException
-     */
-    InputStreamResource exportResource(Identifier identifier) throws DataServiceException, DataServiceConnectionException,
-            IdentifierNotFoundException, QueryNotFoundException;
-
     /**
      * Soft-deletes an identifier for a given id in the metadata database. Does not actually remove the entity from the
      * database, but sets it as deleted.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java
index 0c8ce27d1214b1ac47c6756d7f5d3fbe4c77adcd..5ab9cc26a226374d817966e880a684393c36cf08 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java
@@ -196,13 +196,6 @@ public class DataCiteIdentifierServiceImpl implements IdentifierService {
         return identifierService.exportBibliography(identifier, style);
     }
 
-    @Override
-    @Transactional(readOnly = true)
-    public InputStreamResource exportResource(Identifier identifier) throws DataServiceException,
-            DataServiceConnectionException, IdentifierNotFoundException, QueryNotFoundException {
-        return identifierService.exportResource(identifier);
-    }
-
     @Override
     @Transactional
     public void delete(Identifier identifier) throws DataServiceException, DataServiceConnectionException,
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
index b1d1f45932c61bb755a615f22a6a919297ffec46..8af7023c8cb48b64078457c409b8e14ece6187b7 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
@@ -1,6 +1,5 @@
 package at.tuwien.service.impl;
 
-import at.tuwien.ExportResourceDto;
 import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.identifier.BibliographyTypeDto;
 import at.tuwien.api.identifier.CreateIdentifierDto;
@@ -356,14 +355,6 @@ public class IdentifierServiceImpl implements IdentifierService {
         return body;
     }
 
-    @Override
-    @Transactional(readOnly = true)
-    public InputStreamResource exportResource(Identifier identifier) throws DataServiceException,
-            DataServiceConnectionException, QueryNotFoundException {
-        final ExportResourceDto exportResource = dataServiceGateway.exportQuery(identifier.getDatabase().getId(), identifier.getQueryId());
-        return exportResource.getResource();
-    }
-
     @Override
     @Transactional
     public void delete(Identifier identifier) throws DataServiceException, DataServiceConnectionException,
diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
index 1f4cc4e6691c5108f2fb61e806dc9e488b926f68..490c902295d9c50977caa0ab2b66a462ba6d514b 100644
--- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
+++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
@@ -6201,6 +6201,10 @@ public abstract class BaseTest {
     public static final IdentifierDto IDENTIFIER_1_DTO = IdentifierDto.builder()
             .id(IDENTIFIER_1_ID)
             .databaseId(DATABASE_1_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_1_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_1_ID)
+                    .build())
             .queryId(QUERY_1_ID)
             .descriptions(new LinkedList<>(List.of(IDENTIFIER_1_DESCRIPTION_1_DTO)))
             .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_DTO, IDENTIFIER_1_TITLE_2_DTO)))
@@ -6488,6 +6492,11 @@ public abstract class BaseTest {
             .id(IDENTIFIER_5_ID)
             .databaseId(DATABASE_2_ID)
             .queryId(QUERY_2_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_5_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_5_ID)
+                    .data("/api/database/" + DATABASE_2_ID + "/subset/" + QUERY_2_ID + "/data")
+                    .build())
             .descriptions(new LinkedList<>(List.of(IDENTIFIER_5_DESCRIPTION_1_DTO)))
             .titles(new LinkedList<>(List.of(IDENTIFIER_5_TITLE_1_DTO)))
             .doi(IDENTIFIER_5_DOI)
@@ -6769,6 +6778,11 @@ public abstract class BaseTest {
             .id(IDENTIFIER_6_ID)
             .databaseId(DATABASE_3_ID)
             .queryId(QUERY_3_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_6_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_6_ID)
+                    .data("/api/database/" + DATABASE_3_ID + "/subset/" + QUERY_3_ID + "/data")
+                    .build())
             .descriptions(new LinkedList<>(List.of(IDENTIFIER_6_DESCRIPTION_1_DTO)))
             .titles(new LinkedList<>(List.of(IDENTIFIER_6_TITLE_1_DTO)))
             .doi(IDENTIFIER_6_DOI)
@@ -6878,6 +6892,10 @@ public abstract class BaseTest {
     public static final IdentifierDto IDENTIFIER_7_DTO = IdentifierDto.builder()
             .id(IDENTIFIER_7_ID)
             .databaseId(DATABASE_4_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_7_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_7_ID)
+                    .build())
             .descriptions(new LinkedList<>())
             .titles(new LinkedList<>())
             .doi(IDENTIFIER_7_DOI)
@@ -6986,6 +7004,11 @@ public abstract class BaseTest {
             .id(IDENTIFIER_2_ID)
             .queryId(QUERY_1_ID)
             .databaseId(DATABASE_1_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_2_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_2_ID)
+                    .data("/api/database/" + DATABASE_1_ID + "/subset/" + QUERY_1_ID + "/data")
+                    .build())
             .descriptions(new LinkedList<>())
             .titles(new LinkedList<>())
             .doi(IDENTIFIER_2_DOI)
@@ -7085,6 +7108,11 @@ public abstract class BaseTest {
             .id(IDENTIFIER_3_ID)
             .databaseId(DATABASE_1_ID)
             .viewId(VIEW_1_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_3_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_3_ID)
+                    .data("/api/database/" + DATABASE_1_ID + "/view/" + VIEW_1_ID + "/data")
+                    .build())
             .descriptions(new LinkedList<>())
             .titles(new LinkedList<>())
             .doi(IDENTIFIER_3_DOI)
@@ -7185,6 +7213,11 @@ public abstract class BaseTest {
             .id(IDENTIFIER_4_ID)
             .databaseId(DATABASE_1_ID)
             .tableId(TABLE_1_ID)
+            .links(LinksDto.builder()
+                    .self("/api/identifier/" + IDENTIFIER_4_ID)
+                    .selfHtml("/pid/" + IDENTIFIER_4_ID)
+                    .data("/api/database/" + DATABASE_1_ID + "/table/" + TABLE_1_ID + "/data")
+                    .build())
             .descriptions(new LinkedList<>())
             .titles(new LinkedList<>())
             .doi(IDENTIFIER_4_DOI)
diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock
index ac2d0e3f70431e171ffda6524d193727056840b4..e520c5d0f8890461117ca6d7ab6645de932c2261 100644
--- a/dbrepo-search-service/Pipfile.lock
+++ b/dbrepo-search-service/Pipfile.lock
@@ -373,7 +373,7 @@
         },
         "dbrepo": {
             "hashes": [
-                "sha256:4f5ee48e9a68a44c2d1184923b90729d724553862742738d8f942273a586eb3d"
+                "sha256:e70ea4f7030191eb80116e5d0a4b17b041c94c80359d5d8e707d62218edd9a54"
             ],
             "path": "./lib/dbrepo-1.7.1.tar.gz"
         },
diff --git a/dbrepo-search-service/init/Pipfile.lock b/dbrepo-search-service/init/Pipfile.lock
index 39a52462e0daa22c8052517b0617cb350e9a9408..7e637809c29b2223d18dc64896ae84432efbf7c5 100644
--- a/dbrepo-search-service/init/Pipfile.lock
+++ b/dbrepo-search-service/init/Pipfile.lock
@@ -259,7 +259,7 @@
         },
         "dbrepo": {
             "hashes": [
-                "sha256:4f5ee48e9a68a44c2d1184923b90729d724553862742738d8f942273a586eb3d"
+                "sha256:e70ea4f7030191eb80116e5d0a4b17b041c94c80359d5d8e707d62218edd9a54"
             ],
             "path": "./lib/dbrepo-1.7.1.tar.gz"
         },
diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl b/dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl
index 8e77c6e1f6a01b3d9739280f29539985c359d2c8..61f52896c18ecbec8090177b38b8dbaeb0e1a95e 100644
Binary files a/dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl and b/dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl differ
diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz
index ede846d6168615c3e3bac49872362163b0a9f005..6708e1d892771d6cdf9293a6e9f5197f4dd9e304 100644
Binary files a/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz and b/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz differ
diff --git a/dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl b/dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl
index 8e77c6e1f6a01b3d9739280f29539985c359d2c8..61f52896c18ecbec8090177b38b8dbaeb0e1a95e 100644
Binary files a/dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl and b/dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl differ
diff --git a/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz b/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz
index ede846d6168615c3e3bac49872362163b0a9f005..6708e1d892771d6cdf9293a6e9f5197f4dd9e304 100644
Binary files a/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz and b/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz differ
diff --git a/dbrepo-ui/composables/query-service.ts b/dbrepo-ui/composables/query-service.ts
index 5a86c09d1b1b7017e362a62c0cc5df33c545fd6c..2b33fa8849c6d7bba4509720c2083f4d65562ff1 100644
--- a/dbrepo-ui/composables/query-service.ts
+++ b/dbrepo-ui/composables/query-service.ts
@@ -64,7 +64,7 @@ export const useQueryService = (): any => {
     }
     console.debug('export query with id', queryId, 'in database with id', databaseId)
     return new Promise<any>((resolve, reject) => {
-      axios.get<any>(`/api/database/${databaseId}/subset/${queryId}`, config)
+      axios.get<any>(`/api/database/${databaseId}/subset/${queryId}/data`, config)
         .then((response) => {
           console.info('Exported query with id', queryId, 'in database with id', databaseId)
           resolve(response.data)
diff --git a/dbrepo-ui/composables/table-service.ts b/dbrepo-ui/composables/table-service.ts
index 45ee0a7b934cb92c2d275b3cb1a23738d4fc0809..c9dfeb62fcd42c603ef86d67b52332fea04ac2a2 100644
--- a/dbrepo-ui/composables/table-service.ts
+++ b/dbrepo-ui/composables/table-service.ts
@@ -132,7 +132,7 @@ export const useTableService = (): any => {
     }
     console.debug('export data for table with id', tableId, 'in database with id', databaseId);
     return new Promise<QueryResultDto>((resolve, reject) => {
-      axios.get<QueryResultDto>(`/api/database/${databaseId}/table/${tableId}/export`, config)
+      axios.get<QueryResultDto>(`/api/database/${databaseId}/table/${tableId}/data`, config)
         .then((response) => {
           console.info('Exported data for table')
           resolve(response.data)
diff --git a/dbrepo-ui/composables/view-service.ts b/dbrepo-ui/composables/view-service.ts
index 9029a553ac782248d33707380f2ed72efcfc8032..3e775e2b14d51b83c7332bf7311de99a7a25d24e 100644
--- a/dbrepo-ui/composables/view-service.ts
+++ b/dbrepo-ui/composables/view-service.ts
@@ -114,7 +114,7 @@ export const useViewService = (): any => {
     }
     console.debug('export data for view with id', viewId, 'in database with id', databaseId);
     return new Promise<QueryResultDto>((resolve, reject) => {
-      axios.get<QueryResultDto>(`/api/database/${databaseId}/view/${viewId}/export`, config)
+      axios.get<QueryResultDto>(`/api/database/${databaseId}/view/${viewId}/data`, config)
         .then((response) => {
           console.info('Exported data for view with id', viewId, 'in database with id', databaseId)
           resolve(response.data)
diff --git a/docker-compose.yml b/docker-compose.yml
index e8c5cd8de7795d1bcced37da11b80b94dc404315..84905a7d057f6ea27dae62f7402eaa53f0d92cb7 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -539,6 +539,7 @@ services:
       AUTH_SERVICE_CLIENT: "${AUTH_SERVICE_CLIENT:-dbrepo-client}"
       AUTH_SERVICE_CLIENT_SECRET: "${AUTH_SERVICE_CLIENT:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG}"
       AUTH_SERVICE_ENDPOINT: "${AUTH_SERVICE_ENDPOINT:-http://auth-service:8080}"
+      BASE_URL: "${BASE_URL:-http://localhost}"
       BROKER_EXCHANGE_NAME: "${BROKER_EXCHANGE_NAME:-dbrepo}"
       BROKER_QUEUE_NAME: "${BROKER_QUEUE_NAME:-dbrepo}"
       BROKER_HOST: "${BROKER_ENDPOINT:-broker-service}"
diff --git a/helm/dbrepo/charts/seaweedfs-4.2.1.tgz b/helm/dbrepo/charts/seaweedfs-4.2.1.tgz
index f68e0bea5c235a15b317317f1e757fe29be1c73c..b26358e59779d3206d9c834f59b08e7f2f84149b 100644
Binary files a/helm/dbrepo/charts/seaweedfs-4.2.1.tgz and b/helm/dbrepo/charts/seaweedfs-4.2.1.tgz differ
diff --git a/helm/dbrepo/templates/gateway-configmap.yaml b/helm/dbrepo/templates/gateway-configmap.yaml
index 076e305014cef07a50a427679cd1f75b10b67f4e..0587cbac175d9c70e2ba43ff0a3095bd0dc5b519 100644
--- a/helm/dbrepo/templates/gateway-configmap.yaml
+++ b/helm/dbrepo/templates/gateway-configmap.yaml
@@ -20,7 +20,7 @@ data:
         listen 8080 default_server;
         server_name _;
 
-        location /dashboard/ {
+        location /dashboard {
             rewrite  ^/dashboard/(.*)  /$1 break;
             proxy_set_header        Host $host;
             proxy_set_header        X-Real-IP $remote_addr;
@@ -31,7 +31,7 @@ data:
         }
 
         # Proxy Grafana Live WebSocket connections.
-        location /dashboard/api/live/ {
+        location /dashboard/api/live {
             proxy_set_header        Host $host;
             proxy_set_header        X-Real-IP $remote_addr;
             proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -93,7 +93,7 @@ data:
             proxy_read_timeout      90;
         }
 
-        location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/table/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/(data|history|export)" {
+        location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/table/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/(data|history)" {
             proxy_set_header        Host $host;
             proxy_set_header        X-Real-IP $remote_addr;
             proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -102,7 +102,7 @@ data:
             proxy_read_timeout      90;
         }
 
-        location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/view/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/(data|export)" {
+        location ~ "/api/database/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/view/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/data" {
             proxy_set_header        Host $host;
             proxy_set_header        X-Real-IP $remote_addr;
             proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -138,6 +138,15 @@ data:
             proxy_read_timeout      90;
         }
 
+        location ~ "/api/identifier/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})" {
+            proxy_set_header        Host $host;
+            proxy_set_header        X-Real-IP $remote_addr;
+            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header        X-Forwarded-Proto $scheme;
+            proxy_pass              http://metadata-service;
+            proxy_read_timeout      90;
+        }
+
         location ~ "/pid/([0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})" {
             rewrite /pid/(.*) /api/identifier/$1 break;
             proxy_set_header        Host $host;
diff --git a/helm/seaweedfs/charts/mariadb-20.2.4.tgz b/helm/seaweedfs/charts/mariadb-20.2.4.tgz
deleted file mode 100644
index eb0f7bcfab6286495ed5338abdb8221b1f89805c..0000000000000000000000000000000000000000
Binary files a/helm/seaweedfs/charts/mariadb-20.2.4.tgz and /dev/null differ
diff --git a/helm/seaweedfs/charts/postgresql-16.4.9.tgz b/helm/seaweedfs/charts/postgresql-16.4.9.tgz
deleted file mode 100644
index 4bb0578224f0d8817e757a759547b171798bd407..0000000000000000000000000000000000000000
Binary files a/helm/seaweedfs/charts/postgresql-16.4.9.tgz and /dev/null differ
diff --git a/lib/python/README.md b/lib/python/README.md
index 11506a7bf059630b65ed703d4674cde8cf3642e9..1a15df15c79acd1dba9ea26ab14c09cbb2419927 100644
--- a/lib/python/README.md
+++ b/lib/python/README.md
@@ -44,6 +44,7 @@ client = RestClient(endpoint="https://test.dbrepo.tuwien.ac.at", username="foo",
                     password="bar")
 df = pd.DataFrame(data={'x_coord': 16.52617, 'component': 'Feinstaub (PM10)',
                         'unit': 'µg/m³', ...})
+df = df.set_index(['x_coord'])
 client.create_table(database_id="e0d82287-9099-4077-8f69-3c19fc3bc145",
                     name="Sensor", is_public=True, is_schema_public=True,
                     dataframe=df)
@@ -51,6 +52,14 @@ client.create_table(database_id="e0d82287-9099-4077-8f69-3c19fc3bc145",
 
 ... or just create the table schema by setting `create_table(..., withData=False)`.
 
+In both cases it is important to set the index to existing columns that uniquely
+identify a row. You can specify multiple columns:
+
+```python
+...
+df = df.set_index(['some_column', 'some_other_column'])
+```
+
 ## Supported Features & Best-Practices
 
 - Manage user
diff --git a/lib/python/coverage.xml b/lib/python/coverage.xml
index ac21b0bc1ed6b9f659ba578333c89e481c34ca8f..b23a031c5fe13102ab04331b3ef60329ee9353c0 100644
--- a/lib/python/coverage.xml
+++ b/lib/python/coverage.xml
@@ -1,41 +1,41 @@
 <?xml version="1.0" ?>
-<coverage version="7.6.10" timestamp="1740478405603" lines-valid="1820" lines-covered="1743" line-rate="0.9577" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
+<coverage version="7.6.10" timestamp="1741253336897" lines-valid="1941" lines-covered="1818" line-rate="0.9366" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
 	<!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.6.10 -->
 	<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
 	<sources>
 		<source>/home/mweise/Projects/fda-services/lib/python</source>
 	</sources>
 	<packages>
-		<package name="dbrepo" line-rate="0.9134" branch-rate="0" complexity="0">
+		<package name="dbrepo" line-rate="0.9102" branch-rate="0" complexity="0">
 			<classes>
-				<class name="RestClient.py" filename="dbrepo/RestClient.py" complexity="0" line-rate="0.9248" branch-rate="0">
+				<class name="RestClient.py" filename="dbrepo/RestClient.py" complexity="0" line-rate="0.9102" branch-rate="0">
 					<methods/>
 					<lines>
 						<line number="1" hits="1"/>
 						<line number="2" hits="1"/>
 						<line number="3" hits="1"/>
-						<line number="5" hits="1"/>
+						<line number="4" hits="1"/>
 						<line number="6" hits="1"/>
 						<line number="7" hits="1"/>
-						<line number="9" hits="1"/>
+						<line number="8" hits="1"/>
 						<line number="10" hits="1"/>
 						<line number="11" hits="1"/>
-						<line number="15" hits="1"/>
-						<line number="19" hits="1"/>
-						<line number="31" hits="1"/>
+						<line number="14" hits="1"/>
+						<line number="16" hits="1"/>
+						<line number="20" hits="1"/>
 						<line number="32" hits="1"/>
 						<line number="33" hits="1"/>
 						<line number="34" hits="1"/>
-						<line number="36" hits="1"/>
-						<line number="41" hits="1"/>
+						<line number="35" hits="1"/>
+						<line number="37" hits="1"/>
 						<line number="42" hits="1"/>
 						<line number="43" hits="1"/>
 						<line number="44" hits="1"/>
 						<line number="45" hits="1"/>
-						<line number="47" hits="1"/>
+						<line number="46" hits="1"/>
 						<line number="48" hits="1"/>
-						<line number="51" hits="1"/>
-						<line number="53" hits="1"/>
+						<line number="49" hits="1"/>
+						<line number="52" hits="1"/>
 						<line number="54" hits="1"/>
 						<line number="55" hits="1"/>
 						<line number="56" hits="1"/>
@@ -46,7 +46,7 @@
 						<line number="61" hits="1"/>
 						<line number="62" hits="1"/>
 						<line number="63" hits="1"/>
-						<line number="64" hits="1"/>
+						<line number="65" hits="1"/>
 						<line number="66" hits="1"/>
 						<line number="67" hits="1"/>
 						<line number="68" hits="1"/>
@@ -58,28 +58,28 @@
 						<line number="74" hits="1"/>
 						<line number="75" hits="1"/>
 						<line number="76" hits="1"/>
-						<line number="77" hits="1"/>
-						<line number="80" hits="1"/>
+						<line number="79" hits="1"/>
+						<line number="85" hits="1"/>
 						<line number="86" hits="1"/>
 						<line number="87" hits="1"/>
 						<line number="88" hits="1"/>
 						<line number="89" hits="1"/>
-						<line number="90" hits="1"/>
-						<line number="92" hits="1"/>
+						<line number="91" hits="1"/>
+						<line number="99" hits="1"/>
 						<line number="100" hits="1"/>
 						<line number="101" hits="1"/>
 						<line number="102" hits="1"/>
 						<line number="103" hits="1"/>
 						<line number="104" hits="1"/>
-						<line number="105" hits="1"/>
-						<line number="108" hits="1"/>
+						<line number="107" hits="1"/>
+						<line number="115" hits="1"/>
 						<line number="116" hits="1"/>
 						<line number="117" hits="1"/>
 						<line number="118" hits="1"/>
 						<line number="119" hits="1"/>
 						<line number="120" hits="1"/>
-						<line number="121" hits="1"/>
-						<line number="124" hits="1"/>
+						<line number="123" hits="1"/>
+						<line number="133" hits="1"/>
 						<line number="134" hits="1"/>
 						<line number="135" hits="1"/>
 						<line number="136" hits="1"/>
@@ -89,10 +89,10 @@
 						<line number="140" hits="1"/>
 						<line number="141" hits="1"/>
 						<line number="142" hits="1"/>
-						<line number="143" hits="1"/>
-						<line number="146" hits="1"/>
+						<line number="145" hits="1"/>
+						<line number="165" hits="1"/>
 						<line number="166" hits="1"/>
-						<line number="167" hits="1"/>
+						<line number="169" hits="1"/>
 						<line number="170" hits="1"/>
 						<line number="171" hits="1"/>
 						<line number="172" hits="1"/>
@@ -102,15 +102,15 @@
 						<line number="176" hits="1"/>
 						<line number="177" hits="1"/>
 						<line number="178" hits="1"/>
-						<line number="179" hits="1"/>
-						<line number="182" hits="1"/>
+						<line number="181" hits="1"/>
+						<line number="189" hits="1"/>
 						<line number="190" hits="1"/>
 						<line number="191" hits="1"/>
 						<line number="192" hits="1"/>
 						<line number="193" hits="1"/>
 						<line number="194" hits="1"/>
-						<line number="195" hits="1"/>
-						<line number="198" hits="1"/>
+						<line number="197" hits="1"/>
+						<line number="206" hits="1"/>
 						<line number="207" hits="1"/>
 						<line number="208" hits="1"/>
 						<line number="209" hits="1"/>
@@ -118,21 +118,21 @@
 						<line number="211" hits="1"/>
 						<line number="212" hits="1"/>
 						<line number="213" hits="1"/>
-						<line number="214" hits="1"/>
-						<line number="217" hits="1"/>
+						<line number="216" hits="1"/>
+						<line number="224" hits="1"/>
 						<line number="225" hits="1"/>
 						<line number="226" hits="1"/>
 						<line number="227" hits="1"/>
 						<line number="228" hits="1"/>
 						<line number="229" hits="1"/>
-						<line number="230" hits="1"/>
-						<line number="233" hits="1"/>
+						<line number="232" hits="1"/>
+						<line number="239" hits="1"/>
 						<line number="240" hits="1"/>
 						<line number="241" hits="1"/>
 						<line number="242" hits="1"/>
 						<line number="243" hits="1"/>
-						<line number="244" hits="1"/>
-						<line number="247" hits="1"/>
+						<line number="246" hits="1"/>
+						<line number="257" hits="1"/>
 						<line number="258" hits="1"/>
 						<line number="259" hits="1"/>
 						<line number="260" hits="1"/>
@@ -142,10 +142,10 @@
 						<line number="264" hits="1"/>
 						<line number="265" hits="1"/>
 						<line number="266" hits="1"/>
-						<line number="267" hits="1"/>
-						<line number="270" hits="1"/>
+						<line number="269" hits="1"/>
+						<line number="289" hits="1"/>
 						<line number="290" hits="1"/>
-						<line number="291" hits="1"/>
+						<line number="293" hits="1"/>
 						<line number="294" hits="1"/>
 						<line number="295" hits="1"/>
 						<line number="296" hits="1"/>
@@ -161,10 +161,10 @@
 						<line number="306" hits="1"/>
 						<line number="307" hits="1"/>
 						<line number="308" hits="1"/>
-						<line number="309" hits="1"/>
-						<line number="312" hits="1"/>
+						<line number="311" hits="1"/>
+						<line number="335" hits="1"/>
 						<line number="336" hits="1"/>
-						<line number="337" hits="1"/>
+						<line number="341" hits="1"/>
 						<line number="342" hits="1"/>
 						<line number="343" hits="1"/>
 						<line number="344" hits="1"/>
@@ -176,10 +176,10 @@
 						<line number="350" hits="1"/>
 						<line number="351" hits="1"/>
 						<line number="352" hits="1"/>
-						<line number="353" hits="1"/>
-						<line number="356" hits="1"/>
+						<line number="355" hits="1"/>
+						<line number="372" hits="1"/>
 						<line number="373" hits="1"/>
-						<line number="374" hits="1"/>
+						<line number="375" hits="1"/>
 						<line number="376" hits="1"/>
 						<line number="377" hits="1"/>
 						<line number="378" hits="1"/>
@@ -190,11 +190,11 @@
 						<line number="383" hits="1"/>
 						<line number="384" hits="1"/>
 						<line number="385" hits="1"/>
-						<line number="386" hits="1"/>
+						<line number="387" hits="1"/>
 						<line number="388" hits="1"/>
 						<line number="389" hits="1"/>
-						<line number="390" hits="1"/>
-						<line number="393" hits="1"/>
+						<line number="392" hits="1"/>
+						<line number="408" hits="1"/>
 						<line number="409" hits="1"/>
 						<line number="410" hits="1"/>
 						<line number="411" hits="1"/>
@@ -207,11 +207,11 @@
 						<line number="418" hits="1"/>
 						<line number="419" hits="1"/>
 						<line number="420" hits="1"/>
-						<line number="421" hits="1"/>
+						<line number="422" hits="1"/>
 						<line number="423" hits="1"/>
-						<line number="424" hits="1"/>
-						<line number="426" hits="1"/>
-						<line number="429" hits="1"/>
+						<line number="425" hits="1"/>
+						<line number="428" hits="1"/>
+						<line number="443" hits="1"/>
 						<line number="444" hits="1"/>
 						<line number="445" hits="1"/>
 						<line number="446" hits="1"/>
@@ -228,19 +228,18 @@
 						<line number="457" hits="1"/>
 						<line number="458" hits="1"/>
 						<line number="459" hits="1"/>
-						<line number="460" hits="1"/>
+						<line number="461" hits="1"/>
 						<line number="462" hits="1"/>
 						<line number="463" hits="1"/>
-						<line number="464" hits="1"/>
-						<line number="467" hits="1"/>
+						<line number="466" hits="1"/>
+						<line number="489" hits="1"/>
+						<line number="490" hits="1"/>
 						<line number="491" hits="1"/>
-						<line number="492" hits="1"/>
+						<line number="494" hits="1"/>
 						<line number="495" hits="1"/>
 						<line number="496" hits="1"/>
 						<line number="497" hits="1"/>
-						<line number="498" hits="1"/>
-						<line number="499" hits="1"/>
-						<line number="500" hits="1"/>
+						<line number="498" hits="0"/>
 						<line number="501" hits="1"/>
 						<line number="502" hits="1"/>
 						<line number="503" hits="1"/>
@@ -251,33 +250,33 @@
 						<line number="508" hits="1"/>
 						<line number="509" hits="1"/>
 						<line number="510" hits="1"/>
+						<line number="511" hits="1"/>
+						<line number="512" hits="1"/>
 						<line number="513" hits="1"/>
-						<line number="525" hits="1"/>
-						<line number="526" hits="1"/>
-						<line number="527" hits="1"/>
-						<line number="528" hits="1"/>
+						<line number="514" hits="1"/>
+						<line number="517" hits="1"/>
 						<line number="529" hits="1"/>
 						<line number="530" hits="1"/>
 						<line number="531" hits="1"/>
 						<line number="532" hits="1"/>
 						<line number="533" hits="1"/>
 						<line number="534" hits="1"/>
+						<line number="535" hits="1"/>
+						<line number="536" hits="1"/>
 						<line number="537" hits="1"/>
-						<line number="550" hits="1"/>
-						<line number="551" hits="1"/>
-						<line number="552" hits="1"/>
-						<line number="553" hits="1"/>
+						<line number="538" hits="1"/>
+						<line number="541" hits="1"/>
 						<line number="554" hits="1"/>
 						<line number="555" hits="1"/>
 						<line number="556" hits="1"/>
 						<line number="557" hits="1"/>
 						<line number="558" hits="1"/>
 						<line number="559" hits="1"/>
+						<line number="560" hits="1"/>
+						<line number="561" hits="1"/>
 						<line number="562" hits="1"/>
-						<line number="576" hits="1"/>
-						<line number="577" hits="1"/>
-						<line number="578" hits="1"/>
-						<line number="579" hits="1"/>
+						<line number="563" hits="1"/>
+						<line number="566" hits="1"/>
 						<line number="580" hits="1"/>
 						<line number="581" hits="1"/>
 						<line number="582" hits="1"/>
@@ -289,11 +288,11 @@
 						<line number="588" hits="1"/>
 						<line number="589" hits="1"/>
 						<line number="590" hits="1"/>
+						<line number="591" hits="1"/>
+						<line number="592" hits="1"/>
 						<line number="593" hits="1"/>
-						<line number="606" hits="1"/>
-						<line number="607" hits="1"/>
-						<line number="608" hits="1"/>
-						<line number="609" hits="1"/>
+						<line number="594" hits="1"/>
+						<line number="597" hits="1"/>
 						<line number="610" hits="1"/>
 						<line number="611" hits="1"/>
 						<line number="612" hits="1"/>
@@ -301,11 +300,11 @@
 						<line number="614" hits="1"/>
 						<line number="615" hits="1"/>
 						<line number="616" hits="1"/>
+						<line number="617" hits="1"/>
+						<line number="618" hits="1"/>
 						<line number="619" hits="1"/>
-						<line number="633" hits="1"/>
-						<line number="634" hits="1"/>
-						<line number="635" hits="1"/>
-						<line number="636" hits="1"/>
+						<line number="620" hits="1"/>
+						<line number="623" hits="1"/>
 						<line number="637" hits="1"/>
 						<line number="638" hits="1"/>
 						<line number="639" hits="1"/>
@@ -316,47 +315,46 @@
 						<line number="644" hits="1"/>
 						<line number="645" hits="1"/>
 						<line number="646" hits="1"/>
+						<line number="647" hits="1"/>
+						<line number="648" hits="1"/>
 						<line number="649" hits="1"/>
-						<line number="660" hits="1"/>
-						<line number="661" hits="1"/>
-						<line number="662" hits="1"/>
-						<line number="663" hits="1"/>
+						<line number="650" hits="1"/>
+						<line number="653" hits="1"/>
 						<line number="664" hits="1"/>
 						<line number="665" hits="1"/>
 						<line number="666" hits="1"/>
 						<line number="667" hits="1"/>
+						<line number="668" hits="1"/>
+						<line number="669" hits="1"/>
 						<line number="670" hits="1"/>
-						<line number="683" hits="1"/>
-						<line number="684" hits="1"/>
-						<line number="685" hits="1"/>
-						<line number="686" hits="1"/>
+						<line number="671" hits="1"/>
+						<line number="674" hits="1"/>
 						<line number="687" hits="1"/>
 						<line number="688" hits="1"/>
 						<line number="689" hits="1"/>
 						<line number="690" hits="1"/>
 						<line number="691" hits="1"/>
 						<line number="692" hits="1"/>
+						<line number="693" hits="1"/>
+						<line number="694" hits="1"/>
 						<line number="695" hits="1"/>
-						<line number="710" hits="1"/>
-						<line number="711" hits="1"/>
-						<line number="713" hits="1"/>
+						<line number="696" hits="1"/>
+						<line number="699" hits="1"/>
 						<line number="714" hits="1"/>
 						<line number="715" hits="1"/>
-						<line number="716" hits="1"/>
 						<line number="717" hits="1"/>
 						<line number="718" hits="1"/>
 						<line number="719" hits="1"/>
 						<line number="720" hits="1"/>
+						<line number="721" hits="1"/>
+						<line number="722" hits="1"/>
 						<line number="723" hits="1"/>
-						<line number="743" hits="1"/>
-						<line number="744" hits="1"/>
-						<line number="747" hits="1"/>
+						<line number="724" hits="1"/>
+						<line number="727" hits="1"/>
 						<line number="748" hits="1"/>
 						<line number="749" hits="1"/>
 						<line number="750" hits="1"/>
 						<line number="751" hits="1"/>
-						<line number="752" hits="1"/>
-						<line number="753" hits="1"/>
 						<line number="754" hits="1"/>
 						<line number="755" hits="1"/>
 						<line number="756" hits="1"/>
@@ -366,14 +364,14 @@
 						<line number="760" hits="1"/>
 						<line number="761" hits="1"/>
 						<line number="762" hits="1"/>
+						<line number="763" hits="1"/>
+						<line number="764" hits="1"/>
 						<line number="765" hits="1"/>
-						<line number="780" hits="1"/>
-						<line number="781" hits="1"/>
-						<line number="782" hits="1"/>
-						<line number="783" hits="1"/>
-						<line number="784" hits="1"/>
-						<line number="785" hits="1"/>
-						<line number="786" hits="1"/>
+						<line number="766" hits="1"/>
+						<line number="767" hits="1"/>
+						<line number="768" hits="1"/>
+						<line number="769" hits="1"/>
+						<line number="772" hits="1"/>
 						<line number="787" hits="1"/>
 						<line number="788" hits="1"/>
 						<line number="789" hits="1"/>
@@ -384,14 +382,14 @@
 						<line number="794" hits="1"/>
 						<line number="795" hits="1"/>
 						<line number="796" hits="1"/>
+						<line number="797" hits="1"/>
+						<line number="798" hits="1"/>
 						<line number="799" hits="1"/>
-						<line number="817" hits="1"/>
-						<line number="818" hits="1"/>
-						<line number="819" hits="1"/>
-						<line number="820" hits="1"/>
-						<line number="821" hits="1"/>
-						<line number="822" hits="1"/>
-						<line number="823" hits="1"/>
+						<line number="800" hits="1"/>
+						<line number="801" hits="1"/>
+						<line number="802" hits="1"/>
+						<line number="803" hits="1"/>
+						<line number="806" hits="1"/>
 						<line number="824" hits="1"/>
 						<line number="825" hits="1"/>
 						<line number="826" hits="1"/>
@@ -403,15 +401,15 @@
 						<line number="832" hits="1"/>
 						<line number="833" hits="1"/>
 						<line number="834" hits="1"/>
+						<line number="835" hits="1"/>
 						<line number="836" hits="1"/>
+						<line number="837" hits="1"/>
+						<line number="838" hits="1"/>
 						<line number="839" hits="1"/>
-						<line number="858" hits="1"/>
-						<line number="859" hits="1"/>
-						<line number="860" hits="1"/>
-						<line number="861" hits="1"/>
-						<line number="862" hits="1"/>
-						<line number="863" hits="1"/>
-						<line number="864" hits="1"/>
+						<line number="840" hits="1"/>
+						<line number="841" hits="1"/>
+						<line number="843" hits="1"/>
+						<line number="846" hits="1"/>
 						<line number="865" hits="1"/>
 						<line number="866" hits="1"/>
 						<line number="867" hits="1"/>
@@ -423,144 +421,145 @@
 						<line number="873" hits="1"/>
 						<line number="874" hits="1"/>
 						<line number="875" hits="1"/>
+						<line number="876" hits="1"/>
 						<line number="877" hits="1"/>
+						<line number="878" hits="1"/>
+						<line number="879" hits="1"/>
 						<line number="880" hits="1"/>
-						<line number="894" hits="1"/>
-						<line number="895" hits="1"/>
-						<line number="896" hits="1"/>
-						<line number="897" hits="1"/>
-						<line number="898" hits="1"/>
-						<line number="899" hits="1"/>
-						<line number="900" hits="1"/>
+						<line number="881" hits="1"/>
+						<line number="882" hits="1"/>
+						<line number="884" hits="1"/>
+						<line number="887" hits="1"/>
 						<line number="901" hits="1"/>
 						<line number="902" hits="1"/>
 						<line number="903" hits="1"/>
 						<line number="904" hits="1"/>
 						<line number="905" hits="1"/>
+						<line number="906" hits="1"/>
 						<line number="907" hits="1"/>
+						<line number="908" hits="1"/>
+						<line number="909" hits="1"/>
 						<line number="910" hits="1"/>
-						<line number="926" hits="0"/>
+						<line number="911" hits="1"/>
+						<line number="912" hits="1"/>
+						<line number="914" hits="1"/>
+						<line number="917" hits="1"/>
 						<line number="927" hits="0"/>
 						<line number="928" hits="0"/>
 						<line number="929" hits="0"/>
+						<line number="930" hits="0"/>
 						<line number="932" hits="0"/>
 						<line number="933" hits="0"/>
 						<line number="934" hits="0"/>
 						<line number="935" hits="0"/>
-						<line number="936" hits="0"/>
-						<line number="937" hits="0"/>
-						<line number="938" hits="0"/>
-						<line number="939" hits="0"/>
-						<line number="940" hits="0"/>
-						<line number="941" hits="0"/>
-						<line number="943" hits="0"/>
-						<line number="946" hits="1"/>
+						<line number="938" hits="1"/>
+						<line number="955" hits="0"/>
+						<line number="956" hits="0"/>
+						<line number="959" hits="0"/>
 						<line number="960" hits="0"/>
 						<line number="961" hits="0"/>
 						<line number="962" hits="0"/>
+						<line number="963" hits="0"/>
+						<line number="964" hits="0"/>
+						<line number="965" hits="0"/>
+						<line number="966" hits="0"/>
+						<line number="967" hits="0"/>
 						<line number="968" hits="0"/>
-						<line number="969" hits="0"/>
 						<line number="970" hits="0"/>
-						<line number="971" hits="0"/>
-						<line number="972" hits="0"/>
-						<line number="973" hits="0"/>
-						<line number="974" hits="0"/>
-						<line number="975" hits="0"/>
-						<line number="976" hits="0"/>
-						<line number="977" hits="0"/>
-						<line number="980" hits="1"/>
-						<line number="992" hits="0"/>
+						<line number="973" hits="1"/>
+						<line number="987" hits="0"/>
 						<line number="993" hits="0"/>
 						<line number="994" hits="0"/>
+						<line number="995" hits="0"/>
+						<line number="996" hits="0"/>
+						<line number="997" hits="0"/>
 						<line number="998" hits="0"/>
 						<line number="999" hits="0"/>
 						<line number="1000" hits="0"/>
 						<line number="1001" hits="0"/>
 						<line number="1002" hits="0"/>
-						<line number="1003" hits="0"/>
-						<line number="1004" hits="0"/>
-						<line number="1005" hits="0"/>
-						<line number="1006" hits="0"/>
-						<line number="1007" hits="0"/>
-						<line number="1010" hits="1"/>
-						<line number="1025" hits="1"/>
-						<line number="1026" hits="1"/>
-						<line number="1027" hits="1"/>
-						<line number="1028" hits="1"/>
-						<line number="1029" hits="1"/>
-						<line number="1030" hits="1"/>
-						<line number="1031" hits="1"/>
-						<line number="1032" hits="1"/>
+						<line number="1005" hits="1"/>
+						<line number="1017" hits="0"/>
+						<line number="1021" hits="0"/>
+						<line number="1022" hits="0"/>
+						<line number="1023" hits="0"/>
+						<line number="1024" hits="0"/>
+						<line number="1025" hits="0"/>
+						<line number="1026" hits="0"/>
+						<line number="1027" hits="0"/>
+						<line number="1028" hits="0"/>
+						<line number="1029" hits="0"/>
+						<line number="1030" hits="0"/>
 						<line number="1033" hits="1"/>
-						<line number="1034" hits="1"/>
-						<line number="1035" hits="1"/>
-						<line number="1037" hits="1"/>
-						<line number="1038" hits="1"/>
-						<line number="1039" hits="1"/>
-						<line number="1042" hits="1"/>
+						<line number="1048" hits="1"/>
+						<line number="1049" hits="1"/>
+						<line number="1050" hits="1"/>
+						<line number="1051" hits="1"/>
+						<line number="1052" hits="1"/>
+						<line number="1053" hits="1"/>
+						<line number="1054" hits="1"/>
+						<line number="1055" hits="1"/>
+						<line number="1056" hits="1"/>
 						<line number="1057" hits="1"/>
 						<line number="1058" hits="1"/>
-						<line number="1059" hits="1"/>
 						<line number="1060" hits="1"/>
 						<line number="1061" hits="1"/>
 						<line number="1062" hits="1"/>
-						<line number="1063" hits="1"/>
-						<line number="1064" hits="1"/>
 						<line number="1065" hits="1"/>
-						<line number="1066" hits="1"/>
-						<line number="1067" hits="1"/>
-						<line number="1068" hits="1"/>
-						<line number="1070" hits="1"/>
-						<line number="1073" hits="1"/>
+						<line number="1080" hits="1"/>
+						<line number="1081" hits="1"/>
+						<line number="1082" hits="1"/>
+						<line number="1083" hits="1"/>
+						<line number="1084" hits="1"/>
+						<line number="1085" hits="1"/>
+						<line number="1086" hits="1"/>
 						<line number="1087" hits="1"/>
 						<line number="1088" hits="1"/>
 						<line number="1089" hits="1"/>
 						<line number="1090" hits="1"/>
 						<line number="1091" hits="1"/>
-						<line number="1092" hits="1"/>
 						<line number="1093" hits="1"/>
-						<line number="1094" hits="1"/>
-						<line number="1095" hits="1"/>
 						<line number="1096" hits="1"/>
-						<line number="1097" hits="1"/>
-						<line number="1098" hits="1"/>
-						<line number="1100" hits="1"/>
-						<line number="1103" hits="1"/>
+						<line number="1110" hits="1"/>
+						<line number="1111" hits="1"/>
+						<line number="1112" hits="1"/>
+						<line number="1113" hits="1"/>
+						<line number="1114" hits="1"/>
+						<line number="1115" hits="1"/>
+						<line number="1116" hits="1"/>
+						<line number="1117" hits="1"/>
+						<line number="1118" hits="1"/>
+						<line number="1119" hits="1"/>
 						<line number="1120" hits="1"/>
 						<line number="1121" hits="1"/>
-						<line number="1122" hits="1"/>
 						<line number="1123" hits="1"/>
-						<line number="1124" hits="1"/>
-						<line number="1125" hits="1"/>
 						<line number="1126" hits="1"/>
-						<line number="1127" hits="1"/>
-						<line number="1128" hits="1"/>
-						<line number="1129" hits="1"/>
-						<line number="1130" hits="1"/>
-						<line number="1131" hits="1"/>
-						<line number="1132" hits="1"/>
-						<line number="1133" hits="1"/>
-						<line number="1134" hits="1"/>
-						<line number="1135" hits="1"/>
-						<line number="1136" hits="1"/>
-						<line number="1138" hits="1"/>
-						<line number="1141" hits="1"/>
+						<line number="1143" hits="1"/>
+						<line number="1144" hits="1"/>
+						<line number="1145" hits="1"/>
+						<line number="1146" hits="1"/>
+						<line number="1147" hits="1"/>
+						<line number="1148" hits="1"/>
+						<line number="1149" hits="1"/>
+						<line number="1150" hits="1"/>
+						<line number="1151" hits="1"/>
+						<line number="1152" hits="1"/>
+						<line number="1153" hits="1"/>
+						<line number="1154" hits="1"/>
+						<line number="1155" hits="1"/>
+						<line number="1156" hits="1"/>
 						<line number="1157" hits="1"/>
 						<line number="1158" hits="1"/>
 						<line number="1159" hits="1"/>
-						<line number="1160" hits="1"/>
 						<line number="1161" hits="1"/>
-						<line number="1162" hits="1"/>
-						<line number="1163" hits="1"/>
 						<line number="1164" hits="1"/>
-						<line number="1165" hits="1"/>
-						<line number="1166" hits="1"/>
-						<line number="1167" hits="1"/>
-						<line number="1168" hits="1"/>
-						<line number="1169" hits="1"/>
-						<line number="1170" hits="1"/>
-						<line number="1172" hits="1"/>
-						<line number="1175" hits="1"/>
+						<line number="1180" hits="1"/>
+						<line number="1181" hits="1"/>
+						<line number="1182" hits="1"/>
+						<line number="1183" hits="1"/>
+						<line number="1184" hits="1"/>
+						<line number="1185" hits="1"/>
+						<line number="1186" hits="1"/>
 						<line number="1187" hits="1"/>
 						<line number="1188" hits="1"/>
 						<line number="1189" hits="1"/>
@@ -568,102 +567,104 @@
 						<line number="1191" hits="1"/>
 						<line number="1192" hits="1"/>
 						<line number="1193" hits="1"/>
-						<line number="1194" hits="1"/>
 						<line number="1195" hits="1"/>
-						<line number="1196" hits="1"/>
-						<line number="1199" hits="1"/>
+						<line number="1198" hits="1"/>
+						<line number="1210" hits="1"/>
+						<line number="1211" hits="1"/>
+						<line number="1212" hits="1"/>
+						<line number="1213" hits="1"/>
+						<line number="1214" hits="1"/>
+						<line number="1215" hits="1"/>
 						<line number="1216" hits="1"/>
 						<line number="1217" hits="1"/>
 						<line number="1218" hits="1"/>
 						<line number="1219" hits="1"/>
-						<line number="1220" hits="1"/>
-						<line number="1221" hits="1"/>
 						<line number="1222" hits="1"/>
-						<line number="1223" hits="1"/>
-						<line number="1224" hits="1"/>
-						<line number="1225" hits="1"/>
-						<line number="1226" hits="1"/>
-						<line number="1227" hits="1"/>
-						<line number="1228" hits="1"/>
-						<line number="1230" hits="1"/>
-						<line number="1231" hits="1"/>
-						<line number="1232" hits="1"/>
-						<line number="1235" hits="1"/>
-						<line number="1252" hits="1"/>
+						<line number="1239" hits="1"/>
+						<line number="1240" hits="1"/>
+						<line number="1241" hits="1"/>
+						<line number="1242" hits="1"/>
+						<line number="1243" hits="1"/>
+						<line number="1244" hits="1"/>
+						<line number="1245" hits="1"/>
+						<line number="1246" hits="1"/>
+						<line number="1247" hits="1"/>
+						<line number="1248" hits="1"/>
+						<line number="1249" hits="1"/>
+						<line number="1250" hits="1"/>
+						<line number="1251" hits="1"/>
 						<line number="1253" hits="1"/>
 						<line number="1254" hits="1"/>
 						<line number="1255" hits="1"/>
-						<line number="1256" hits="1"/>
-						<line number="1257" hits="1"/>
 						<line number="1258" hits="1"/>
-						<line number="1259" hits="1"/>
-						<line number="1260" hits="1"/>
-						<line number="1261" hits="1"/>
-						<line number="1262" hits="1"/>
-						<line number="1263" hits="1"/>
-						<line number="1264" hits="1"/>
-						<line number="1266" hits="1"/>
-						<line number="1267" hits="1"/>
-						<line number="1268" hits="1"/>
-						<line number="1271" hits="1"/>
+						<line number="1275" hits="1"/>
+						<line number="1276" hits="1"/>
+						<line number="1277" hits="1"/>
+						<line number="1278" hits="1"/>
+						<line number="1279" hits="1"/>
+						<line number="1280" hits="1"/>
+						<line number="1281" hits="1"/>
+						<line number="1282" hits="1"/>
+						<line number="1283" hits="1"/>
+						<line number="1284" hits="1"/>
 						<line number="1285" hits="1"/>
 						<line number="1286" hits="1"/>
 						<line number="1287" hits="1"/>
-						<line number="1288" hits="1"/>
 						<line number="1289" hits="1"/>
 						<line number="1290" hits="1"/>
 						<line number="1291" hits="1"/>
-						<line number="1292" hits="1"/>
-						<line number="1293" hits="1"/>
 						<line number="1294" hits="1"/>
-						<line number="1295" hits="1"/>
-						<line number="1296" hits="1"/>
-						<line number="1298" hits="1"/>
-						<line number="1299" hits="1"/>
-						<line number="1300" hits="1"/>
-						<line number="1303" hits="1"/>
+						<line number="1308" hits="1"/>
+						<line number="1309" hits="1"/>
+						<line number="1310" hits="1"/>
+						<line number="1311" hits="1"/>
+						<line number="1312" hits="1"/>
+						<line number="1313" hits="1"/>
+						<line number="1314" hits="1"/>
+						<line number="1315" hits="1"/>
+						<line number="1316" hits="1"/>
+						<line number="1317" hits="1"/>
+						<line number="1318" hits="1"/>
+						<line number="1319" hits="1"/>
+						<line number="1321" hits="1"/>
+						<line number="1322" hits="1"/>
+						<line number="1323" hits="1"/>
 						<line number="1326" hits="1"/>
-						<line number="1327" hits="1"/>
-						<line number="1328" hits="1"/>
-						<line number="1329" hits="1"/>
-						<line number="1330" hits="1"/>
-						<line number="1331" hits="1"/>
-						<line number="1332" hits="1"/>
-						<line number="1333" hits="1"/>
-						<line number="1335" hits="1"/>
-						<line number="1336" hits="1"/>
-						<line number="1337" hits="1"/>
-						<line number="1338" hits="1"/>
-						<line number="1339" hits="1"/>
-						<line number="1340" hits="1"/>
-						<line number="1341" hits="1"/>
-						<line number="1342" hits="1"/>
-						<line number="1343" hits="1"/>
-						<line number="1344" hits="1"/>
-						<line number="1345" hits="1"/>
-						<line number="1346" hits="1"/>
-						<line number="1347" hits="1"/>
-						<line number="1348" hits="1"/>
 						<line number="1349" hits="1"/>
 						<line number="1350" hits="1"/>
+						<line number="1351" hits="1"/>
+						<line number="1352" hits="1"/>
 						<line number="1353" hits="1"/>
+						<line number="1354" hits="1"/>
+						<line number="1355" hits="1"/>
+						<line number="1356" hits="1"/>
+						<line number="1357" hits="1"/>
+						<line number="1358" hits="1"/>
+						<line number="1360" hits="1"/>
+						<line number="1361" hits="1"/>
+						<line number="1362" hits="1"/>
+						<line number="1363" hits="1"/>
+						<line number="1364" hits="1"/>
+						<line number="1365" hits="1"/>
+						<line number="1366" hits="1"/>
+						<line number="1367" hits="1"/>
+						<line number="1368" hits="1"/>
+						<line number="1369" hits="1"/>
+						<line number="1370" hits="1"/>
 						<line number="1371" hits="1"/>
 						<line number="1372" hits="1"/>
 						<line number="1373" hits="1"/>
 						<line number="1374" hits="1"/>
 						<line number="1375" hits="1"/>
-						<line number="1376" hits="1"/>
-						<line number="1377" hits="1"/>
 						<line number="1378" hits="1"/>
-						<line number="1379" hits="1"/>
-						<line number="1380" hits="1"/>
-						<line number="1381" hits="1"/>
-						<line number="1382" hits="1"/>
-						<line number="1383" hits="1"/>
-						<line number="1384" hits="1"/>
-						<line number="1385" hits="1"/>
-						<line number="1386" hits="1"/>
-						<line number="1389" hits="1"/>
+						<line number="1396" hits="1"/>
+						<line number="1397" hits="1"/>
+						<line number="1398" hits="1"/>
+						<line number="1399" hits="1"/>
+						<line number="1400" hits="1"/>
+						<line number="1401" hits="1"/>
+						<line number="1402" hits="1"/>
+						<line number="1403" hits="1"/>
 						<line number="1404" hits="1"/>
 						<line number="1405" hits="1"/>
 						<line number="1406" hits="1"/>
@@ -671,13 +672,13 @@
 						<line number="1408" hits="1"/>
 						<line number="1409" hits="1"/>
 						<line number="1410" hits="1"/>
-						<line number="1411" hits="1"/>
-						<line number="1412" hits="1"/>
 						<line number="1413" hits="1"/>
-						<line number="1414" hits="1"/>
-						<line number="1415" hits="1"/>
-						<line number="1416" hits="1"/>
-						<line number="1419" hits="1"/>
+						<line number="1428" hits="1"/>
+						<line number="1429" hits="1"/>
+						<line number="1430" hits="1"/>
+						<line number="1431" hits="1"/>
+						<line number="1432" hits="1"/>
+						<line number="1433" hits="1"/>
 						<line number="1434" hits="1"/>
 						<line number="1435" hits="1"/>
 						<line number="1436" hits="1"/>
@@ -685,14 +686,12 @@
 						<line number="1438" hits="1"/>
 						<line number="1439" hits="1"/>
 						<line number="1440" hits="1"/>
-						<line number="1441" hits="1"/>
-						<line number="1442" hits="1"/>
 						<line number="1443" hits="1"/>
-						<line number="1444" hits="1"/>
-						<line number="1445" hits="1"/>
-						<line number="1446" hits="1"/>
-						<line number="1447" hits="1"/>
-						<line number="1450" hits="1"/>
+						<line number="1458" hits="1"/>
+						<line number="1459" hits="1"/>
+						<line number="1460" hits="1"/>
+						<line number="1461" hits="1"/>
+						<line number="1462" hits="1"/>
 						<line number="1463" hits="1"/>
 						<line number="1464" hits="1"/>
 						<line number="1465" hits="1"/>
@@ -702,209 +701,207 @@
 						<line number="1469" hits="1"/>
 						<line number="1470" hits="1"/>
 						<line number="1471" hits="1"/>
-						<line number="1472" hits="1"/>
-						<line number="1473" hits="1"/>
 						<line number="1474" hits="1"/>
-						<line number="1477" hits="1"/>
+						<line number="1487" hits="1"/>
+						<line number="1488" hits="1"/>
+						<line number="1489" hits="1"/>
+						<line number="1490" hits="1"/>
+						<line number="1491" hits="1"/>
+						<line number="1492" hits="1"/>
+						<line number="1493" hits="1"/>
+						<line number="1494" hits="1"/>
 						<line number="1495" hits="1"/>
 						<line number="1496" hits="1"/>
 						<line number="1497" hits="1"/>
 						<line number="1498" hits="1"/>
-						<line number="1499" hits="1"/>
-						<line number="1500" hits="1"/>
 						<line number="1501" hits="1"/>
-						<line number="1502" hits="1"/>
-						<line number="1503" hits="1"/>
-						<line number="1504" hits="1"/>
-						<line number="1505" hits="1"/>
-						<line number="1506" hits="1"/>
-						<line number="1507" hits="1"/>
-						<line number="1508" hits="1"/>
-						<line number="1509" hits="1"/>
-						<line number="1510" hits="1"/>
-						<line number="1513" hits="1"/>
-						<line number="1549" hits="1"/>
-						<line number="1550" hits="1"/>
-						<line number="1555" hits="1"/>
-						<line number="1556" hits="1"/>
-						<line number="1557" hits="1"/>
-						<line number="1558" hits="1"/>
-						<line number="1559" hits="1"/>
-						<line number="1560" hits="1"/>
-						<line number="1561" hits="1"/>
-						<line number="1562" hits="1"/>
-						<line number="1563" hits="1"/>
-						<line number="1564" hits="1"/>
-						<line number="1565" hits="1"/>
-						<line number="1566" hits="1"/>
-						<line number="1568" hits="1"/>
-						<line number="1569" hits="1"/>
-						<line number="1570" hits="1"/>
+						<line number="1519" hits="1"/>
+						<line number="1520" hits="1"/>
+						<line number="1521" hits="1"/>
+						<line number="1522" hits="1"/>
+						<line number="1523" hits="1"/>
+						<line number="1524" hits="1"/>
+						<line number="1525" hits="1"/>
+						<line number="1526" hits="1"/>
+						<line number="1527" hits="1"/>
+						<line number="1528" hits="1"/>
+						<line number="1529" hits="1"/>
+						<line number="1530" hits="1"/>
+						<line number="1531" hits="1"/>
+						<line number="1532" hits="1"/>
+						<line number="1533" hits="1"/>
+						<line number="1534" hits="1"/>
+						<line number="1537" hits="1"/>
 						<line number="1573" hits="1"/>
-						<line number="1610" hits="1"/>
-						<line number="1611" hits="1"/>
-						<line number="1617" hits="1"/>
-						<line number="1618" hits="1"/>
-						<line number="1619" hits="1"/>
-						<line number="1620" hits="1"/>
-						<line number="1621" hits="1"/>
-						<line number="1622" hits="1"/>
-						<line number="1623" hits="1"/>
-						<line number="1624" hits="1"/>
-						<line number="1625" hits="1"/>
-						<line number="1626" hits="1"/>
-						<line number="1627" hits="1"/>
-						<line number="1628" hits="1"/>
-						<line number="1630" hits="1"/>
-						<line number="1631" hits="1"/>
-						<line number="1632" hits="1"/>
+						<line number="1574" hits="1"/>
+						<line number="1579" hits="1"/>
+						<line number="1580" hits="1"/>
+						<line number="1581" hits="1"/>
+						<line number="1582" hits="1"/>
+						<line number="1583" hits="1"/>
+						<line number="1584" hits="1"/>
+						<line number="1585" hits="1"/>
+						<line number="1586" hits="1"/>
+						<line number="1587" hits="1"/>
+						<line number="1588" hits="1"/>
+						<line number="1589" hits="1"/>
+						<line number="1590" hits="1"/>
+						<line number="1592" hits="1"/>
+						<line number="1593" hits="1"/>
+						<line number="1594" hits="1"/>
+						<line number="1597" hits="1"/>
+						<line number="1634" hits="1"/>
 						<line number="1635" hits="1"/>
+						<line number="1641" hits="1"/>
+						<line number="1642" hits="1"/>
+						<line number="1643" hits="1"/>
+						<line number="1644" hits="1"/>
+						<line number="1645" hits="1"/>
+						<line number="1646" hits="1"/>
+						<line number="1647" hits="1"/>
+						<line number="1648" hits="1"/>
+						<line number="1649" hits="1"/>
 						<line number="1650" hits="1"/>
 						<line number="1651" hits="1"/>
 						<line number="1652" hits="1"/>
-						<line number="1653" hits="1"/>
 						<line number="1654" hits="1"/>
 						<line number="1655" hits="1"/>
 						<line number="1656" hits="1"/>
-						<line number="1657" hits="1"/>
-						<line number="1658" hits="1"/>
 						<line number="1659" hits="1"/>
-						<line number="1660" hits="1"/>
-						<line number="1661" hits="1"/>
-						<line number="1662" hits="1"/>
-						<line number="1664" hits="1"/>
-						<line number="1665" hits="1"/>
-						<line number="1666" hits="1"/>
-						<line number="1669" hits="1"/>
+						<line number="1674" hits="1"/>
 						<line number="1675" hits="1"/>
 						<line number="1676" hits="1"/>
 						<line number="1677" hits="1"/>
 						<line number="1678" hits="1"/>
 						<line number="1679" hits="1"/>
 						<line number="1680" hits="1"/>
+						<line number="1681" hits="1"/>
+						<line number="1682" hits="1"/>
 						<line number="1683" hits="1"/>
-						<line number="1689" hits="0"/>
-						<line number="1690" hits="0"/>
-						<line number="1691" hits="0"/>
-						<line number="1692" hits="0"/>
-						<line number="1693" hits="0"/>
-						<line number="1694" hits="0"/>
-						<line number="1697" hits="1"/>
+						<line number="1684" hits="1"/>
+						<line number="1685" hits="1"/>
+						<line number="1686" hits="1"/>
+						<line number="1688" hits="1"/>
+						<line number="1689" hits="1"/>
+						<line number="1690" hits="1"/>
+						<line number="1693" hits="1"/>
+						<line number="1699" hits="1"/>
+						<line number="1700" hits="1"/>
+						<line number="1701" hits="1"/>
+						<line number="1702" hits="1"/>
 						<line number="1703" hits="1"/>
 						<line number="1704" hits="1"/>
-						<line number="1705" hits="1"/>
-						<line number="1706" hits="1"/>
 						<line number="1707" hits="1"/>
-						<line number="1708" hits="1"/>
-						<line number="1711" hits="1"/>
+						<line number="1713" hits="0"/>
+						<line number="1714" hits="0"/>
+						<line number="1715" hits="0"/>
+						<line number="1716" hits="0"/>
+						<line number="1717" hits="0"/>
+						<line number="1718" hits="0"/>
+						<line number="1721" hits="1"/>
+						<line number="1727" hits="1"/>
+						<line number="1728" hits="1"/>
+						<line number="1729" hits="1"/>
 						<line number="1730" hits="1"/>
 						<line number="1731" hits="1"/>
 						<line number="1732" hits="1"/>
-						<line number="1733" hits="1"/>
-						<line number="1734" hits="1"/>
 						<line number="1735" hits="1"/>
-						<line number="1736" hits="1"/>
-						<line number="1737" hits="1"/>
-						<line number="1738" hits="1"/>
-						<line number="1739" hits="1"/>
-						<line number="1740" hits="1"/>
-						<line number="1741" hits="1"/>
-						<line number="1742" hits="1"/>
-						<line number="1743" hits="1"/>
-						<line number="1744" hits="1"/>
-						<line number="1745" hits="1"/>
-						<line number="1746" hits="1"/>
-						<line number="1747" hits="1"/>
-						<line number="1748" hits="1"/>
-						<line number="1749" hits="1"/>
-						<line number="1750" hits="1"/>
-						<line number="1751" hits="1"/>
-						<line number="1752" hits="1"/>
-						<line number="1753" hits="1"/>
 						<line number="1754" hits="1"/>
 						<line number="1755" hits="1"/>
 						<line number="1756" hits="1"/>
 						<line number="1757" hits="1"/>
+						<line number="1758" hits="1"/>
 						<line number="1759" hits="1"/>
+						<line number="1760" hits="1"/>
+						<line number="1761" hits="1"/>
 						<line number="1762" hits="1"/>
-						<line number="1773" hits="0"/>
-						<line number="1774" hits="0"/>
-						<line number="1775" hits="0"/>
-						<line number="1776" hits="0"/>
-						<line number="1777" hits="0"/>
-						<line number="1778" hits="0"/>
-						<line number="1779" hits="0"/>
-						<line number="1780" hits="0"/>
+						<line number="1763" hits="1"/>
+						<line number="1764" hits="1"/>
+						<line number="1765" hits="1"/>
+						<line number="1766" hits="1"/>
+						<line number="1767" hits="1"/>
+						<line number="1768" hits="1"/>
+						<line number="1769" hits="1"/>
+						<line number="1770" hits="1"/>
+						<line number="1771" hits="1"/>
+						<line number="1772" hits="1"/>
+						<line number="1773" hits="1"/>
+						<line number="1774" hits="1"/>
+						<line number="1775" hits="1"/>
+						<line number="1776" hits="1"/>
+						<line number="1777" hits="1"/>
+						<line number="1778" hits="1"/>
+						<line number="1779" hits="1"/>
+						<line number="1780" hits="1"/>
+						<line number="1781" hits="1"/>
 						<line number="1783" hits="1"/>
-						<line number="1794" hits="0"/>
-						<line number="1795" hits="0"/>
-						<line number="1796" hits="0"/>
+						<line number="1786" hits="1"/>
 						<line number="1797" hits="0"/>
 						<line number="1798" hits="0"/>
 						<line number="1799" hits="0"/>
 						<line number="1800" hits="0"/>
 						<line number="1801" hits="0"/>
-						<line number="1804" hits="1"/>
-						<line number="1810" hits="1"/>
-						<line number="1811" hits="1"/>
-						<line number="1812" hits="1"/>
-						<line number="1813" hits="1"/>
-						<line number="1814" hits="1"/>
-						<line number="1815" hits="0"/>
-						<line number="1818" hits="1"/>
-						<line number="1824" hits="1"/>
-						<line number="1825" hits="1"/>
-						<line number="1826" hits="1"/>
-						<line number="1827" hits="1"/>
-						<line number="1828" hits="1"/>
+						<line number="1802" hits="0"/>
+						<line number="1803" hits="0"/>
+						<line number="1804" hits="0"/>
+						<line number="1807" hits="1"/>
+						<line number="1818" hits="0"/>
+						<line number="1819" hits="0"/>
+						<line number="1820" hits="0"/>
+						<line number="1821" hits="0"/>
+						<line number="1822" hits="0"/>
+						<line number="1823" hits="0"/>
+						<line number="1824" hits="0"/>
+						<line number="1826" hits="0"/>
+						<line number="1827" hits="0"/>
 						<line number="1829" hits="0"/>
-						<line number="1833" hits="1"/>
+						<line number="1830" hits="0"/>
+						<line number="1832" hits="0"/>
+						<line number="1833" hits="0"/>
+						<line number="1834" hits="0"/>
+						<line number="1835" hits="0"/>
+						<line number="1836" hits="0"/>
+						<line number="1837" hits="0"/>
+						<line number="1840" hits="1"/>
+						<line number="1851" hits="1"/>
+						<line number="1852" hits="1"/>
 						<line number="1853" hits="1"/>
 						<line number="1854" hits="1"/>
-						<line number="1856" hits="1"/>
-						<line number="1857" hits="1"/>
-						<line number="1858" hits="1"/>
-						<line number="1859" hits="1"/>
-						<line number="1860" hits="1"/>
+						<line number="1855" hits="1"/>
+						<line number="1856" hits="0"/>
+						<line number="1857" hits="0"/>
+						<line number="1858" hits="0"/>
 						<line number="1861" hits="1"/>
-						<line number="1862" hits="1"/>
-						<line number="1863" hits="1"/>
-						<line number="1864" hits="1"/>
-						<line number="1865" hits="1"/>
-						<line number="1866" hits="1"/>
 						<line number="1867" hits="1"/>
 						<line number="1868" hits="1"/>
 						<line number="1869" hits="1"/>
-					</lines>
-				</class>
-				<class name="UploadClient.py" filename="dbrepo/UploadClient.py" complexity="0" line-rate="0.52" branch-rate="0">
-					<methods/>
-					<lines>
-						<line number="1" hits="1"/>
-						<line number="2" hits="1"/>
-						<line number="3" hits="1"/>
-						<line number="4" hits="1"/>
-						<line number="5" hits="1"/>
-						<line number="7" hits="1"/>
-						<line number="8" hits="1"/>
-						<line number="10" hits="1"/>
-						<line number="12" hits="1"/>
-						<line number="16" hits="1"/>
-						<line number="24" hits="1"/>
-						<line number="26" hits="1"/>
-						<line number="27" hits="0"/>
-						<line number="29" hits="1"/>
-						<line number="30" hits="0"/>
-						<line number="31" hits="0"/>
-						<line number="32" hits="0"/>
-						<line number="33" hits="0"/>
-						<line number="34" hits="0"/>
-						<line number="35" hits="0"/>
-						<line number="36" hits="0"/>
-						<line number="37" hits="0"/>
-						<line number="38" hits="0"/>
-						<line number="39" hits="0"/>
-						<line number="40" hits="0"/>
+						<line number="1870" hits="1"/>
+						<line number="1871" hits="1"/>
+						<line number="1872" hits="0"/>
+						<line number="1875" hits="1"/>
+						<line number="1881" hits="1"/>
+						<line number="1882" hits="1"/>
+						<line number="1883" hits="1"/>
+						<line number="1884" hits="1"/>
+						<line number="1885" hits="1"/>
+						<line number="1886" hits="0"/>
+						<line number="1889" hits="1"/>
+						<line number="1909" hits="1"/>
+						<line number="1910" hits="1"/>
+						<line number="1912" hits="1"/>
+						<line number="1913" hits="1"/>
+						<line number="1914" hits="1"/>
+						<line number="1915" hits="1"/>
+						<line number="1916" hits="1"/>
+						<line number="1917" hits="1"/>
+						<line number="1918" hits="1"/>
+						<line number="1919" hits="1"/>
+						<line number="1920" hits="1"/>
+						<line number="1921" hits="1"/>
+						<line number="1922" hits="1"/>
+						<line number="1923" hits="1"/>
+						<line number="1924" hits="1"/>
+						<line number="1925" hits="1"/>
 					</lines>
 				</class>
 				<class name="__init__.py" filename="dbrepo/__init__.py" complexity="0" line-rate="1" branch-rate="0">
@@ -913,7 +910,7 @@
 				</class>
 			</classes>
 		</package>
-		<package name="dbrepo.api" line-rate="1" branch-rate="0" complexity="0">
+		<package name="dbrepo.api" line-rate="0.959" branch-rate="0" complexity="0">
 			<classes>
 				<class name="__init__.py" filename="dbrepo/api/__init__.py" complexity="0" line-rate="1" branch-rate="0">
 					<methods/>
@@ -941,81 +938,79 @@
 						<line number="26" hits="1"/>
 						<line number="27" hits="1"/>
 						<line number="28" hits="1"/>
-						<line number="29" hits="1"/>
-						<line number="30" hits="1"/>
 						<line number="31" hits="1"/>
 						<line number="32" hits="1"/>
 						<line number="33" hits="1"/>
-						<line number="36" hits="1"/>
-						<line number="37" hits="1"/>
+						<line number="34" hits="1"/>
+						<line number="35" hits="1"/>
 						<line number="38" hits="1"/>
 						<line number="39" hits="1"/>
 						<line number="40" hits="1"/>
-						<line number="43" hits="1"/>
-						<line number="44" hits="1"/>
+						<line number="41" hits="1"/>
+						<line number="42" hits="1"/>
 						<line number="45" hits="1"/>
 						<line number="46" hits="1"/>
 						<line number="47" hits="1"/>
 						<line number="50" hits="1"/>
 						<line number="51" hits="1"/>
 						<line number="52" hits="1"/>
+						<line number="53" hits="1"/>
+						<line number="54" hits="1"/>
 						<line number="55" hits="1"/>
 						<line number="56" hits="1"/>
 						<line number="57" hits="1"/>
 						<line number="58" hits="1"/>
-						<line number="59" hits="1"/>
-						<line number="60" hits="1"/>
 						<line number="61" hits="1"/>
 						<line number="62" hits="1"/>
 						<line number="63" hits="1"/>
-						<line number="66" hits="1"/>
+						<line number="64" hits="1"/>
 						<line number="67" hits="1"/>
 						<line number="68" hits="1"/>
 						<line number="69" hits="1"/>
+						<line number="70" hits="1"/>
+						<line number="71" hits="1"/>
 						<line number="72" hits="1"/>
 						<line number="73" hits="1"/>
-						<line number="74" hits="1"/>
-						<line number="75" hits="1"/>
 						<line number="76" hits="1"/>
 						<line number="77" hits="1"/>
 						<line number="78" hits="1"/>
+						<line number="79" hits="1"/>
+						<line number="80" hits="1"/>
 						<line number="81" hits="1"/>
 						<line number="82" hits="1"/>
 						<line number="83" hits="1"/>
-						<line number="84" hits="1"/>
-						<line number="85" hits="1"/>
 						<line number="86" hits="1"/>
 						<line number="87" hits="1"/>
 						<line number="88" hits="1"/>
+						<line number="89" hits="1"/>
+						<line number="90" hits="1"/>
 						<line number="91" hits="1"/>
 						<line number="92" hits="1"/>
-						<line number="93" hits="1"/>
-						<line number="94" hits="1"/>
 						<line number="95" hits="1"/>
 						<line number="96" hits="1"/>
 						<line number="97" hits="1"/>
 						<line number="98" hits="1"/>
 						<line number="99" hits="1"/>
-						<line number="102" hits="1"/>
-						<line number="103" hits="1"/>
+						<line number="100" hits="1"/>
+						<line number="101" hits="1"/>
 						<line number="104" hits="1"/>
 						<line number="105" hits="1"/>
 						<line number="106" hits="1"/>
 						<line number="107" hits="1"/>
 						<line number="108" hits="1"/>
+						<line number="109" hits="1"/>
+						<line number="110" hits="1"/>
 						<line number="111" hits="1"/>
-						<line number="112" hits="1"/>
-						<line number="113" hits="1"/>
 						<line number="114" hits="1"/>
 						<line number="115" hits="1"/>
 						<line number="116" hits="1"/>
 						<line number="117" hits="1"/>
 						<line number="118" hits="1"/>
+						<line number="119" hits="1"/>
+						<line number="120" hits="1"/>
 						<line number="121" hits="1"/>
 						<line number="122" hits="1"/>
 						<line number="123" hits="1"/>
-						<line number="124" hits="1"/>
-						<line number="125" hits="1"/>
 						<line number="126" hits="1"/>
 						<line number="127" hits="1"/>
 						<line number="128" hits="1"/>
@@ -1026,26 +1021,28 @@
 						<line number="135" hits="1"/>
 						<line number="136" hits="1"/>
 						<line number="137" hits="1"/>
+						<line number="138" hits="1"/>
+						<line number="139" hits="1"/>
 						<line number="140" hits="1"/>
-						<line number="141" hits="1"/>
-						<line number="142" hits="1"/>
 						<line number="143" hits="1"/>
 						<line number="144" hits="1"/>
-						<line number="145" hits="1"/>
-						<line number="146" hits="1"/>
 						<line number="147" hits="1"/>
-						<line number="150" hits="1"/>
+						<line number="148" hits="1"/>
 						<line number="151" hits="1"/>
-						<line number="154" hits="1"/>
 						<line number="155" hits="1"/>
+						<line number="156" hits="1"/>
 						<line number="158" hits="1"/>
+						<line number="159" hits="1"/>
+						<line number="161" hits="1"/>
 						<line number="162" hits="1"/>
-						<line number="163" hits="1"/>
 						<line number="165" hits="1"/>
-						<line number="166" hits="1"/>
-						<line number="168" hits="1"/>
 						<line number="169" hits="1"/>
+						<line number="170" hits="1"/>
+						<line number="171" hits="1"/>
 						<line number="172" hits="1"/>
+						<line number="173" hits="1"/>
+						<line number="174" hits="1"/>
+						<line number="175" hits="1"/>
 						<line number="176" hits="1"/>
 						<line number="177" hits="1"/>
 						<line number="178" hits="1"/>
@@ -1069,14 +1066,14 @@
 						<line number="196" hits="1"/>
 						<line number="197" hits="1"/>
 						<line number="198" hits="1"/>
-						<line number="199" hits="1"/>
-						<line number="200" hits="1"/>
 						<line number="201" hits="1"/>
-						<line number="202" hits="1"/>
-						<line number="203" hits="1"/>
-						<line number="204" hits="1"/>
 						<line number="205" hits="1"/>
+						<line number="206" hits="1"/>
+						<line number="207" hits="1"/>
 						<line number="208" hits="1"/>
+						<line number="209" hits="1"/>
+						<line number="210" hits="1"/>
+						<line number="211" hits="1"/>
 						<line number="212" hits="1"/>
 						<line number="213" hits="1"/>
 						<line number="214" hits="1"/>
@@ -1254,171 +1251,171 @@
 						<line number="386" hits="1"/>
 						<line number="387" hits="1"/>
 						<line number="388" hits="1"/>
-						<line number="389" hits="1"/>
-						<line number="390" hits="1"/>
 						<line number="391" hits="1"/>
 						<line number="392" hits="1"/>
 						<line number="393" hits="1"/>
-						<line number="394" hits="1"/>
-						<line number="395" hits="1"/>
-						<line number="398" hits="1"/>
-						<line number="399" hits="1"/>
+						<line number="396" hits="1"/>
+						<line number="397" hits="1"/>
 						<line number="400" hits="1"/>
-						<line number="403" hits="1"/>
+						<line number="401" hits="1"/>
 						<line number="404" hits="1"/>
-						<line number="407" hits="1"/>
 						<line number="408" hits="1"/>
+						<line number="409" hits="1"/>
+						<line number="410" hits="1"/>
 						<line number="411" hits="1"/>
+						<line number="414" hits="1"/>
 						<line number="415" hits="1"/>
 						<line number="416" hits="1"/>
 						<line number="417" hits="1"/>
-						<line number="418" hits="1"/>
+						<line number="420" hits="1"/>
 						<line number="421" hits="1"/>
-						<line number="422" hits="1"/>
-						<line number="423" hits="1"/>
 						<line number="424" hits="1"/>
+						<line number="425" hits="1"/>
+						<line number="426" hits="1"/>
 						<line number="427" hits="1"/>
 						<line number="428" hits="1"/>
 						<line number="431" hits="1"/>
 						<line number="432" hits="1"/>
 						<line number="433" hits="1"/>
 						<line number="434" hits="1"/>
-						<line number="435" hits="1"/>
+						<line number="437" hits="1"/>
 						<line number="438" hits="1"/>
-						<line number="439" hits="1"/>
-						<line number="440" hits="1"/>
 						<line number="441" hits="1"/>
+						<line number="442" hits="1"/>
+						<line number="443" hits="1"/>
 						<line number="444" hits="1"/>
 						<line number="445" hits="1"/>
+						<line number="446" hits="1"/>
+						<line number="447" hits="1"/>
 						<line number="448" hits="1"/>
-						<line number="449" hits="1"/>
-						<line number="450" hits="1"/>
 						<line number="451" hits="1"/>
 						<line number="452" hits="1"/>
 						<line number="453" hits="1"/>
 						<line number="454" hits="1"/>
 						<line number="455" hits="1"/>
-						<line number="458" hits="1"/>
-						<line number="459" hits="1"/>
+						<line number="456" hits="1"/>
+						<line number="457" hits="1"/>
 						<line number="460" hits="1"/>
 						<line number="461" hits="1"/>
-						<line number="462" hits="1"/>
-						<line number="463" hits="1"/>
 						<line number="464" hits="1"/>
+						<line number="465" hits="1"/>
+						<line number="466" hits="1"/>
 						<line number="467" hits="1"/>
-						<line number="468" hits="1"/>
+						<line number="470" hits="1"/>
 						<line number="471" hits="1"/>
 						<line number="472" hits="1"/>
 						<line number="473" hits="1"/>
 						<line number="474" hits="1"/>
-						<line number="477" hits="1"/>
-						<line number="478" hits="1"/>
+						<line number="475" hits="1"/>
+						<line number="476" hits="1"/>
 						<line number="479" hits="1"/>
 						<line number="480" hits="1"/>
-						<line number="481" hits="1"/>
-						<line number="482" hits="1"/>
 						<line number="483" hits="1"/>
-						<line number="486" hits="1"/>
-						<line number="487" hits="1"/>
-						<line number="490" hits="1"/>
-						<line number="491" hits="1"/>
+						<line number="484" hits="1"/>
+						<line number="485" hits="1"/>
+						<line number="488" hits="1"/>
+						<line number="489" hits="1"/>
 						<line number="492" hits="1"/>
+						<line number="493" hits="1"/>
+						<line number="494" hits="1"/>
 						<line number="495" hits="1"/>
 						<line number="496" hits="1"/>
-						<line number="499" hits="1"/>
+						<line number="497" hits="1"/>
 						<line number="500" hits="1"/>
 						<line number="501" hits="1"/>
 						<line number="502" hits="1"/>
-						<line number="503" hits="1"/>
-						<line number="504" hits="1"/>
+						<line number="505" hits="1"/>
+						<line number="506" hits="1"/>
 						<line number="507" hits="1"/>
-						<line number="508" hits="1"/>
-						<line number="509" hits="1"/>
-						<line number="512" hits="1"/>
-						<line number="513" hits="1"/>
+						<line number="510" hits="1"/>
+						<line number="511" hits="1"/>
 						<line number="514" hits="1"/>
+						<line number="515" hits="1"/>
+						<line number="516" hits="1"/>
 						<line number="517" hits="1"/>
 						<line number="518" hits="1"/>
-						<line number="521" hits="1"/>
-						<line number="522" hits="1"/>
+						<line number="519" hits="1"/>
+						<line number="520" hits="1"/>
 						<line number="523" hits="1"/>
 						<line number="524" hits="1"/>
 						<line number="525" hits="1"/>
 						<line number="526" hits="1"/>
 						<line number="527" hits="1"/>
+						<line number="528" hits="1"/>
+						<line number="529" hits="1"/>
 						<line number="530" hits="1"/>
 						<line number="531" hits="1"/>
 						<line number="532" hits="1"/>
 						<line number="533" hits="1"/>
 						<line number="534" hits="1"/>
-						<line number="535" hits="1"/>
-						<line number="536" hits="1"/>
 						<line number="537" hits="1"/>
 						<line number="538" hits="1"/>
 						<line number="539" hits="1"/>
 						<line number="540" hits="1"/>
 						<line number="541" hits="1"/>
 						<line number="544" hits="1"/>
-						<line number="545" hits="1"/>
-						<line number="546" hits="1"/>
-						<line number="547" hits="1"/>
 						<line number="548" hits="1"/>
+						<line number="549" hits="1"/>
+						<line number="550" hits="1"/>
 						<line number="551" hits="1"/>
-						<line number="555" hits="1"/>
-						<line number="556" hits="1"/>
-						<line number="557" hits="1"/>
+						<line number="554" hits="1"/>
 						<line number="558" hits="1"/>
-						<line number="561" hits="1"/>
+						<line number="559" hits="1"/>
+						<line number="560" hits="1"/>
+						<line number="563" hits="1"/>
+						<line number="564" hits="1"/>
 						<line number="565" hits="1"/>
 						<line number="566" hits="1"/>
 						<line number="567" hits="1"/>
+						<line number="568" hits="1"/>
+						<line number="569" hits="1"/>
 						<line number="570" hits="1"/>
 						<line number="571" hits="1"/>
 						<line number="572" hits="1"/>
 						<line number="573" hits="1"/>
 						<line number="574" hits="1"/>
 						<line number="575" hits="1"/>
-						<line number="576" hits="1"/>
-						<line number="577" hits="1"/>
 						<line number="578" hits="1"/>
 						<line number="579" hits="1"/>
 						<line number="580" hits="1"/>
 						<line number="581" hits="1"/>
 						<line number="582" hits="1"/>
+						<line number="583" hits="1"/>
+						<line number="584" hits="1"/>
 						<line number="585" hits="1"/>
 						<line number="586" hits="1"/>
-						<line number="587" hits="1"/>
-						<line number="588" hits="1"/>
 						<line number="589" hits="1"/>
 						<line number="590" hits="1"/>
 						<line number="591" hits="1"/>
 						<line number="592" hits="1"/>
 						<line number="593" hits="1"/>
+						<line number="594" hits="1"/>
+						<line number="595" hits="1"/>
 						<line number="596" hits="1"/>
 						<line number="597" hits="1"/>
 						<line number="598" hits="1"/>
 						<line number="599" hits="1"/>
 						<line number="600" hits="1"/>
-						<line number="601" hits="1"/>
-						<line number="602" hits="1"/>
 						<line number="603" hits="1"/>
 						<line number="604" hits="1"/>
-						<line number="605" hits="1"/>
-						<line number="606" hits="1"/>
 						<line number="607" hits="1"/>
+						<line number="608" hits="1"/>
+						<line number="609" hits="1"/>
 						<line number="610" hits="1"/>
 						<line number="611" hits="1"/>
 						<line number="614" hits="1"/>
 						<line number="615" hits="1"/>
 						<line number="616" hits="1"/>
 						<line number="617" hits="1"/>
-						<line number="618" hits="1"/>
+						<line number="620" hits="1"/>
 						<line number="621" hits="1"/>
-						<line number="622" hits="1"/>
-						<line number="623" hits="1"/>
 						<line number="624" hits="1"/>
+						<line number="625" hits="1"/>
+						<line number="626" hits="1"/>
 						<line number="627" hits="1"/>
 						<line number="628" hits="1"/>
+						<line number="629" hits="1"/>
+						<line number="630" hits="1"/>
 						<line number="631" hits="1"/>
 						<line number="632" hits="1"/>
 						<line number="633" hits="1"/>
@@ -1435,15 +1432,15 @@
 						<line number="644" hits="1"/>
 						<line number="645" hits="1"/>
 						<line number="646" hits="1"/>
-						<line number="647" hits="1"/>
-						<line number="648" hits="1"/>
 						<line number="649" hits="1"/>
 						<line number="650" hits="1"/>
-						<line number="651" hits="1"/>
-						<line number="652" hits="1"/>
 						<line number="653" hits="1"/>
+						<line number="654" hits="1"/>
+						<line number="655" hits="1"/>
 						<line number="656" hits="1"/>
 						<line number="657" hits="1"/>
+						<line number="658" hits="1"/>
+						<line number="659" hits="1"/>
 						<line number="660" hits="1"/>
 						<line number="661" hits="1"/>
 						<line number="662" hits="1"/>
@@ -1464,19 +1461,19 @@
 						<line number="677" hits="1"/>
 						<line number="678" hits="1"/>
 						<line number="679" hits="1"/>
-						<line number="680" hits="1"/>
-						<line number="681" hits="1"/>
 						<line number="682" hits="1"/>
 						<line number="683" hits="1"/>
 						<line number="684" hits="1"/>
 						<line number="685" hits="1"/>
+						<line number="686" hits="1"/>
+						<line number="687" hits="1"/>
 						<line number="688" hits="1"/>
-						<line number="689" hits="1"/>
-						<line number="690" hits="1"/>
 						<line number="691" hits="1"/>
 						<line number="692" hits="1"/>
 						<line number="693" hits="1"/>
 						<line number="694" hits="1"/>
+						<line number="695" hits="1"/>
+						<line number="696" hits="1"/>
 						<line number="697" hits="1"/>
 						<line number="698" hits="1"/>
 						<line number="699" hits="1"/>
@@ -1484,12 +1481,12 @@
 						<line number="701" hits="1"/>
 						<line number="702" hits="1"/>
 						<line number="703" hits="1"/>
-						<line number="704" hits="1"/>
-						<line number="705" hits="1"/>
 						<line number="706" hits="1"/>
 						<line number="707" hits="1"/>
 						<line number="708" hits="1"/>
 						<line number="709" hits="1"/>
+						<line number="710" hits="1"/>
+						<line number="711" hits="1"/>
 						<line number="712" hits="1"/>
 						<line number="713" hits="1"/>
 						<line number="714" hits="1"/>
@@ -1497,13 +1494,11 @@
 						<line number="716" hits="1"/>
 						<line number="717" hits="1"/>
 						<line number="718" hits="1"/>
-						<line number="719" hits="1"/>
-						<line number="720" hits="1"/>
 						<line number="721" hits="1"/>
 						<line number="722" hits="1"/>
 						<line number="723" hits="1"/>
 						<line number="724" hits="1"/>
-						<line number="727" hits="1"/>
+						<line number="725" hits="1"/>
 						<line number="728" hits="1"/>
 						<line number="729" hits="1"/>
 						<line number="730" hits="1"/>
@@ -1512,96 +1507,83 @@
 						<line number="735" hits="1"/>
 						<line number="736" hits="1"/>
 						<line number="737" hits="1"/>
+						<line number="738" hits="1"/>
+						<line number="739" hits="1"/>
 						<line number="740" hits="1"/>
 						<line number="741" hits="1"/>
 						<line number="742" hits="1"/>
 						<line number="743" hits="1"/>
 						<line number="744" hits="1"/>
-						<line number="745" hits="1"/>
-						<line number="746" hits="1"/>
 						<line number="747" hits="1"/>
 						<line number="748" hits="1"/>
 						<line number="749" hits="1"/>
 						<line number="750" hits="1"/>
-						<line number="753" hits="1"/>
+						<line number="751" hits="1"/>
 						<line number="754" hits="1"/>
 						<line number="755" hits="1"/>
 						<line number="756" hits="1"/>
 						<line number="757" hits="1"/>
 						<line number="760" hits="1"/>
 						<line number="761" hits="1"/>
-						<line number="762" hits="1"/>
-						<line number="763" hits="1"/>
+						<line number="764" hits="1"/>
+						<line number="765" hits="1"/>
 						<line number="766" hits="1"/>
 						<line number="767" hits="1"/>
-						<line number="770" hits="1"/>
-						<line number="771" hits="1"/>
+						<line number="768" hits="1"/>
+						<line number="769" hits="1"/>
 						<line number="772" hits="1"/>
 						<line number="773" hits="1"/>
 						<line number="774" hits="1"/>
 						<line number="775" hits="1"/>
 						<line number="778" hits="1"/>
 						<line number="779" hits="1"/>
-						<line number="780" hits="1"/>
-						<line number="781" hits="1"/>
+						<line number="782" hits="1"/>
+						<line number="783" hits="1"/>
 						<line number="784" hits="1"/>
 						<line number="785" hits="1"/>
-						<line number="788" hits="1"/>
+						<line number="786" hits="1"/>
 						<line number="789" hits="1"/>
-						<line number="790" hits="1"/>
-						<line number="791" hits="1"/>
-						<line number="792" hits="1"/>
+						<line number="793" hits="1"/>
+						<line number="794" hits="1"/>
 						<line number="795" hits="1"/>
-						<line number="796" hits="1"/>
-						<line number="799" hits="1"/>
+						<line number="798" hits="1"/>
+						<line number="802" hits="1"/>
 						<line number="803" hits="1"/>
-						<line number="804" hits="1"/>
-						<line number="805" hits="1"/>
 						<line number="806" hits="1"/>
+						<line number="807" hits="1"/>
+						<line number="808" hits="1"/>
 						<line number="809" hits="1"/>
+						<line number="810" hits="1"/>
 						<line number="813" hits="1"/>
 						<line number="814" hits="1"/>
+						<line number="815" hits="1"/>
+						<line number="816" hits="1"/>
 						<line number="817" hits="1"/>
+						<line number="820" hits="1"/>
 						<line number="821" hits="1"/>
 						<line number="822" hits="1"/>
-						<line number="823" hits="1"/>
-						<line number="824" hits="1"/>
 						<line number="825" hits="1"/>
 						<line number="826" hits="1"/>
 						<line number="827" hits="1"/>
-						<line number="828" hits="1"/>
-						<line number="829" hits="1"/>
 						<line number="830" hits="1"/>
 						<line number="831" hits="1"/>
 						<line number="832" hits="1"/>
 						<line number="833" hits="1"/>
 						<line number="834" hits="1"/>
-						<line number="835" hits="1"/>
-						<line number="836" hits="1"/>
 						<line number="837" hits="1"/>
 						<line number="838" hits="1"/>
+						<line number="839" hits="1"/>
+						<line number="840" hits="1"/>
 						<line number="841" hits="1"/>
-						<line number="845" hits="1"/>
-						<line number="846" hits="1"/>
-						<line number="847" hits="1"/>
+						<line number="844" hits="1"/>
 						<line number="848" hits="1"/>
 						<line number="849" hits="1"/>
 						<line number="850" hits="1"/>
 						<line number="851" hits="1"/>
-						<line number="852" hits="1"/>
-						<line number="853" hits="1"/>
 						<line number="854" hits="1"/>
-						<line number="855" hits="1"/>
-						<line number="856" hits="1"/>
-						<line number="857" hits="1"/>
 						<line number="858" hits="1"/>
 						<line number="859" hits="1"/>
-						<line number="860" hits="1"/>
-						<line number="861" hits="1"/>
 						<line number="862" hits="1"/>
-						<line number="863" hits="1"/>
-						<line number="864" hits="1"/>
-						<line number="865" hits="1"/>
 						<line number="866" hits="1"/>
 						<line number="867" hits="1"/>
 						<line number="868" hits="1"/>
@@ -1615,62 +1597,73 @@
 						<line number="876" hits="1"/>
 						<line number="877" hits="1"/>
 						<line number="878" hits="1"/>
+						<line number="879" hits="1"/>
+						<line number="880" hits="1"/>
 						<line number="881" hits="1"/>
-						<line number="885" hits="1"/>
+						<line number="882" hits="1"/>
+						<line number="883" hits="1"/>
 						<line number="886" hits="1"/>
-						<line number="887" hits="1"/>
-						<line number="888" hits="1"/>
-						<line number="889" hits="1"/>
 						<line number="890" hits="1"/>
+						<line number="891" hits="1"/>
+						<line number="892" hits="1"/>
 						<line number="893" hits="1"/>
+						<line number="894" hits="1"/>
+						<line number="895" hits="1"/>
+						<line number="896" hits="1"/>
 						<line number="897" hits="1"/>
 						<line number="898" hits="1"/>
+						<line number="899" hits="1"/>
 						<line number="900" hits="1"/>
 						<line number="901" hits="1"/>
+						<line number="902" hits="1"/>
+						<line number="903" hits="1"/>
 						<line number="904" hits="1"/>
+						<line number="905" hits="1"/>
+						<line number="906" hits="1"/>
+						<line number="907" hits="1"/>
 						<line number="908" hits="1"/>
 						<line number="909" hits="1"/>
+						<line number="910" hits="1"/>
 						<line number="911" hits="1"/>
 						<line number="912" hits="1"/>
+						<line number="913" hits="1"/>
 						<line number="914" hits="1"/>
 						<line number="915" hits="1"/>
+						<line number="916" hits="1"/>
 						<line number="917" hits="1"/>
 						<line number="918" hits="1"/>
+						<line number="919" hits="1"/>
+						<line number="920" hits="1"/>
 						<line number="921" hits="1"/>
-						<line number="925" hits="1"/>
+						<line number="922" hits="1"/>
+						<line number="923" hits="1"/>
 						<line number="926" hits="1"/>
-						<line number="928" hits="1"/>
-						<line number="929" hits="1"/>
+						<line number="930" hits="1"/>
+						<line number="931" hits="1"/>
 						<line number="932" hits="1"/>
-						<line number="936" hits="1"/>
-						<line number="937" hits="1"/>
-						<line number="939" hits="1"/>
-						<line number="940" hits="1"/>
+						<line number="933" hits="1"/>
+						<line number="934" hits="1"/>
+						<line number="935" hits="1"/>
+						<line number="938" hits="1"/>
 						<line number="942" hits="1"/>
 						<line number="943" hits="1"/>
 						<line number="945" hits="1"/>
 						<line number="946" hits="1"/>
 						<line number="949" hits="1"/>
-						<line number="950" hits="1"/>
-						<line number="951" hits="1"/>
-						<line number="952" hits="1"/>
 						<line number="953" hits="1"/>
 						<line number="954" hits="1"/>
-						<line number="955" hits="1"/>
 						<line number="956" hits="1"/>
 						<line number="957" hits="1"/>
-						<line number="958" hits="1"/>
 						<line number="959" hits="1"/>
 						<line number="960" hits="1"/>
-						<line number="961" hits="1"/>
-						<line number="964" hits="1"/>
-						<line number="965" hits="1"/>
-						<line number="968" hits="1"/>
-						<line number="969" hits="1"/>
+						<line number="962" hits="1"/>
+						<line number="963" hits="1"/>
+						<line number="966" hits="1"/>
 						<line number="970" hits="1"/>
+						<line number="971" hits="1"/>
 						<line number="973" hits="1"/>
 						<line number="974" hits="1"/>
-						<line number="975" hits="1"/>
+						<line number="977" hits="1"/>
 						<line number="978" hits="1"/>
 						<line number="979" hits="1"/>
 						<line number="980" hits="1"/>
@@ -1683,30 +1676,20 @@
 						<line number="987" hits="1"/>
 						<line number="988" hits="1"/>
 						<line number="989" hits="1"/>
-						<line number="990" hits="1"/>
-						<line number="991" hits="1"/>
 						<line number="992" hits="1"/>
 						<line number="993" hits="1"/>
 						<line number="994" hits="1"/>
-						<line number="997" hits="1"/>
+						<line number="995" hits="1"/>
 						<line number="998" hits="1"/>
 						<line number="999" hits="1"/>
-						<line number="1000" hits="1"/>
-						<line number="1001" hits="1"/>
 						<line number="1002" hits="1"/>
 						<line number="1003" hits="1"/>
 						<line number="1004" hits="1"/>
-						<line number="1005" hits="1"/>
-						<line number="1006" hits="1"/>
 						<line number="1007" hits="1"/>
 						<line number="1008" hits="1"/>
 						<line number="1009" hits="1"/>
-						<line number="1010" hits="1"/>
-						<line number="1011" hits="1"/>
 						<line number="1012" hits="1"/>
 						<line number="1013" hits="1"/>
-						<line number="1014" hits="1"/>
-						<line number="1015" hits="1"/>
 						<line number="1016" hits="1"/>
 						<line number="1017" hits="1"/>
 						<line number="1018" hits="1"/>
@@ -1715,6 +1698,8 @@
 						<line number="1021" hits="1"/>
 						<line number="1022" hits="1"/>
 						<line number="1023" hits="1"/>
+						<line number="1024" hits="1"/>
+						<line number="1025" hits="1"/>
 						<line number="1026" hits="1"/>
 						<line number="1027" hits="1"/>
 						<line number="1028" hits="1"/>
@@ -1722,8 +1707,6 @@
 						<line number="1030" hits="1"/>
 						<line number="1031" hits="1"/>
 						<line number="1032" hits="1"/>
-						<line number="1033" hits="1"/>
-						<line number="1034" hits="1"/>
 						<line number="1035" hits="1"/>
 						<line number="1036" hits="1"/>
 						<line number="1037" hits="1"/>
@@ -1732,6 +1715,8 @@
 						<line number="1040" hits="1"/>
 						<line number="1041" hits="1"/>
 						<line number="1042" hits="1"/>
+						<line number="1043" hits="1"/>
+						<line number="1044" hits="1"/>
 						<line number="1045" hits="1"/>
 						<line number="1046" hits="1"/>
 						<line number="1047" hits="1"/>
@@ -1749,9 +1734,9 @@
 						<line number="1059" hits="1"/>
 						<line number="1060" hits="1"/>
 						<line number="1061" hits="1"/>
-						<line number="1062" hits="1"/>
-						<line number="1063" hits="1"/>
 						<line number="1064" hits="1"/>
+						<line number="1065" hits="1"/>
+						<line number="1066" hits="1"/>
 						<line number="1067" hits="1"/>
 						<line number="1068" hits="1"/>
 						<line number="1069" hits="1"/>
@@ -1763,9 +1748,9 @@
 						<line number="1075" hits="1"/>
 						<line number="1076" hits="1"/>
 						<line number="1077" hits="1"/>
+						<line number="1078" hits="1"/>
+						<line number="1079" hits="1"/>
 						<line number="1080" hits="1"/>
-						<line number="1081" hits="1"/>
-						<line number="1082" hits="1"/>
 						<line number="1083" hits="1"/>
 						<line number="1084" hits="1"/>
 						<line number="1085" hits="1"/>
@@ -1781,23 +1766,32 @@
 						<line number="1095" hits="1"/>
 						<line number="1096" hits="1"/>
 						<line number="1097" hits="1"/>
+						<line number="1098" hits="1"/>
+						<line number="1099" hits="1"/>
 						<line number="1100" hits="1"/>
 						<line number="1101" hits="1"/>
 						<line number="1102" hits="1"/>
-						<line number="1103" hits="1"/>
+						<line number="1105" hits="1"/>
 						<line number="1106" hits="1"/>
 						<line number="1107" hits="1"/>
 						<line number="1108" hits="1"/>
 						<line number="1109" hits="1"/>
 						<line number="1110" hits="1"/>
+						<line number="1111" hits="1"/>
+						<line number="1112" hits="1"/>
 						<line number="1113" hits="1"/>
-						<line number="1117" hits="1"/>
+						<line number="1114" hits="1"/>
+						<line number="1115" hits="1"/>
 						<line number="1118" hits="1"/>
 						<line number="1119" hits="1"/>
 						<line number="1120" hits="1"/>
 						<line number="1121" hits="1"/>
+						<line number="1122" hits="1"/>
+						<line number="1123" hits="1"/>
 						<line number="1124" hits="1"/>
 						<line number="1125" hits="1"/>
+						<line number="1126" hits="1"/>
+						<line number="1127" hits="1"/>
 						<line number="1128" hits="1"/>
 						<line number="1129" hits="1"/>
 						<line number="1130" hits="1"/>
@@ -1810,17 +1804,42 @@
 						<line number="1139" hits="1"/>
 						<line number="1140" hits="1"/>
 						<line number="1141" hits="1"/>
-						<line number="1142" hits="1"/>
-						<line number="1143" hits="1"/>
+						<line number="1144" hits="1"/>
+						<line number="1145" hits="1"/>
 						<line number="1146" hits="1"/>
 						<line number="1147" hits="1"/>
 						<line number="1148" hits="1"/>
-						<line number="1149" hits="1"/>
-						<line number="1152" hits="1"/>
-						<line number="1153" hits="1"/>
-						<line number="1154" hits="1"/>
+						<line number="1151" hits="1"/>
 						<line number="1155" hits="1"/>
 						<line number="1156" hits="1"/>
+						<line number="1157" hits="1"/>
+						<line number="1158" hits="1"/>
+						<line number="1159" hits="1"/>
+						<line number="1162" hits="1"/>
+						<line number="1163" hits="1"/>
+						<line number="1166" hits="1"/>
+						<line number="1167" hits="1"/>
+						<line number="1168" hits="1"/>
+						<line number="1169" hits="1"/>
+						<line number="1170" hits="1"/>
+						<line number="1171" hits="1"/>
+						<line number="1172" hits="1"/>
+						<line number="1173" hits="1"/>
+						<line number="1176" hits="1"/>
+						<line number="1177" hits="1"/>
+						<line number="1178" hits="1"/>
+						<line number="1179" hits="1"/>
+						<line number="1180" hits="1"/>
+						<line number="1181" hits="1"/>
+						<line number="1184" hits="1"/>
+						<line number="1185" hits="1"/>
+						<line number="1186" hits="1"/>
+						<line number="1187" hits="1"/>
+						<line number="1190" hits="1"/>
+						<line number="1191" hits="1"/>
+						<line number="1192" hits="1"/>
+						<line number="1193" hits="1"/>
+						<line number="1194" hits="1"/>
 					</lines>
 				</class>
 				<class name="exceptions.py" filename="dbrepo/api/exceptions.py" complexity="0" line-rate="1" branch-rate="0">
@@ -1860,6 +1879,108 @@
 						<line number="110" hits="1"/>
 					</lines>
 				</class>
+				<class name="mapper.py" filename="dbrepo/api/mapper.py" complexity="0" line-rate="0.5567" branch-rate="0">
+					<methods/>
+					<lines>
+						<line number="1" hits="1"/>
+						<line number="3" hits="1"/>
+						<line number="4" hits="1"/>
+						<line number="5" hits="1"/>
+						<line number="7" hits="1"/>
+						<line number="9" hits="1"/>
+						<line number="12" hits="1"/>
+						<line number="13" hits="1"/>
+						<line number="14" hits="0"/>
+						<line number="15" hits="1"/>
+						<line number="16" hits="1"/>
+						<line number="17" hits="0"/>
+						<line number="18" hits="1"/>
+						<line number="20" hits="1"/>
+						<line number="21" hits="0"/>
+						<line number="22" hits="1"/>
+						<line number="23" hits="1"/>
+						<line number="24" hits="1"/>
+						<line number="26" hits="1"/>
+						<line number="28" hits="1"/>
+						<line number="29" hits="0"/>
+						<line number="31" hits="1"/>
+						<line number="32" hits="1"/>
+						<line number="33" hits="0"/>
+						<line number="34" hits="1"/>
+						<line number="38" hits="1"/>
+						<line number="39" hits="1"/>
+						<line number="40" hits="0"/>
+						<line number="42" hits="0"/>
+						<line number="44" hits="0"/>
+						<line number="45" hits="0"/>
+						<line number="46" hits="0"/>
+						<line number="47" hits="1"/>
+						<line number="50" hits="1"/>
+						<line number="51" hits="1"/>
+						<line number="52" hits="1"/>
+						<line number="53" hits="1"/>
+						<line number="57" hits="1"/>
+						<line number="58" hits="1"/>
+						<line number="59" hits="1"/>
+						<line number="60" hits="1"/>
+						<line number="63" hits="1"/>
+						<line number="64" hits="0"/>
+						<line number="65" hits="0"/>
+						<line number="66" hits="0"/>
+						<line number="67" hits="0"/>
+						<line number="68" hits="0"/>
+						<line number="70" hits="0"/>
+						<line number="71" hits="0"/>
+						<line number="72" hits="1"/>
+						<line number="73" hits="1"/>
+						<line number="74" hits="1"/>
+						<line number="75" hits="1"/>
+						<line number="76" hits="0"/>
+						<line number="77" hits="0"/>
+						<line number="78" hits="0"/>
+						<line number="79" hits="0"/>
+						<line number="80" hits="1"/>
+						<line number="81" hits="1"/>
+						<line number="82" hits="1"/>
+						<line number="83" hits="1"/>
+						<line number="84" hits="1"/>
+						<line number="85" hits="0"/>
+						<line number="86" hits="0"/>
+						<line number="87" hits="0"/>
+						<line number="88" hits="0"/>
+						<line number="89" hits="0"/>
+						<line number="90" hits="0"/>
+						<line number="91" hits="0"/>
+						<line number="92" hits="0"/>
+						<line number="93" hits="0"/>
+						<line number="94" hits="1"/>
+						<line number="95" hits="1"/>
+						<line number="96" hits="1"/>
+						<line number="97" hits="1"/>
+						<line number="98" hits="0"/>
+						<line number="99" hits="0"/>
+						<line number="100" hits="0"/>
+						<line number="101" hits="1"/>
+						<line number="102" hits="1"/>
+						<line number="103" hits="1"/>
+						<line number="104" hits="1"/>
+						<line number="106" hits="0"/>
+						<line number="107" hits="0"/>
+						<line number="108" hits="0"/>
+						<line number="109" hits="0"/>
+						<line number="110" hits="0"/>
+						<line number="111" hits="0"/>
+						<line number="112" hits="0"/>
+						<line number="113" hits="0"/>
+						<line number="115" hits="0"/>
+						<line number="116" hits="1"/>
+						<line number="117" hits="1"/>
+						<line number="119" hits="1"/>
+						<line number="120" hits="1"/>
+						<line number="121" hits="0"/>
+						<line number="122" hits="1"/>
+					</lines>
+				</class>
 			</classes>
 		</package>
 	</packages>
diff --git a/lib/python/dbrepo/RestClient.py b/lib/python/dbrepo/RestClient.py
index f2a93151ecff15ece92618ddf30d9d7bfa0f1dcd..3459543d838cc76ee125f2ad84165caf9bced574 100644
--- a/lib/python/dbrepo/RestClient.py
+++ b/lib/python/dbrepo/RestClient.py
@@ -826,7 +826,7 @@ class RestClient:
         if page is not None and size is not None:
             params.append(('page', page))
             params.append(('size', size))
-        response = self._wrapper(method="get", url=url, params=params)
+        response = self._wrapper(method="get", url=url, params=params, headers={'Accept': 'application/json'})
         if response.status_code == 200:
             return DataFrame.from_records(response.json())
         if response.status_code == 400:
@@ -869,7 +869,7 @@ class RestClient:
             params.append(('size', size))
         if timestamp is not None:
             params.append(('timestamp', timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")))
-        response = self._wrapper(method="get", url=url, params=params)
+        response = self._wrapper(method="get", url=url, params=params, headers={'Accept': 'application/json'})
         if response.status_code == 200:
             return DataFrame.from_records(response.json())
         if response.status_code == 400:
@@ -1393,11 +1393,10 @@ class RestClient:
         :raises ServiceError: If something went wrong with obtaining the information in the data service.
         :raises ResponseCodeError: If something went wrong with the retrieval.
         """
-        headers = {}
         url = f'/api/database/{database_id}/subset/{subset_id}/data'
         if page is not None and size is not None:
             url += f'?page={page}&size={size}'
-        response = self._wrapper(method="get", url=url, headers=headers)
+        response = self._wrapper(method="get", url=url, headers={'Accept': 'application/json'})
         if response.status_code == 200:
             return DataFrame.from_records(response.json())
         if response.status_code == 400:
@@ -1786,7 +1785,7 @@ class RestClient:
 
     def get_identifier(self, identifier_id: str) -> Identifier:
         """
-        Get list of identifiers, filter by the remaining optional arguments.
+        Get the identifier by given id.
 
         :param identifier_id: The identifier id.
 
@@ -1805,6 +1804,39 @@ class RestClient:
         raise ResponseCodeError(f'Failed to get identifier: response code: {response.status_code} is not '
                                 f'200 (OK): {response.text}')
 
+    def get_identifier_data(self, identifier_id: str) -> DataFrame:
+        """
+        Get the identifier data by given id.
+
+        :param identifier_id: The identifier id.
+
+        :returns: The identifier, if successful.
+
+        :raises NotExistsError: If the identifier does not exist.
+        :raises ResponseCodeError: If something went wrong with the retrieval of the identifier.
+        """
+        url = f'/api/identifier/{identifier_id}'
+        response = self._wrapper(method="get", url=url, headers={'Accept': 'application/json'})
+        if response.status_code == 200:
+            body = response.json()
+            identifier = Identifier.model_validate(body)
+            if identifier.type == IdentifierType.VIEW:
+                return self.get_view_data(database_id=identifier.database_id, view_id=identifier.view_id, page=0,
+                                          size=10000)
+            elif identifier.type == IdentifierType.TABLE:
+                return self.get_table_data(database_id=identifier.database_id, table_id=identifier.table_id, page=0,
+                                           size=10000)
+            elif identifier.type == IdentifierType.SUBSET:
+                return self.get_subset_data(database_id=identifier.database_id, subset_id=identifier.query_id, page=0,
+                                            size=10000)
+            raise FormatNotAvailable(f'Failed to get identifier data: type is database')
+        if response.status_code == 404:
+            raise NotExistsError(f'Failed to get identifier data: not found')
+        if response.status_code == 406:
+            raise NotExistsError(f'Failed to get identifier data: type database')
+        raise ResponseCodeError(f'Failed to get identifier data: response code: {response.status_code} is not '
+                                f'200 (OK): {response.text}')
+
     def get_image(self, image_id: str) -> Image:
         """
         Get container image.
diff --git a/lib/python/dbrepo/api/dto.py b/lib/python/dbrepo/api/dto.py
index 526ba29bf7d4dfea5983bce99c84c2e67e8befe4..356f9b220095970886e524e8cccefdd49ea823c7 100644
--- a/lib/python/dbrepo/api/dto.py
+++ b/lib/python/dbrepo/api/dto.py
@@ -653,6 +653,7 @@ class IdentifierSave(CreateIdentifier):
 class Identifier(BaseModel):
     id: str
     database_id: str
+    links: Links
     type: IdentifierType
     owner: UserBrief
     status: IdentifierStatusType
@@ -988,6 +989,12 @@ class Query(BaseModel):
     identifiers: List[IdentifierBrief] = field(default_factory=list)
 
 
+class Links(BaseModel):
+    self: str
+    self_html: str
+    data: Optional[str] = None
+
+
 class UpdateQuery(BaseModel):
     persist: bool
 
diff --git a/lib/python/tests/test_unit_identifier.py b/lib/python/tests/test_unit_identifier.py
index 9ac386437c29f4c65f6879d1a1f0c98641652652..137a513d4666ad097094f67d6fd4dcff80fc1d3b 100644
--- a/lib/python/tests/test_unit_identifier.py
+++ b/lib/python/tests/test_unit_identifier.py
@@ -7,7 +7,7 @@ from dbrepo.api.dto import Identifier, IdentifierType, SaveIdentifierTitle, Crea
     IdentifierDescription, SaveIdentifierDescription, Language, SaveIdentifierFunder, SaveRelatedIdentifier, \
     RelatedIdentifierRelation, RelatedIdentifierType, IdentifierFunder, RelatedIdentifier, UserBrief, \
     IdentifierStatusType, CreateIdentifierCreator, CreateIdentifierTitle, CreateIdentifierFunder, \
-    CreateRelatedIdentifier, CreateIdentifierDescription, SaveIdentifierCreator
+    CreateRelatedIdentifier, CreateIdentifierDescription, SaveIdentifierCreator, Links
 from dbrepo.api.exceptions import MalformedError, ForbiddenError, NotExistsError, AuthenticationError, \
     ServiceConnectionError, ServiceError, ResponseCodeError, FormatNotAvailable, RequestError
 
@@ -19,6 +19,9 @@ class IdentifierUnitTest(unittest.TestCase):
             exp = Identifier(id="f6171539-a479-4829-9b9b-a6b474e1c7d3",
                              database_id="6bd39359-b154-456d-b9c2-caa516a45732",
                              view_id="e5229d24-584a-43e8-b9f6-d349c3053f9c",
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              publication_year=2024,
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
@@ -172,6 +175,9 @@ class IdentifierUnitTest(unittest.TestCase):
                               publisher='TU Wien',
                               type=IdentifierType.VIEW,
                               language=Language.EN,
+                              links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                          self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                          data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                               descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                   description='Test Description')],
                               titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3",
@@ -275,6 +281,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3",
@@ -517,6 +526,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -530,7 +542,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=202)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=202)
             # test
             client = RestClient(username="a", password="b")
             response = client.publish_identifier(identifier_id="f6171539-a479-4829-9b9b-a6b474e1c7d3")
@@ -545,6 +558,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -558,7 +574,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=400)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=400)
             # test
             try:
                 RestClient(username="a", password="b").publish_identifier(
@@ -575,6 +592,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -588,7 +608,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=403)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=403)
             # test
             try:
                 RestClient(username="a", password="b").publish_identifier(
@@ -605,6 +626,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -618,7 +642,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=404)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=404)
             # test
             try:
                 RestClient(username="a", password="b").publish_identifier(
@@ -635,6 +660,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -648,7 +676,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=502)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=502)
             # test
             try:
                 RestClient(username="a", password="b").publish_identifier(
@@ -665,6 +694,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -678,7 +710,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=503)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=503)
             # test
             try:
                 RestClient(username="a", password="b").publish_identifier(
@@ -695,6 +728,9 @@ class IdentifierUnitTest(unittest.TestCase):
                              publisher='TU Wien',
                              type=IdentifierType.VIEW,
                              language=Language.EN,
+                             links=Links(self="/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         self_html="/pid/f6171539-a479-4829-9b9b-a6b474e1c7d3",
+                                         data="/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view/e5229d24-584a-43e8-b9f6-d349c3053f9c/data"),
                              descriptions=[IdentifierDescription(id="d8bdc933-655c-46bd-9903-ede3928a304b",
                                                                  description='Test Description')],
                              titles=[IdentifierTitle(id="f6171539-a479-4829-9b9b-a6b474e1c7d3", title='Test Title')],
@@ -708,7 +744,8 @@ class IdentifierUnitTest(unittest.TestCase):
                              status=IdentifierStatusType.PUBLISHED,
                              owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'))
             # mock
-            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(), status_code=200)
+            mock.put('/api/identifier/f6171539-a479-4829-9b9b-a6b474e1c7d3/publish', json=exp.model_dump(),
+                     status_code=200)
             # test
             try:
                 RestClient(username="a", password="b").publish_identifier(