API Documentation
The TU Wien Research Data API provides programmatic access to datasets, metadata, search functionalities, and more. This API lets you automate data management tasks, integrate with external systems, or build custom workflows for data analysis and visualization.
In this page we list the most common API operations which include:
- Case 1 - Retrieve a Dataset's Metadata
- Case 2 - Search for Datasets
- Case 3 - Upload a New Dataset
- Case 4 - Attach a File to an Existing Record
- Case 5 - File Download
While our customized implementation inherits all the core functionalities from a vanilla InvenioRDM instance, it introduces several enhancements to better serve the research community:
- Custom Permissions: Unlike the standard InvenioRDM, our instance enforces enhanced permission settings. For instance, an extra "guard" ensures that users can't create drafts in the system without being granted access by an administrator. Moreover, records prior to publication go also through an administrative review, thus ensuring that only curated high-quality content can be publicly available.
- Curation Workflow: A thorough review system now includes new ways to interact through the interface. These endpoints allow curators to review submissions, add annotations, and approve records before they are published, ensuring compliance with data quality and regulatory standards.
- Invenio-DAMAP Integration: Our deployment includes extended functionality through the Invenio-DAMAP package.This is the additional fine layer of advanced digital asset management such as automatic population of DMP fields and enriched file-specific metadata in the TU Wien DMP Tool.
For detailed examples of our enhanced Curation Workflow and Invenio-DAMAP integration, please see the Additional Customizations section below.
Authentication
Note: Operations such as creating records or attaching files require an access token. You can generate one here. Other operations (like retrieving metadata) are public.
Common Query Parameters
For search endpoints, the most relevant parameters include:
q
: The search query (e.g.,q=title:climate
).sort
: Sorting criteria (e.g.,sort=newest
).size
: Results size per page (e.g.,size=50
).page
: Pagination control (e.g.,page=1
).
More details about query parameters can be found in the official InvenioRDM API Documentation.
API Usage Examples
Case 1 - Retrieve a Dataset's Metadata: Quickly fetch detailed metadata for a dataset using its persistent identifier.
User Story: As a researcher, I want to quickly retrieve detailed metadata for a dataset using its unique identifier so that I can verify its relevance and incorporate accurate information into my analysis.
Endpoint: GET /api/records/{record_id}
Token Required: No
cURL:
curl "https://researchdata.tuwien.ac.at/api/records/abcde-12345"
Python (requests):
import requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345" response = requests.get(url) print(response.json())
Example Response (HTTP 200 - OK):
{ "id": "abcde-12345", "metadata": { "title": "Dataset Title", "creators": [{"name": "Doe, John"}], "publication_date": "2025-01-09", "resource_type": {"id": "dataset", "title": {"en": "Dataset"}} }, "links": { "self": "https://researchdata.tuwien.ac.at/api/records/abcde-12345", "files": "https://researchdata.tuwien.ac.at/api/records/abcde-12345/files" } }
Case 2 - Search for Datasets: Execute advanced searches with filters (keywords, authors, dates, etc.).
User Story: As a data scientist, I want to search for datasets using keywords and publication ranges, or author names so that I can find data that matches my research criteria without browsing through irrelevant records.
Endpoint: GET /api/records
Token Required: No
Query Parameters: q
, sort
, and page
cURL:
curl -G "https://researchdata.tuwien.ac.at/api/records" \ --data-urlencode "q=climate AND metadata.publication_date:[2023 TO 2025]" \ --data-urlencode "sort=newest" \ --data-urlencode "page=1"
Python (requests):
import requests params = { "q": "climate AND metadata.publication_date=[2023 TO 2025]", "sort": "newest", "page": 1 } url = "https://researchdata.tuwien.ac.at/api/records" response = requests.get(url, params=params) print(response.json())
Example Response (HTTP 200 - OK):
{ "hits": { "total": 2, "hits": [ { "id": "abcde-12345", "metadata": { "title": "Climate Change Data", "publication_date": "2025-01-01" } }, { "id": "efgh-5678", "metadata": { "title": "Temperature Records", "publication_date": "2024-12-25" } } ] }, "links": { "self": "https://researchdata.tuwien.ac.at/api/records?q=climate&sort=newest&page=1", "next": "https://researchdata.tuwien.ac.at/api/records?q=climate&sort=newest&page=2" } }
π‘Hint: You can refer to our search guide for further details on how to construct simple or advanced search queries.
Case 3 - Upload a New Dataset: Automate metadata submissions and record creation.
User Story: As a lab scientist, I want to automate the upload of new datasets along with detailed metadata so that my research outputs are quickly published, discoverable, and citable through an assigned DOI.
cURL Snippets:
Step 1: Create a new draft
curl -X POST "https://researchdata.tuwien.ac.at/api/records" \ -H "Authorization: Bearer {your-access-token}" \ -H "Content-Type: application/json" \ -d ' { "metadata": { "creators": [ { "person_or_org": { "family_name": "Doe", "given_name": "Jane", "type": "personal" } } ], "publication_date": "2025-01-09", "publisher": "TU Wien", "resource_type": {"id": "dataset"}, "title": "New Dataset Title" }, "files": {"enabled": true} }'
Step 2: Request a DOI
curl -X POST "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/pids/doi" \ -H "Authorization: Bearer {your-access-token}"
Python (requests) Snippets:
Step 1: Create a new draft
import requests url = "https://researchdata.tuwien.ac.at/api/records" headers = { "Authorization": "Bearer {your-access-token}", "Content-Type": "application/json" } data = { "metadata": { "creators": [ { "person_or_org": { "family_name": "Doe", "given_name": "Jane", "type": "personal", } } ], "publication_date": "2025-01-09", "publisher": "TU Wien", "resource_type": {"id": "dataset"}, "title": "New Dataset Title", }, "files": {"enabled": True}, } response = requests.post(url, json=data, headers=headers) print(response.json())
Step 2: Request a DOI
import requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/pids/doi" headers = { "Authorization": "Bearer {your-access-token}", } response = requests.post(url, headers=headers) print(response.json())
Case 4 - Attach a File to an Existing Record: Enrich records by associating files using a multi-step upload process.
User Story: As a project manager, I want to attach supplementary files (like additional data or documentation) to an existing dataset record so that all components of the research project are organized and accessible in one place.
-
Initialize the file upload:
Endpoint::
POST /api/records/{record_id}/draft/files
Token Required: Yes β generate one here.
-
Upload the file content:
Endpoint:
PUT /api/records/{record_id}/draft/files/{file_name}/content
Token Required: Yes β generate one here.
-
Commit draft file upload:
Endpoint:
POST /api/records/{record_id}/draft/files/{file_name}/commit
Token Required: Yes β generate one here.
-
Publish the draft: (After curation request has been accepted - See curation endpoint)
Endpoint:
POST /api/records/{record_id}/draft/actions/publish
Token Required: Yes β generate one here.
cURL Snippets:
Step 1: Initialize File Upload
curl -X POST "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/files" \ -H "Authorization: Bearer {your-access-token}" \ -H "Content-Type: application/json" \ -d ' { "files": [{"key": "example_dataset.csv"}] }'
Step 2: Upload File Content
curl -X PUT "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/files/example_dataset.csv/content" \ -H "Authorization: Bearer {your-access-token}" \ -H "Content-Type: application/octet-stream" \ --data-binary @example_dataset.csv
Step 3: Commit Draft File Upload
curl -X POST "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/files/example_dataset.csv/commit" \ -H "Authorization: Bearer {your-access-token}"
Step 4: Publish the Draft (After curation request has been accepted - See curation endpoint)
curl -X POST "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/actions/publish" \ -H "Authorization: Bearer {your-access-token}"
Python (requests) Snippets:
Step 1: Initialize File Upload
import requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/files" headers = { "Authorization": "Bearer {your-access-token}", "Content-Type": "application/json" } data = [ { "key": "example_dataset.csv" } ] response = requests.post(url, json=data, headers=headers) print(response.json())
Step 2: Upload File Content
import requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/files/example_dataset.csv/content" headers = { "Authorization": "Bearer {your-access-token}", "Content-Type": "application/octet-stream" } with open("example_dataset.csv", "rb") as file_data: response = requests.put(url, headers=headers, data=file_data) print(response.json())
Step 3: Commit Draft File Upload
import requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/files/example_dataset.csv/commit" headers = { "Authorization": "Bearer {your-access-token}", } response = requests.post(url, headers=headers) print(response.json())
Step 4: Publish the Draft (After curation request has been accepted - See curation endpoint)
import requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345/draft/actions/publish" headers = { "Authorization": "Bearer {your-access-token}", } data = { "metadata": { "title": "New Dataset Title", "creators": [{"name": "Doe, Jane"}], "publication_date": "2025-01-09", "resource_type": {"id": "dataset"} }, "files": {"enabled": True} } response = requests.post(url, json=data, headers=headers) print(response.json())
Case 5 - File Download: Retrieving Contents from a Record.
User Story: As a researcher, I want to download an individual file from a dataset so that I can analyze its contents locally without navigating through multiple interfaces.
Endpoint: GET /api/records/{record_id}/files/{filename}/content
Token Required: No
cURL:
curl -JO "https://researchdata.tuwien.ac.at/api/records/abcde-12345/files/example_dataset.csv/content"
Python (requests):
import os, re, requests url = "https://researchdata.tuwien.ac.at/api/records/abcde-12345/files/example_dataset.csv/content" response = requests.get(url, stream=True) content_disposition = response.headers.get("Content-Disposition", "") filename = re.search(r'filename="([^"]+)"', content_disposition).group(1) with open(filename, "wb") as f: for chunk in response.iter_content(chunk_size=8192): _ = f.write(chunk) print("File saved at: ", os.path.abspath(filename))
Example Response Headers (HTTP 200 - OK):
Content-Disposition: attachment; filename="example_dataset.csv" Content-Length: 5577907 Content-Type: application/octet-stream Date: Mon, 28 Fri 2025 13:56:29 GMT ETag: "674c65f3-551cb3" Last-Modified: Sun, 01 Dec 2024 13:34:43 GMT
Additional Customizations
Extended Functionality: Custom Endpoints
Our customized instance of the repository comes with additional endpoints that differ from what would be expected from a standard Invenio RDM installation. These improvements cover the following:
-
Curation Workflow Requests:
We offer an API that supports a custom curation process. Custom endpoints assign curators to records, review submissions, add curation notes, and allow publishing of curated content. This workflow guarantees that data quality and compliance standards are met prior to data being made public.
Create a new curation request:
Endpoint:
POST /api/curations/
Token Required: Yes β generate one here.
cURL:
curl -X POST "https://researchdata.tuwien.ac.at/api/curations/" \ -H "Authorization: Bearer {your-access-token}" \ -H "Content-Type: application/json" \ -d ' { "topic":{ "record": "fghij-54321" } }'
Python (requests):
import requests url = "https://researchdata.tuwien.ac.at/api/curations/" headers = { "Authorization": "Bearer {your-access-token}", } data = { "topic":{ "record": "fghij-54321" } } response = requests.post(url, json=data, headers=headers) print(response.json())
-
Invenio-DAMAP Endpoints:
Additionally, we provide extra endpoints that ship with the Invenio-DAMAP package. They allow to directly link your record to a DAMAP-based system, by automatically filling specific DMP fields, saving you time and effort.For further details about this integration, visit the dedicated DAMAP page.
Additional Resources
For further details, please refer to the official InvenioRDM API Documentation.