diff --git a/requirements.txt b/requirements.txt
index a19e9db0f2ea3d56ced4a29681563dc53d257303..28331ab437c9506c0e464e3d3124a5acd55316d3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,4 +8,4 @@ pymitter==0.5.0
 uvicorn==0.27.1
 python-multipart==0.0.9
 aiosmtplib==3.0.1
-nacsos_data[scripts,server,utils] @ git+ssh://git@gitlab.pik-potsdam.de/mcc-apsis/nacsos/nacsos-data.git@v0.14.5
+nacsos_data[scripts,server,utils] @ git+ssh://git@gitlab.pik-potsdam.de/mcc-apsis/nacsos/nacsos-data.git@v0.14.6
diff --git a/server/api/routes/export.py b/server/api/routes/export.py
index 3be91c3639b356a605929bedf2306fe67203858a..52506ca918a668dcb0cfe7a0302eb8d28f204fc4 100644
--- a/server/api/routes/export.py
+++ b/server/api/routes/export.py
@@ -6,21 +6,21 @@ from typing import TYPE_CHECKING
 
 from nacsos_data.db.crud.projects import read_project_by_id
 
-from fastapi import APIRouter, Depends, Query
-from nacsos_data.db.schemas import ItemType
-from nacsos_data.util.annotations.export import \
-    prepare_export_table, \
-    get_project_labels, \
-    get_project_scopes, \
-    get_project_bot_scopes, \
-    get_project_users, \
+from fastapi import APIRouter, Depends
+from nacsos_data.models.nql import NQLFilter
+from nacsos_data.util.annotations.export import (
+    prepare_export_table,
+    get_project_labels,
+    get_project_scopes,
+    get_project_bot_scopes,
+    get_project_users,
     LabelOptions
+)
 from pydantic import BaseModel
 from starlette.background import BackgroundTask
 from starlette.responses import FileResponse
 
-from server.util.security import \
-    UserPermissionChecker
+from server.util.security import UserPermissionChecker
 
 from nacsos_data.util.auth import UserPermissions
 
@@ -40,23 +40,27 @@ class CFR(FileResponse):  # custom file response to set the media type
     media_type = 'application/csv'
 
 
+class ExportRequest(BaseModel):
+    labels: list[LabelOptions]
+    nql_filter: NQLFilter | None = None
+    bot_annotation_metadata_ids: list[str] | None = None
+    assignment_scope_ids: list[str] | None = None
+    user_ids: list[str] | None = None
+    ignore_hierarchy: bool = True
+    ignore_repeat: bool = True
+
+
 @router.post('/annotations/csv', response_class=CFR)
-async def get_annotations_csv(labels: list[LabelOptions],
-                              bot_annotation_metadata_ids: list[str] | None = Query(default=None),
-                              assignment_scope_ids: list[str] | None = Query(default=None),
-                              user_ids: list[str] | None = Query(default=None),
-                              ignore_hierarchy: bool = Query(default=True),
-                              ignore_repeat: bool = Query(default=True),
-                              item_fields: list[str] | None = Query(default=None),
+async def get_annotations_csv(query: ExportRequest,
                               permissions: UserPermissions = Depends(UserPermissionChecker('annotations_read'))):
-    result = await prepare_export_table(bot_annotation_metadata_ids=bot_annotation_metadata_ids,
-                                        assignment_scope_ids=assignment_scope_ids,
-                                        user_ids=user_ids,
+    result = await prepare_export_table(bot_annotation_metadata_ids=query.bot_annotation_metadata_ids,
+                                        assignment_scope_ids=query.assignment_scope_ids,
+                                        user_ids=query.user_ids,
                                         project_id=permissions.permissions.project_id,
-                                        labels=labels,
-                                        ignore_repeat=ignore_repeat,
-                                        ignore_hierarchy=ignore_hierarchy,
-                                        item_fields=item_fields,
+                                        labels=query.labels,
+                                        nql_filter=query.nql_filter,
+                                        ignore_repeat=query.ignore_repeat,
+                                        ignore_hierarchy=query.ignore_hierarchy,
                                         db_engine=db_engine)
 
     with tempfile.NamedTemporaryFile(suffix='.csv', mode='w', newline='', delete=False) as fp:
@@ -87,7 +91,6 @@ class ProjectBaseInfo(BaseModel):
     scopes: list[ProjectBaseInfoScopeEntry]
     bot_scopes: list[ProjectBaseInfoEntry]
     labels: dict[str, LabelOptions]
-    fields: list[str]
 
 
 @router.get('/project/baseinfo', response_model=ProjectBaseInfo)
@@ -105,17 +108,7 @@ async def get_export_baseinfo(permissions: UserPermissions = Depends(UserPermiss
     if project is None:
         raise RuntimeError('Invalid state!')
 
-    if project.type == ItemType.twitter:
-        fields = ['text', 'twitter_id', 'created_at', 'twitter_author_id', 'conversation_id']
-    elif project.type == ItemType.academic:
-        fields = ['text', 'title', 'doi', 'wos_id', 'scopus_id', 'openalex_id', 'publication_year', 'source']
-    elif project.type == ItemType.lexis:
-        fields = ['text', 'teaser', 'author']  # TODO: ideally we would also export the source data
-    else:
-        fields = ['text']
-
     return ProjectBaseInfo(users=[ProjectBaseInfoEntry.model_validate(pu) for pu in project_users],
                            scopes=[ProjectBaseInfoScopeEntry.model_validate(ps) for ps in project_scopes],
                            bot_scopes=[ProjectBaseInfoEntry.model_validate(pbs) for pbs in project_bot_scopes],
-                           labels=project_labels,
-                           fields=fields)
+                           labels=project_labels)