diff --git a/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts b/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
index d8a70c20e7bccf6401fe08087ee4508002b14288..f4f18e65571d33e43ad0c3ea9f27a30107b9c463 100644
--- a/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
+++ b/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
@@ -51,6 +51,9 @@ export enum ApiRootLinkRel {
   ALL_WIEDERVORLAGEN = 'vorgaenge_wiedervorlagen_all',
   MY_WIEDERVORLAGEN = 'vorgaenge_wiedervorlagen_my',
   UNASSIGNED_WIEDERVORLAGEN = 'vorgaenge_wiedervorlagen_unassigned',
+  ALL_UNGELESENE_NACHRICHTEN = 'vorgaenge_ungelesene_nachrichten_all',
+  MY_UNGELESENE_NACHRICHTEN = 'vorgaenge_ungelesene_nachrichten_my',
+  UNASSIGNED_UNGELESENE_NACHRICHTEN = 'vorgaenge_ungelesene_nachrichten_unassigned',
   ALLE_VORGAENGE_ZU_LOESCHEN = 'vorgaenge_zu_loeschen_all',
   MEINE_VORGAENGE_ZU_LOESCHEN = 'vorgaenge_zu_loeschen_my',
   UNASSIGNED_ZU_LOESCHEN = 'vorgaenge_zu_loeschen_unassigned',
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts
index 94216faa5f7884f6fa1252e711f49e26d957462c..c7a5be544eed27c2ee84715549bd578f02b079c7 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts
@@ -143,6 +143,7 @@ function createEmptyVorgangStatistic(): VorgangStatistic {
     },
     wiedervorlagen: null,
     existsWiedervorlageOverdue: false,
+    ungeleseneNachrichten: 0,
   };
 }
 
diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts
index 67f6e3da2c32b30e3fe1140a25047b97196b193e..9214160eaabd1f68c97f33762312139fbe2241e9 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts
@@ -42,6 +42,7 @@ export const BESCHIEDEN_ROUTE_PARAM: string = 'beschieden';
 export const ABGESCHLOSSEN_ROUTE_PARAM: string = 'abgeschlossen';
 export const VERWORFEN_ROUTE_PARAM: string = 'verworfen';
 export const WIEDERVORLAGEN_ROUTE_PARAM: string = 'wiedervorlagen';
+export const UNGELESENE_NACHRICHTEN_ROUTE_PARAM: string = 'ungelesene_nachrichten';
 export const ZU_LOESCHEN_ROUTE_PARAM: string = 'zu_loeschen';
 export const SEARCH_ROUTE_PARAM: string = 'search';
 
@@ -56,6 +57,7 @@ export const ROUTE_PARAM_BY_VORGANG_VIEW: { [view: string]: string } = {
   [VorgangView.VERWORFEN]: VERWORFEN_ROUTE_PARAM,
   [VorgangView.VORGANG_LIST]: EMPTY_STRING,
   [VorgangView.WIEDERVORLAGEN]: WIEDERVORLAGEN_ROUTE_PARAM,
+  [VorgangView.UNGELESENE_NACHRICHTEN]: UNGELESENE_NACHRICHTEN_ROUTE_PARAM,
   [VorgangView.ZU_LOESCHEN]: ZU_LOESCHEN_ROUTE_PARAM,
   [VorgangView.SEARCH]: SEARCH_ROUTE_PARAM,
 };
@@ -68,6 +70,7 @@ export const VORGANG_VIEW_BY_ROUTE_PARAM: { [routeParam: string]: VorgangView }
   [ABGESCHLOSSEN_ROUTE_PARAM]: VorgangView.ABGESCHLOSSEN,
   [VERWORFEN_ROUTE_PARAM]: VorgangView.VERWORFEN,
   [WIEDERVORLAGEN_ROUTE_PARAM]: VorgangView.WIEDERVORLAGEN,
+  [UNGELESENE_NACHRICHTEN_ROUTE_PARAM]: VorgangView.UNGELESENE_NACHRICHTEN,
   [ZU_LOESCHEN_ROUTE_PARAM]: VorgangView.ZU_LOESCHEN,
   [SEARCH_ROUTE_PARAM]: VorgangView.SEARCH,
 };
diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts
index 41b412c9839bb98940bbdd55ea74e8fcd1e47cb3..c18d952fcec598790bc40eee1a0522742c0eccd3 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts
@@ -109,6 +109,7 @@ export interface VorgangStatistic {
   byStatus: ByStatus;
   wiedervorlagen: number;
   existsWiedervorlageOverdue: boolean;
+  ungeleseneNachrichten: number;
 }
 
 export interface ByStatus {
@@ -163,6 +164,7 @@ export enum VorgangView {
   WIEDERVORLAGEN,
   SEARCH,
   ZU_LOESCHEN,
+  UNGELESENE_NACHRICHTEN,
 }
 
 export interface StatusCommandMap {
diff --git a/alfa-client/libs/vorgang-shared/test/vorgang.ts b/alfa-client/libs/vorgang-shared/test/vorgang.ts
index 743c5e65339cfc65091a3db158cdbf8664863b3c..8bddc8cc501bf26b18890d8106b0eef67dc3a3ff 100644
--- a/alfa-client/libs/vorgang-shared/test/vorgang.ts
+++ b/alfa-client/libs/vorgang-shared/test/vorgang.ts
@@ -145,6 +145,7 @@ export function createVorgangStatistic(): VorgangStatistic {
     byStatus: createByStatus(),
     wiedervorlagen: faker.datatype.number(),
     existsWiedervorlageOverdue: false,
+    ungeleseneNachrichten: faker.datatype.number(),
   };
 }
 
diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html
index c7d9d6fc8850a44c562412d25b77ea4a0c2cda83..6c874f1b35f4c2e6ea7955504a4dc69a5937fa6b 100644
--- a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html
+++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html
@@ -130,6 +130,22 @@
     >
       <div class="dot zu-loeschen"></div>
     </alfa-vorgang-view-item-container>
+    <alfa-vorgang-view-item-container
+      *ngIf="
+        apiRootResource
+          | hasAnyLink
+            : apiRootLinkRel.ALL_UNGELESENE_NACHRICHTEN
+            : apiRootLinkRel.MY_UNGELESENE_NACHRICHTEN
+            : apiRootLinkRel.UNASSIGNED_UNGELESENE_NACHRICHTEN
+      "
+      data-test-id="vorgang-ungelesene-nachrichten-view"
+      label="Ungelesen"
+      [view]="vorgangView.UNGELESENE_NACHRICHTEN"
+      [count]="statistic.ungeleseneNachrichten"
+      class="top-border"
+    >
+      <ozgcloud-postfach-icon [showBadge]="true"></ozgcloud-postfach-icon>
+    </alfa-vorgang-view-item-container>
     <alfa-vorgang-view-item-container
       *ngIf="
         apiRootResource
@@ -142,7 +158,6 @@
       label="Wiedervorlagen"
       [view]="vorgangView.WIEDERVORLAGEN"
       [count]="statistic.wiedervorlagen"
-      class="top-border"
     >
       <alfa-wiedervorlage-icon
         [isOverdue]="statistic.existsWiedervorlageOverdue"
diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.scss b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.scss
index 4b089df917f623d3d02d1f44fcca2dc9e7ba79c1..e6328b2c2a8d60b60bd8a536fe854ad19450a9e6 100644
--- a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.scss
+++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.scss
@@ -70,6 +70,7 @@ body.dark :host {
   }
 }
 
-ozgcloud-icon {
+ozgcloud-icon,
+ozgcloud-postfach-icon {
   margin-right: 6px;
 }
diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts
index cf4f8bd301a92a054afbf9e6c3d22c7c1af0b5fe..2d312f19021b016c3985e0b17b487fc982210f79 100644
--- a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts
+++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts
@@ -25,7 +25,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ApiRootLinkRel } from '@alfa-client/api-root-shared';
 import { HasLinkPipe, createStateResource } from '@alfa-client/tech-shared';
 import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils';
-import { OzgcloudIconComponent } from '@alfa-client/ui';
+import { OzgcloudIconComponent, PostfachIconComponent } from '@alfa-client/ui';
 import { createApiRootResource } from 'libs/api-root-shared/test/api-root';
 import { HasAnyLinkPipe } from 'libs/tech-shared/src/lib/pipe/has-any-link.pipe';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
@@ -48,6 +48,7 @@ describe('VorgangViewsMenuComponent', () => {
   const abgeschlossenView: string = getDataTestIdOf('vorgang-abgeschlossen-view');
   const verworfenView: string = getDataTestIdOf('vorgang-verworfen-view');
   const wiedervorlagenView: string = getDataTestIdOf('vorgang-wiedervorlagen-view');
+  const ungeleseneNachrichtenView: string = getDataTestIdOf('vorgang-ungelesene-nachrichten-view');
   const vorgangListView: string = getDataTestIdOf('vorgang-vorgang-list-view');
   const searchView: string = getDataTestIdOf('vorgang-search-view');
 
@@ -62,6 +63,7 @@ describe('VorgangViewsMenuComponent', () => {
         MockComponent(VorgangViewItemComponent),
         MockComponent(VorgangSearchViewItemContainerComponent),
         MockComponent(OzgcloudIconComponent),
+        MockComponent(PostfachIconComponent),
       ],
     }).compileComponents();
 
@@ -215,6 +217,26 @@ describe('VorgangViewsMenuComponent', () => {
     });
   });
 
+  describe('ungelesene nachrichten view', () => {
+    it.each([
+      ApiRootLinkRel.ALL_UNGELESENE_NACHRICHTEN,
+      ApiRootLinkRel.MY_UNGELESENE_NACHRICHTEN,
+      ApiRootLinkRel.UNASSIGNED_UNGELESENE_NACHRICHTEN,
+    ])('should show if %s link exists', (linkRel: string) => {
+      component.apiRootResource = createApiRootResource([linkRel]);
+      fixture.detectChanges();
+
+      existsAsHtmlElement(fixture, ungeleseneNachrichtenView);
+    });
+
+    it('should hide if link not exists', () => {
+      component.apiRootResource = createApiRootResource();
+      fixture.detectChanges();
+
+      notExistsAsHtmlElement(fixture, ungeleseneNachrichtenView);
+    });
+  });
+
   describe('vorgangList view', () => {
     it.each([
       ApiRootLinkRel.ALLE_VORGAENGE,
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java
index e8d834618a56d3efd308efa231d6ca5c13cc13ef..b5d79fcc0ab64557b88236b0903d0aafc14e125f 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java
@@ -38,6 +38,10 @@ class RootViewLinkHandler {
 	static final String SEARCH_MY_VORGEANGE_REL = "search_my";
 	static final String SEARCH_UNASSIGNED_VORGEANGE_REL = "search_unassigned";
 
+	static final String ALL_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_all";
+	static final String MY_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_my";
+	static final String UNASSIGNED_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_unassigned";
+
 	static final int PAGE_SIZE = 100;
 
 	@Autowired
@@ -100,6 +104,8 @@ class RootViewLinkHandler {
 		modelBuilder
 				.addLink(buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(UserId.empty(), UNASSIGNED_WIEDERVORLAGEN_REL));
 		userId.map(id -> buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(id, MY_WIEDERVORLAGEN_REL)).ifPresent(modelBuilder::addLink);
+
+		addGetByUngeleseneNachrichtenLinks(modelBuilder, userId);
 	}
 
 	Link buildGetAllUnassignedVorgaengeLink() {
@@ -169,4 +175,22 @@ class RootViewLinkHandler {
 		return linkTo(methodOn(VorgangController.class).getAllByAssignedToAndHasNextWiedervorlageFrist(0, PAGE_SIZE, userId,
 				VorgangController.PARAM_NEXT_WIEDERVORLAGE_FRIST_EXISTS)).withRel(linkRel);
 	}
+
+	void addGetByUngeleseneNachrichtenLinks(ModelBuilder<Root> modelBuilder, Optional<UserId> userId) {
+		modelBuilder.addLink(buildGelAllByUngeleseneNachrichtenLink());
+		modelBuilder.addLink(buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), UNASSIGNED_UNGELESENE_NACHRICHTEN_REL));
+		userId.map(id -> buildGetAllByAssignedToAndUngeleseneNachrichten(id, MY_UNGELESENE_NACHRICHTEN_REL)).ifPresent(modelBuilder::addLink);
+	}
+
+	Link buildGelAllByUngeleseneNachrichtenLink() {
+		return linkTo(methodOn(VorgangController.class)
+				.getAllByUngeleseneNachrichten(0, PAGE_SIZE, VorgangController.PARAM_NACHRICHTEN_UNGELESENE))
+				.withRel(ALL_UNGELESENE_NACHRICHTEN_REL);
+	}
+
+	Link buildGetAllByAssignedToAndUngeleseneNachrichten(@NonNull UserId userId, String linkRel) {
+		return linkTo(methodOn(VorgangController.class)
+				.getAllByAssignedToAndUngeleseneNachrichten(0, PAGE_SIZE, userId, VorgangController.PARAM_NACHRICHTEN_UNGELESENE))
+				.withRel(linkRel);
+	}
 }
\ No newline at end of file
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/Statistic.java b/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/Statistic.java
index 2a17cc875696000782390062587d6e91474db53f..855d2ef1c57c58cc69cebffe7fb37facf972a25f 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/Statistic.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/Statistic.java
@@ -12,4 +12,5 @@ public class Statistic {
 	private ByStatus byStatus;
 	private int wiedervorlagen;
 	private boolean existsWiedervorlageOverdue;
+	private int ungeleseneNachrichten;
 }
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticRemoteService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticRemoteService.java
index cd508d6198827251fd4f661a7e0a4815570fa898..b39e47178187ac8a31b838d794bf7580f6748c67 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticRemoteService.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticRemoteService.java
@@ -11,9 +11,9 @@ import org.springframework.stereotype.Service;
 import de.ozgcloud.alfa.AlfaProperties;
 import de.ozgcloud.alfa.common.GrpcUtil;
 import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery.GroupMethod;
-import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery.Operator;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticRequest;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticResponse;
 import de.ozgcloud.vorgang.statistic.StatisticServiceGrpc.StatisticServiceBlockingStub;
@@ -25,9 +25,11 @@ class StatisticRemoteService {
 	static final String COUNT_VORGANG_STATUS_RESULT_NAME_FORMAT = "countVorgangStatus_%s";
 	static final String COUNT_WIEDERVORLAGE_NEXT_FRIST_RESULT_NAME = "countWiedervorlage";
 	static final String EXISTS_WIEDERVORLAGE_OVERDUE_RESULT_NAME = "existsWiedervorlageOverdue";
+	static final String COUNT_VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_RESULT_NAME = "countVorgaengeWithUngeleseneNachrichten";
 
 	static final String STATUS_PATH = "Vorgang.status";
 	static final String WIEDERVORLAGE_NEXT_FRIST_PATH_TEMPLATE = "ClientAttribute.%s.nextWiedervorlageFrist";
+	static final String VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH = "ClientAttribute.OzgCloud_NachrichtenManager.hasNewPostfachNachricht";
 
 	static final String OPERAND_TODAY_DATE = "today()";
 
@@ -43,6 +45,7 @@ class StatisticRemoteService {
 				.addAllQuery(buildCountByStatusQueries(countByVorgangStatus))
 				.addQuery(buildCountWiedervorlageNextFristQuery())
 				.addQuery(buildExistsWiedervorlageOverdueQuery())
+				.addQuery(buildCountVorgaengeWithUngeleseneNachrichtenQuery())
 				.build();
 
 		var grpcResponse = statisticServiceStub.getVorgangStatistic(grpcRequest);
@@ -59,7 +62,7 @@ class StatisticRemoteService {
 				.setResultName(buildCountByStatusResultName(vorgangStatus))
 				.setPath(STATUS_PATH)
 				.setGroupMethod(GroupMethod.COUNT)
-				.setOperator(Operator.EQUAL)
+				.setOperator(GrpcQueryOperator.EQUAL)
 				.setOperandStringValue(vorgangStatus.name())
 				.build();
 	}
@@ -69,7 +72,7 @@ class StatisticRemoteService {
 				.setResultName(COUNT_WIEDERVORLAGE_NEXT_FRIST_RESULT_NAME)
 				.setPath(String.format(WIEDERVORLAGE_NEXT_FRIST_PATH_TEMPLATE, alfaProperties.getApplicationName()))
 				.setGroupMethod(GroupMethod.COUNT)
-				.setOperator(Operator.UNEQUAL)
+				.setOperator(GrpcQueryOperator.UNEQUAL)
 				.build();
 	}
 
@@ -78,7 +81,7 @@ class StatisticRemoteService {
 				.setResultName(EXISTS_WIEDERVORLAGE_OVERDUE_RESULT_NAME)
 				.setPath(String.format(WIEDERVORLAGE_NEXT_FRIST_PATH_TEMPLATE, alfaProperties.getApplicationName()))
 				.setGroupMethod(GroupMethod.EXISTS)
-				.setOperator(Operator.LESS_THEN_OR_EQUAL_TO)
+				.setOperator(GrpcQueryOperator.LESS_THEN_OR_EQUAL_TO)
 				.setOperandStringValue(OPERAND_TODAY_DATE)
 				.build();
 	}
@@ -93,4 +96,14 @@ class StatisticRemoteService {
 				.map(mapper::toResult)
 				.collect(Collectors.toMap(StatisticResult::getName, Function.identity()));
 	}
+
+	public GrpcVorgangStatisticQuery buildCountVorgaengeWithUngeleseneNachrichtenQuery() {
+		return GrpcVorgangStatisticQuery.newBuilder()
+				.setResultName(COUNT_VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_RESULT_NAME)
+				.setPath(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH)
+				.setGroupMethod(GroupMethod.COUNT)
+				.setOperator(GrpcQueryOperator.EQUAL)
+				.setOperandBoolValue(true)
+				.build();
+	}
 }
\ No newline at end of file
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticService.java
index 68b9ab06c4d73f5b6810035b9b1312a6d3edbd2c..6b88ba78d635f291e3db330f661119f131ceb019 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticService.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/statistic/StatisticService.java
@@ -48,6 +48,7 @@ class StatisticService {
 		return Statistic.builder()
 				.existsWiedervorlageOverdue(getBooleanResult(response, StatisticRemoteService.EXISTS_WIEDERVORLAGE_OVERDUE_RESULT_NAME))
 				.wiedervorlagen(getIntResult(response, StatisticRemoteService.COUNT_WIEDERVORLAGE_NEXT_FRIST_RESULT_NAME))
+				.ungeleseneNachrichten(getIntResult(response, StatisticRemoteService.COUNT_VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_RESULT_NAME))
 				.byStatus(ByStatus.builder()
 						.neu(getIntResult(response, remoteService.buildCountByStatusResultName(VorgangStatus.NEU)))
 						.abgeschlossen(getIntResult(response, remoteService.buildCountByStatusResultName(VorgangStatus.ABGESCHLOSSEN)))
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/FilterCriteria.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/FilterCriteria.java
index c80e8617af570fb48b34bf5bea4cd4070212630f..89fe664537bdb8c0f58eece1b848ce0a4e00b395 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/FilterCriteria.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/FilterCriteria.java
@@ -22,4 +22,5 @@ class FilterCriteria {
 	@Builder.Default
 	private Optional<UserId> assignedTo = Optional.empty();
 	private boolean hasNextWiedervorlageFrist;
+	private boolean hasUngeleseneNachrichten;
 }
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java
index 35062413fb4a816eaf0263aa284d2bc5b32b4e6a..8d23095292dea0d30595fcdde1a13e3191e61d28 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java
@@ -25,8 +25,6 @@ package de.ozgcloud.alfa.vorgang;
 
 import java.util.Optional;
 
-import jakarta.servlet.http.HttpServletResponse;
-
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.hateoas.EntityModel;
@@ -46,6 +44,7 @@ import de.ozgcloud.alfa.common.clientattribute.ClientAttributeService;
 import de.ozgcloud.alfa.common.user.UserId;
 import de.ozgcloud.alfa.statistic.StatisticController;
 import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
+import jakarta.servlet.http.HttpServletResponse;
 
 @RestController
 @RequestMapping(VorgangController.PATH)
@@ -58,8 +57,10 @@ public class VorgangController {
 	static final String PARAM_ASSIGNED_TO = "assignedTo";
 	static final String PARAM_STATUS = "status";
 	static final String PARAM_NEXT_WIEDERVORLAGE_FRIST = "nextFrist";
+	static final String PARAM_NACHRICHTEN = "nachrichten";
 
 	public static final String PARAM_NEXT_WIEDERVORLAGE_FRIST_EXISTS = "exists";
+	public static final String PARAM_NACHRICHTEN_UNGELESENE = "ungelesene";
 
 	@Autowired
 	private VorgangService vorgangService;
@@ -189,4 +190,27 @@ public class VorgangController {
 		clientAttributeService.resetPostfachNachricht(vorgangId);
 		response.setStatus(HttpStatus.NO_CONTENT.value());
 	}
+
+	@GetMapping(params = { PARAM_PAGE, PARAM_LIMIT, PARAM_NACHRICHTEN })
+	public RepresentationModel<EntityModel<EnhancedVorgang>> getAllByUngeleseneNachrichten(@RequestParam int page, @RequestParam Integer limit,
+			@RequestParam String nachrichten) {
+		var requestCriteria = FindVorgaengeHeaderRequestCriteria.builder().page(page).limit(limit)
+				.filterCriteria(FilterCriteria.builder().hasUngeleseneNachrichten(PARAM_NACHRICHTEN_UNGELESENE.equals(nachrichten)).build())
+				.build();
+
+		return handleGetAllRequest(requestCriteria);
+	}
+
+	@GetMapping(params = { PARAM_PAGE, PARAM_LIMIT, PARAM_ASSIGNED_TO, PARAM_NACHRICHTEN })
+	public RepresentationModel<EntityModel<EnhancedVorgang>> getAllByAssignedToAndUngeleseneNachrichten(@RequestParam int page,
+			@RequestParam Integer limit, @RequestParam UserId assignedTo, @RequestParam String nachrichten) {
+		var requestCriteria = FindVorgaengeHeaderRequestCriteria.builder().page(page).limit(limit)
+				.filterCriteria(FilterCriteria.builder()
+						.filterByAssignedTo(true).assignedTo(asOptional(assignedTo))
+						.hasUngeleseneNachrichten(PARAM_NACHRICHTEN_UNGELESENE.equals(nachrichten))
+						.build())
+				.build();
+
+		return handleGetAllRequest(requestCriteria);
+	}
 }
\ No newline at end of file
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangRemoteService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangRemoteService.java
index bb2d49e67b4e7c57dac52b54c1aa27d329fd9525..a6d44d0c43309ab1f751b909d66d7a2483b5e492 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangRemoteService.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangRemoteService.java
@@ -29,18 +29,23 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.alfa.common.GrpcUtil;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
 import de.ozgcloud.vorgang.vorgang.GrpcFilterBy;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangRequest;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangRequest.GrpcOrderBy;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangResponse;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangResponse;
+import de.ozgcloud.vorgang.vorgang.GrpcQuery;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression;
 import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
 @Service
 class VorgangRemoteService {
 
+	static final String VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH = "ClientAttribute.OzgCloud_NachrichtenManager.hasNewPostfachNachricht";
+
 	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
 	private VorgangServiceBlockingStub vorgangServiceStub;
 	@Autowired
@@ -70,7 +75,24 @@ class VorgangRemoteService {
 				.setOrderBy(GrpcOrderBy.valueOf(requestCriteria.getOrderBy().name()))
 				.setLimit(requestCriteria.getLimit())
 				.setOffset(requestCriteria.getPage() * requestCriteria.getLimit())
-				.setFilterBy(mapFilterCriteria(filterCriteria));
+				.setQuery(createQuery(filterCriteria))
+				.setFilterBy(createFilterBy(filterCriteria));
+	}
+
+	GrpcQuery createQuery(FilterCriteria filterCriteria) {
+		var queryBuilder = GrpcQuery.newBuilder();
+		if (filterCriteria.isHasUngeleseneNachrichten()) {
+			addUngeleseneNachrichtenExpression(queryBuilder);
+		}
+		return queryBuilder.build();
+	}
+
+	private void addUngeleseneNachrichtenExpression(GrpcQuery.Builder queryBuilder) {
+		queryBuilder.addExpressions(GrpcVorgangQueryExpression.newBuilder()
+				.setPath(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH)
+				.setOperator(GrpcQueryOperator.EQUAL)
+				.setOperandBoolValue(true)
+				.build());
 	}
 
 	VorgaengeHeaderResponse buildVorgaengeHeaderResponse(GrpcFindVorgangResponse response) {
@@ -90,10 +112,10 @@ class VorgangRemoteService {
 	}
 
 	GrpcFindVorgangWithEingangRequest buildFindVorgangWithEingangRequest(String vorgangId, FilterCriteria filterCriteria) {
-		return GrpcFindVorgangWithEingangRequest.newBuilder().setId(vorgangId).setFilterBy(mapFilterCriteria(filterCriteria)).build();
+		return GrpcFindVorgangWithEingangRequest.newBuilder().setId(vorgangId).setFilterBy(createFilterBy(filterCriteria)).build();
 	}
 
-	GrpcFilterBy mapFilterCriteria(FilterCriteria filterCriteria) {
+	GrpcFilterBy createFilterBy(FilterCriteria filterCriteria) {
 		var filterCriteriaBuilder = GrpcFilterBy.newBuilder()
 				.setFilterByAssignedTo(filterCriteria.isFilterByAssignedTo())
 				.setFilterByOrganisationseinheitenId(filterCriteria.isFilterByOrganisationseinheitenId())
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java
index 64f4aadcf97daf229570e1affc1273dc9423da7a..84733b060eff9e273ab5bb84f97ccd00588bf73e 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java
@@ -6,6 +6,7 @@ import static org.mockito.Mockito.*;
 
 import java.util.Optional;
 
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -18,6 +19,8 @@ import org.mockito.Spy;
 import org.springframework.hateoas.Link;
 import org.springframework.hateoas.LinkRelation;
 
+import com.thedeanda.lorem.LoremIpsum;
+
 import de.ozgcloud.alfa.common.ModelBuilder;
 import de.ozgcloud.alfa.common.user.CurrentUserService;
 import de.ozgcloud.alfa.common.user.UserId;
@@ -282,6 +285,13 @@ class RootViewLinkHandlerTest {
 							.get().extracting(Link::getHref).isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=&nextFrist=exists");
 				}
 			}
+
+			@Test
+			void shouldAddLinksForUngeleseneNachrichten() {
+				viewLinkHandler.addViewLinksForVerwaltungUser(modelBuilder, Optional.of(UserProfileTestFactory.ID));
+
+				verify(viewLinkHandler).addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID));
+			}
 		}
 
 		@DisplayName("search all vorgaenge")
@@ -318,7 +328,7 @@ class RootViewLinkHandlerTest {
 			void shouldBeAddedIfUserIsPresent() {
 				var link = viewLinkHandler.buildMyVorgaengeLink(UserProfileTestFactory.ID);
 
-				assertThat(link.getHref()).isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=" + UserProfileTestFactory.ID.toString());
+				assertThat(link.getHref()).isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=" + UserProfileTestFactory.ID);
 			}
 		}
 
@@ -504,6 +514,176 @@ class RootViewLinkHandlerTest {
 		}
 	}
 
+	@Nested
+	class TestBuildGelAllByUngeleseneNachrichtenLink {
+
+		@Test
+		void shouldHaveLinkHref() {
+			var link = viewLinkHandler.buildGelAllByUngeleseneNachrichtenLink();
+
+			assertThat(link)
+					.extracting(Link::getHref)
+					.isEqualTo("/api/vorgangs?page=0&limit=100&nachrichten=ungelesene");
+		}
+
+		@Test
+		void shouldHaveLinkRel() {
+			var link = viewLinkHandler.buildGelAllByUngeleseneNachrichtenLink();
+
+			assertThat(link)
+					.extracting(Link::getRel)
+					.extracting(LinkRelation::value)
+					.isEqualTo(RootViewLinkHandler.ALL_UNGELESENE_NACHRICHTEN_REL);
+		}
+	}
+
+	@Nested
+	class TestBuildGetAllByAssignedToAndUngeleseneNachrichten {
+
+		@Nested
+		class AssignTo {
+
+			@Test
+			void shouldHaveLink() {
+				var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID,
+						RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL);
+
+				assertThat(link)
+						.extracting(Link::getHref)
+						.isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=" + UserProfileTestFactory.ID + "&nachrichten=ungelesene");
+			}
+
+			@Test
+			void shouldHaveLinkRel() {
+				var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID,
+						RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL);
+
+				assertThat(link)
+						.extracting(Link::getRel)
+						.extracting(LinkRelation::value)
+						.isEqualTo(RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL);
+			}
+		}
+
+		@Nested
+		class Unassigned {
+
+			@Test
+			void shouldHaveLink() {
+				var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(),
+						RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL);
+
+				assertThat(link)
+						.extracting(Link::getHref)
+						.isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=&nachrichten=ungelesene");
+			}
+
+			@Test
+			void shouldHaveLinkRel() {
+				var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(),
+						RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL);
+
+				assertThat(link)
+						.extracting(Link::getRel)
+						.extracting(LinkRelation::value)
+						.isEqualTo(RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL);
+			}
+
+		}
+
+	}
+
+	@Nested
+	class TestAddGetByUngeleseneNachrichtenLinks {
+
+		@Mock
+		private Root rootResource;
+		private final ModelBuilder<Root> modelBuilder = ModelBuilder.fromEntity(rootResource);
+		private final Link linkAllUngeleseneNachrichten = Link.of(LoremIpsum.getInstance().getUrl());
+		private final Link linkMyUngeleseneNachrichten = Link.of(LoremIpsum.getInstance().getUrl());
+		private final Link linkUnassignedUngeleseneNachrichten = Link.of(LoremIpsum.getInstance().getUrl());
+
+		@BeforeEach
+		void setUp() {
+			doReturn(linkAllUngeleseneNachrichten).when(viewLinkHandler).buildGelAllByUngeleseneNachrichtenLink();
+			doReturn(linkUnassignedUngeleseneNachrichten).when(viewLinkHandler)
+					.buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL);
+		}
+
+		@Test
+		void shouldBuildLinkForUngeleseneNachrichten() {
+			viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID));
+
+			verify(viewLinkHandler).buildGelAllByUngeleseneNachrichtenLink();
+		}
+
+		@Test
+		void shouldAddLinkForUngeleseneNachrichten() {
+			var modelBuilder = ModelBuilder.fromEntity(rootResource);
+
+			viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID));
+
+			assertThat(modelBuilder.buildModel().getLinks()).contains(linkAllUngeleseneNachrichten);
+		}
+
+		@Test
+		void shouldBuildLinkForUnassignedUngeleseneNachrichten() {
+			viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.empty());
+
+			verify(viewLinkHandler).buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(),
+					RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL);
+		}
+
+		@Test
+		void shouldAddLinkForUnassignedUngeleseneNachrichten() {
+			var modelBuilder = ModelBuilder.fromEntity(rootResource);
+
+			viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.empty());
+
+			assertThat(modelBuilder.buildModel().getLinks()).contains(linkUnassignedUngeleseneNachrichten);
+		}
+
+		@Nested
+		class UsedIdExists {
+
+			@BeforeEach
+			void setUp() {
+				doReturn(linkMyUngeleseneNachrichten).when(viewLinkHandler).buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID,
+						RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL);
+			}
+
+			@Test
+			void shouldBuildLinkForMyUngeleseneNachrichten() {
+				viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID));
+
+				verify(viewLinkHandler).buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID,
+						RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL);
+			}
+
+			@Test
+			void shouldAddLinkForMyUngeleseneNachrichten() {
+				var modelBuilder = ModelBuilder.fromEntity(rootResource);
+
+				viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID));
+
+				assertThat(modelBuilder.buildModel().getLinks()).contains(linkMyUngeleseneNachrichten);
+			}
+		}
+
+		@Nested
+		class UserIdEmpty {
+
+			@Test
+			void shouldNotBuildLinkForMyUngeleseneNachrichten() {
+				viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.empty());
+
+				verify(viewLinkHandler, never()).buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID,
+						RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL);
+			}
+		}
+
+	}
+
 	//	@DisplayName("Test user assistance documentation link")
 	//	@Nested
 	//	class TestDocumentationLink {
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/GrpcVorgangStatisticQueryTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/GrpcVorgangStatisticQueryTestFactory.java
index 0d26d330dc055948cec844b3cfd851f4adf72fd5..517f2f4495241c63259375ad45e7e6389b120f67 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/GrpcVorgangStatisticQueryTestFactory.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/GrpcVorgangStatisticQueryTestFactory.java
@@ -1,14 +1,19 @@
 package de.ozgcloud.alfa.statistic;
 
+import com.thedeanda.lorem.LoremIpsum;
+
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery;
 
 public class GrpcVorgangStatisticQueryTestFactory {
 
+	public static final String RESULT_NAME = LoremIpsum.getInstance().getWords(1);
+
 	public static GrpcVorgangStatisticQuery create() {
 		return createBuilder().build();
 	}
 
 	public static GrpcVorgangStatisticQuery.Builder createBuilder() {
-		return GrpcVorgangStatisticQuery.newBuilder();
+		return GrpcVorgangStatisticQuery.newBuilder()
+				.setResultName(RESULT_NAME);
 	}
 }
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticRemoteServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticRemoteServiceTest.java
index 5716d65c2197741fbf8d03e498f3b283e398cc17..8306173ae997b9ade430cb8dfe93a2a4749b531f 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticRemoteServiceTest.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticRemoteServiceTest.java
@@ -15,6 +15,8 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
 import org.junit.jupiter.params.provider.EnumSource.Mode;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
@@ -23,9 +25,10 @@ import com.thedeanda.lorem.LoremIpsum;
 
 import de.ozgcloud.alfa.AlfaProperties;
 import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery.GroupMethod;
-import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticQuery.Operator;
+import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticRequest;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticResponse;
 import de.ozgcloud.vorgang.statistic.GrpcVorgangStatisticResult;
 import de.ozgcloud.vorgang.statistic.StatisticServiceGrpc.StatisticServiceBlockingStub;
@@ -79,7 +82,7 @@ class StatisticRemoteServiceTest {
 		void shouldContainOperator(VorgangStatus vorgangStatus) {
 			var query = service.buildCountByVorgangStatusQuery(vorgangStatus);
 
-			assertThat(query.getOperator()).isEqualTo(Operator.EQUAL);
+			assertThat(query.getOperator()).isEqualTo(GrpcQueryOperator.EQUAL);
 		}
 
 		@ParameterizedTest
@@ -126,7 +129,7 @@ class StatisticRemoteServiceTest {
 					.contains(
 							COUNT_WIEDERVORLAGE_NEXT_FRIST_RESULT_NAME,
 							String.format(StatisticRemoteService.WIEDERVORLAGE_NEXT_FRIST_PATH_TEMPLATE, applicationName),
-							Operator.UNEQUAL,
+							GrpcQueryOperator.UNEQUAL,
 							GroupMethod.COUNT
 					);
 		}
@@ -167,7 +170,7 @@ class StatisticRemoteServiceTest {
 		void shouldContainOperator() {
 			var query = service.buildExistsWiedervorlageOverdueQuery();
 
-			assertThat(query.getOperator()).isEqualTo(Operator.LESS_THEN_OR_EQUAL_TO);
+			assertThat(query.getOperator()).isEqualTo(GrpcQueryOperator.LESS_THEN_OR_EQUAL_TO);
 		}
 
 		@Test
@@ -190,12 +193,20 @@ class StatisticRemoteServiceTest {
 	class TestGetVorgaengeStatistics {
 
 		private final GrpcVorgangStatisticResponse response = GrpcVorgangStatisticResponseTestFactory.create();
+		private final GrpcVorgangStatisticQuery countVorgaengeWithUngeleseneNachrichtenQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder()
+				.setResultName("ungelesene nachrichten").build();
+		private final GrpcVorgangStatisticQuery existsWiedervorlageOverdueQuery = GrpcVorgangStatisticQueryTestFactory.createBuilder()
+				.setResultName("exists overdue").build();
+
+		@Captor
+		private ArgumentCaptor<GrpcVorgangStatisticRequest> grpcRequestCaptor;
 
 		@BeforeEach
 		void beforeEach() {
 			when(serviceStub.getVorgangStatistic(any())).thenReturn(response);
 
-			doReturn(GrpcVorgangStatisticQueryTestFactory.create()).when(service).buildExistsWiedervorlageOverdueQuery();
+			doReturn(existsWiedervorlageOverdueQuery).when(service).buildExistsWiedervorlageOverdueQuery();
+			doReturn(countVorgaengeWithUngeleseneNachrichtenQuery).when(service).buildCountVorgaengeWithUngeleseneNachrichtenQuery();
 		}
 
 		@Test
@@ -232,6 +243,21 @@ class StatisticRemoteServiceTest {
 
 			verify(service).buildStatisticResult(response);
 		}
+
+		@Test
+		void shouldCallBuildCountVorgaengeWithUngeleseneNachrichtenQuery() {
+			service.getVorgaengeStatistics(STATUSES_TO_COUNT);
+
+			verify(service).buildCountVorgaengeWithUngeleseneNachrichtenQuery();
+		}
+
+		@Test
+		void shouldAddCountVorgaengeWithUngeleseneNachrichtenQuery() {
+			service.getVorgaengeStatistics(STATUSES_TO_COUNT);
+
+			verify(serviceStub).getVorgangStatistic(grpcRequestCaptor.capture());
+			assertThat(grpcRequestCaptor.getValue().getQueryList()).contains(countVorgaengeWithUngeleseneNachrichtenQuery);
+		}
 	}
 
 	@Nested
@@ -270,4 +296,47 @@ class StatisticRemoteServiceTest {
 					.hasEntrySatisfying(RESULT_NAME, statisticResult -> assertThat(statisticResult.getIntValue()).isEqualTo(RESULT_INT));
 		}
 	}
+
+	@Nested
+	class TestBuildCountVorgaengeWithUngeleseneNachrichtenQuery {
+
+		@Test
+		void shouldHaveResultName() {
+			var query = callService();
+
+			assertThat(query.getResultName()).isEqualTo(COUNT_VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_RESULT_NAME);
+		}
+
+		@Test
+		void shouldHavePath() {
+			var query = callService();
+
+			assertThat(query.getPath()).isEqualTo(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH);
+		}
+
+		@Test
+		void shouldHaveGroupingMethod() {
+			var query = callService();
+
+			assertThat(query.getGroupMethod()).isEqualTo(GroupMethod.COUNT);
+		}
+
+		@Test
+		void shouldHaveOperator() {
+			var query = callService();
+
+			assertThat(query.getOperator()).isEqualTo(GrpcQueryOperator.EQUAL);
+		}
+
+		@Test
+		void shouldHaveOperandValue() {
+			var query = callService();
+
+			assertThat(query.getOperandBoolValue()).isTrue();
+		}
+
+		private GrpcVorgangStatisticQuery callService() {
+			return service.buildCountVorgaengeWithUngeleseneNachrichtenQuery();
+		}
+	}
 }
\ No newline at end of file
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticServiceTest.java
index 1b030d675d4eec8e8cee9f8c2bcb0f3f83e339e1..e35e1de7fecbdcfeae02ca7e75064d40e354546d 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticServiceTest.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticServiceTest.java
@@ -138,6 +138,14 @@ class StatisticServiceTest {
 
 			assertThat(statistic.getByStatus().getNeu()).isZero();
 		}
+
+		@Test
+		void shouldContainUngeleseneNachrichten() {
+			var statistic = service.buildGetVorgaengeStatisticResult(
+					Map.of(COUNT_VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_RESULT_NAME, StatisticResultTestFactory.create()));
+
+			assertThat(statistic.getUngeleseneNachrichten()).isEqualTo(StatisticResultTestFactory.INT_VALUE);
+		}
 	}
 
 	@Nested
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticTestFactory.java
index d4acbda72b80abdb119b6e736812291208ae0411..5808eb9355941f76f27cf1e036c4eabd9fc410ec 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticTestFactory.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/statistic/StatisticTestFactory.java
@@ -4,6 +4,7 @@ public class StatisticTestFactory {
 
 	public static final int COUNT_WIEDERVORLAGEN = 8;
 	public static final boolean EXISTS_WIEDERVORLAGE_OVERDUE = true;
+	public static final int COUNT_UNGELESENE_NACHRICHTEN = 5;
 
 	public static Statistic create() {
 		return createBuilder().build();
@@ -13,6 +14,7 @@ public class StatisticTestFactory {
 		return Statistic.builder()
 				.byStatus(ByStatusTestFactory.create())
 				.wiedervorlagen(COUNT_WIEDERVORLAGEN)
-				.existsWiedervorlageOverdue(EXISTS_WIEDERVORLAGE_OVERDUE);
+				.existsWiedervorlageOverdue(EXISTS_WIEDERVORLAGE_OVERDUE)
+				.ungeleseneNachrichten(COUNT_UNGELESENE_NACHRICHTEN);
 	}
 }
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/FilterCriteriaTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/FilterCriteriaTestFactory.java
index a4572dc1eaf28498d41b9aa0da67f8a935ea837b..a6fd2febaf7e1c665f9fbee464ba4d0c48f45f68 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/FilterCriteriaTestFactory.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/FilterCriteriaTestFactory.java
@@ -10,11 +10,10 @@ public class FilterCriteriaTestFactory {
 
 	public static final boolean FILTER_BY_ORGANISATIONS_EINHEITEN_ID = true;
 	public static final boolean FILTER_BY_ASSIGNED_TO = true;
-
 	public static final VorgangStatus VORGANG_STATUS = VorgangStatus.NEU;
 	public static final String ORGANISATIONS_EINHEIT_ID = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID;
-
 	public static final boolean HAS_NEXT_WIEDERVORLAGE_FRIST = false;
+	public static final boolean HAS_UNGELESENE_NACHRICHTEN = false;
 
 	public static FilterCriteria create() {
 		return createBuilder().build();
@@ -27,6 +26,7 @@ public class FilterCriteriaTestFactory {
 				.filterByAssignedTo(FILTER_BY_ASSIGNED_TO)
 				.assignedTo(Optional.of(UserProfileTestFactory.ID))
 				.organisationsEinheitenId(List.of(ORGANISATIONS_EINHEIT_ID))
-				.hasNextWiedervorlageFrist(HAS_NEXT_WIEDERVORLAGE_FRIST);
+				.hasNextWiedervorlageFrist(HAS_NEXT_WIEDERVORLAGE_FRIST)
+				.hasUngeleseneNachrichten(HAS_UNGELESENE_NACHRICHTEN);
 	}
 }
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/GrpcQueryTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/GrpcQueryTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..33c4fe7c36a9af6b5a85423c00b649af863ab468
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/GrpcQueryTestFactory.java
@@ -0,0 +1,14 @@
+package de.ozgcloud.alfa.vorgang;
+
+import de.ozgcloud.vorgang.vorgang.GrpcQuery;
+
+public class GrpcQueryTestFactory {
+
+	public static GrpcQuery create() {
+		return createBuilder().build();
+	}
+
+	public static GrpcQuery.Builder createBuilder() {
+		return GrpcQuery.newBuilder();
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerITCase.java
index 8eea6215c5ed51e9cd4d184c627a70ba5ee5a55a..c93835bcb0da848cf565cdedfc35ee677880ce3a 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerITCase.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerITCase.java
@@ -142,42 +142,42 @@ class VorgangControllerITCase {
 				private static final String BY_STATUS_PATH = "$.statistic.byStatus.";
 
 				@Test
-				void shouldContainsNeu() throws Exception {
+				void shouldContainNeu() throws Exception {
 					var response = doRequest();
 
 					response.andExpect(jsonPath(BY_STATUS_PATH + "neu").value(ByStatusTestFactory.NEU_COUNT));
 				}
 
 				@Test
-				void shouldContainsAngenommen() throws Exception {
+				void shouldContainAngenommen() throws Exception {
 					var response = doRequest();
 
 					response.andExpect(jsonPath(BY_STATUS_PATH + "angenommen").value(ByStatusTestFactory.ANGENOMMEN_COUNT));
 				}
 
 				@Test
-				void shouldContainsInBearbeitung() throws Exception {
+				void shouldContainInBearbeitung() throws Exception {
 					var response = doRequest();
 
 					response.andExpect(jsonPath(BY_STATUS_PATH + "inBearbeitung").value(ByStatusTestFactory.IN_BEARBEITUNG_COUNT));
 				}
 
 				@Test
-				void shouldContainsBeschieden() throws Exception {
+				void shouldContainBeschieden() throws Exception {
 					var response = doRequest();
 
 					response.andExpect(jsonPath(BY_STATUS_PATH + "beschieden").value(ByStatusTestFactory.BESCHIEDEN_COUNT));
 				}
 
 				@Test
-				void shouldContainsAbgeschlossen() throws Exception {
+				void shouldContainAbgeschlossen() throws Exception {
 					var response = doRequest();
 
 					response.andExpect(jsonPath(BY_STATUS_PATH + "abgeschlossen").value(ByStatusTestFactory.ABGESCHLOSSEN_COUNT));
 				}
 
 				@Test
-				void shouldContainsVerworfen() throws Exception {
+				void shouldContainVerworfen() throws Exception {
 					var response = doRequest();
 
 					response.andExpect(jsonPath(BY_STATUS_PATH + "verworfen").value(ByStatusTestFactory.VERWORFEN_COUNT));
@@ -185,11 +185,18 @@ class VorgangControllerITCase {
 			}
 
 			@Test
-			void shouldContainsWiedervorlagen() throws Exception {
+			void shouldContainWiedervorlagen() throws Exception {
 				var response = doRequest();
 
 				response.andExpect(jsonPath("$.statistic.wiedervorlagen").value(StatisticTestFactory.COUNT_WIEDERVORLAGEN));
 			}
+
+			@Test
+			void shouldContainUngeleseneNachrichten() throws Exception {
+				var response = doRequest();
+
+				response.andExpect(jsonPath("$.statistic.ungeleseneNachrichten").value(StatisticTestFactory.COUNT_UNGELESENE_NACHRICHTEN));
+			}
 		}
 	}
 
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerTest.java
index eb68a2d7b8716df1ac05a12ae42ffc6b34e89600..4c237346f037043fb98cf7c8c49a3a72b8e65bfd 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerTest.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangControllerTest.java
@@ -30,10 +30,15 @@ import static org.mockito.Mockito.*;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
 
+import java.util.List;
+
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.InjectMocks;
@@ -606,6 +611,163 @@ class VorgangControllerTest {
 				}
 			}
 		}
+
+		@Nested
+		class TestGetAllByUngeleseneNachrichten {
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCallHandleGetAllRequest(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(any(FindVorgaengeHeaderRequestCriteria.class));
+			}
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCriteriaHavePage(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+				assertThat(criteriaCaptor.getValue().getPage()).isEqualTo(PAGE);
+			}
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCriteriaHaveLimit(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+				assertThat(criteriaCaptor.getValue().getLimit()).isEqualTo(LIMIT);
+			}
+
+			static List<String> nachrichtenValues() {
+				return List.of(VorgangController.PARAM_NACHRICHTEN_UNGELESENE, "", "dummy");
+			}
+
+			@Nested
+			class WithParamNachrichtenUngelesene {
+
+				@Test
+				void shouldCriteriaHaveHasUngeleseneNachrichtenTrue() {
+					doRequestWithNachrichtenParam(VorgangController.PARAM_NACHRICHTEN_UNGELESENE);
+
+					verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+					assertThat(criteriaCaptor.getValue().getFilterCriteria().isHasUngeleseneNachrichten()).isTrue();
+				}
+			}
+
+			@Nested
+			class WithoutParamNachrichtenUngelesene {
+
+				@ParameterizedTest
+				@ValueSource(strings = {"", "dummy"})
+				void shouldCriteriaHaveHasUngeleseneNachrichtenFalse(String nachrichtenValue) {
+					doRequestWithNachrichtenParam(nachrichtenValue);
+
+					verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+					assertThat(criteriaCaptor.getValue().getFilterCriteria().isHasUngeleseneNachrichten()).isFalse();
+				}
+			}
+
+			@SneakyThrows
+			private void doRequestWithNachrichtenParam(String paramValue) {
+				mockMvc.perform(get(PATH)
+								.param(VorgangController.PARAM_PAGE, Integer.toString(PAGE))
+								.param(VorgangController.PARAM_LIMIT, Integer.toString(LIMIT))
+								.param(VorgangController.PARAM_NACHRICHTEN, paramValue))
+						.andExpect(status().isOk());
+			}
+		}
+
+		@Nested
+		class TestGetAllByAssignedToAndUngeleseneNachrichten {
+
+			private static final UserId ASSIGNED_TO = UserProfileTestFactory.ID;
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCallHandleGetAllRequest(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(any(FindVorgaengeHeaderRequestCriteria.class));
+			}
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCriteriaHavePage(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+				assertThat(criteriaCaptor.getValue().getPage()).isEqualTo(PAGE);
+			}
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCriteriaHaveLimit(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+				assertThat(criteriaCaptor.getValue().getLimit()).isEqualTo(LIMIT);
+			}
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldCriteriaHaveAssignedTo(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+				assertThat(criteriaCaptor.getValue().getFilterCriteria().getAssignedTo()).hasValue(ASSIGNED_TO);
+			}
+
+			@ParameterizedTest
+			@MethodSource("nachrichtenValues")
+			void shouldSetFilterByAssignedTo(String nachrichtenValue) {
+				doRequestWithNachrichtenParam(nachrichtenValue);
+
+				verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+				assertThat(criteriaCaptor.getValue().getFilterCriteria().isFilterByAssignedTo()).isTrue();
+			}
+
+			static List<String> nachrichtenValues() {
+				return List.of(VorgangController.PARAM_NACHRICHTEN_UNGELESENE, "", "dummy");
+			}
+
+			@Nested
+			class WithParamNachrichtenUngelesene {
+
+				@Test
+				void shouldCriteriaHaveHasUngeleseneNachrichtenTrue() {
+					doRequestWithNachrichtenParam(VorgangController.PARAM_NACHRICHTEN_UNGELESENE);
+
+					verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+					assertThat(criteriaCaptor.getValue().getFilterCriteria().isHasUngeleseneNachrichten()).isTrue();
+				}
+			}
+
+			@Nested
+			class WithoutParamNachrichtenUngelesene {
+
+				@ParameterizedTest
+				@ValueSource(strings = {"", "dummy"})
+				void shouldCriteriaHaveHasUngeleseneNachrichtenFalse(String nachrichtenValue) {
+					doRequestWithNachrichtenParam(nachrichtenValue);
+
+					verify(controller).handleGetAllRequest(criteriaCaptor.capture());
+					assertThat(criteriaCaptor.getValue().getFilterCriteria().isHasUngeleseneNachrichten()).isFalse();
+				}
+			}
+
+			@SneakyThrows
+			private void doRequestWithNachrichtenParam(String paramValue) {
+				mockMvc.perform(get(PATH)
+								.param(VorgangController.PARAM_PAGE, Integer.toString(PAGE))
+								.param(VorgangController.PARAM_LIMIT, Integer.toString(LIMIT))
+								.param(VorgangController.PARAM_ASSIGNED_TO, ASSIGNED_TO.toString())
+								.param(VorgangController.PARAM_NACHRICHTEN, paramValue))
+						.andExpect(status().isOk());
+			}
+		}
 	}
 
 	@DisplayName("As Optional")
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangRemoteServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangRemoteServiceTest.java
index c2c4eb8db070a11c9fecdc60473d9325d3e77745..be66261c6e40450b44a08d50d9f325ce6b2df18a 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangRemoteServiceTest.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangRemoteServiceTest.java
@@ -23,6 +23,7 @@
  */
 package de.ozgcloud.alfa.vorgang;
 
+import static de.ozgcloud.alfa.vorgang.VorgangRemoteService.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
@@ -39,9 +40,12 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.alfa.common.user.UserProfileTestFactory;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
 import de.ozgcloud.vorgang.vorgang.GrpcFilterBy;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangRequest;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangResponse;
+import de.ozgcloud.vorgang.vorgang.GrpcQuery;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression;
 import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub;
 
 class VorgangRemoteServiceTest {
@@ -59,6 +63,8 @@ class VorgangRemoteServiceTest {
 
 	private final GrpcFilterBy filterBy = GrpcFilterByTestFactory.create();
 
+	private final GrpcQuery query = GrpcQueryTestFactory.create();
+
 	@DisplayName("Find vorgaenge header")
 	@Nested
 	class TestFindVorgaengeHeader {
@@ -73,7 +79,8 @@ class VorgangRemoteServiceTest {
 
 			@BeforeEach
 			void initMockReturnValues() {
-				doReturn(filterBy).when(service).mapFilterCriteria(any());
+				doReturn(query).when(service).createQuery(any());
+				doReturn(filterBy).when(service).createFilterBy(any());
 				doReturn(VorgangListResponseTestFactory.create()).when(service).buildVorgaengeHeaderResponse(any());
 			}
 
@@ -84,11 +91,18 @@ class VorgangRemoteServiceTest {
 				verify(service).buildFindVorgangRequest(requestCriteria, filterCriteria);
 			}
 
+			@Test
+			void callCreateQuery() {
+				callService();
+
+				verify(service).createQuery(filterCriteria);
+			}
+
 			@Test
 			void callCreateFilterBy() {
 				callService();
 
-				verify(service).mapFilterCriteria(filterCriteria);
+				verify(service).createFilterBy(filterCriteria);
 			}
 
 			@Test
@@ -109,7 +123,8 @@ class VorgangRemoteServiceTest {
 
 			@BeforeEach
 			void initMockReturnValues() {
-				doReturn(filterBy).when(service).mapFilterCriteria(any());
+				doReturn(query).when(service).createQuery(any());
+				doReturn(filterBy).when(service).createFilterBy(any());
 			}
 
 			@Test
@@ -127,6 +142,13 @@ class VorgangRemoteServiceTest {
 						.isEqualTo(FindVorgaengeRequestCriteriaTestFactory.PAGE * FindVorgaengeRequestCriteriaTestFactory.LIMIT);
 			}
 
+			@Test
+			void shouldSetQuery() {
+				var request = callService();
+
+				assertThat(request.getQuery()).isEqualTo(query);
+			}
+
 			@Test
 			void shouldSetFilterBy() {
 				var request = callService();
@@ -186,13 +208,64 @@ class VorgangRemoteServiceTest {
 		}
 	}
 
+	@Nested
+	class TestCreateQuery {
+
+		@Nested
+		class WhenHasUngeleseneNachrichtenIsTrue {
+
+			private final FilterCriteria filterCriteria = FilterCriteriaTestFactory.createBuilder().hasUngeleseneNachrichten(true).build();
+
+			@Test
+			void shouldAddExpression() {
+				var query = service.createQuery(filterCriteria);
+
+				assertThat(query.getExpressionsList()).extracting(GrpcVorgangQueryExpression::getPath)
+						.containsOnlyOnce(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH);
+			}
+
+			@Test
+			void shouldHaveOperator() {
+				var expression = getExpression(service.createQuery(filterCriteria));
+
+				assertThat(expression.getOperator()).isEqualTo(GrpcQueryOperator.EQUAL);
+			}
+
+			@Test
+			void shouldHaveOperandBoolValue() {
+				var expression = getExpression(service.createQuery(filterCriteria));
+
+				assertThat(expression.getOperandBoolValue()).isTrue();
+			}
+
+			private GrpcVorgangQueryExpression getExpression(GrpcQuery query) {
+				return query.getExpressionsList().stream()
+						.filter(expression -> expression.getPath().equals(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH)).findFirst().orElseThrow();
+			}
+		}
+
+		@Nested
+		class WhenHasUngeleseneNachrichtenIsFalse {
+
+			private final FilterCriteria filterCriteria = FilterCriteriaTestFactory.createBuilder().hasUngeleseneNachrichten(false).build();
+
+			@Test
+			void shouldNotAddExpression() {
+				var query = service.createQuery(filterCriteria);
+
+				assertThat(query.getExpressionsList()).extracting(GrpcVorgangQueryExpression::getPath)
+						.isNotEqualTo(VORGAENGE_WITH_UNGELESENE_NACHRICHTEN_PATH);
+			}
+		}
+	}
+
 	@DisplayName("Create filterBy")
 	@Nested
 	class TestCreateFilterBy {
 
 		@Test
 		void shouldSetFilterByOrganisationsEinheitId() {
-			var filterCriteria = mapFilterCriteria();
+			var filterCriteria = createFilterBy();
 
 			assertThat(filterCriteria.getFilterByOrganisationseinheitenId())
 					.isEqualTo(FilterCriteriaTestFactory.FILTER_BY_ORGANISATIONS_EINHEITEN_ID);
@@ -200,7 +273,7 @@ class VorgangRemoteServiceTest {
 
 		@Test
 		void shouldSetOrganisationsEinheitIds() {
-			var filterCriteria = mapFilterCriteria();
+			var filterCriteria = createFilterBy();
 
 			assertThat(filterCriteria.getOrganisationseinheitIdList()).containsExactly(FilterCriteriaTestFactory.ORGANISATIONS_EINHEIT_ID);
 		}
@@ -211,7 +284,7 @@ class VorgangRemoteServiceTest {
 
 			@Test
 			void shouldBeSet() {
-				var filterCriteria = mapFilterCriteria();
+				var filterCriteria = createFilterBy();
 
 				assertThat(filterCriteria.getFilterByAssignedTo()).isTrue();
 			}
@@ -223,14 +296,14 @@ class VorgangRemoteServiceTest {
 
 			@Test
 			void shouldBeSetIfExists() {
-				var filterCriteria = mapFilterCriteria();
+				var filterCriteria = createFilterBy();
 
 				assertThat(filterCriteria.getAssignedTo()).isEqualTo(UserProfileTestFactory.ID.toString());
 			}
 
 			@Test
 			void shouldNotBeSetIfNotExist() {
-				var filterCriteria = mapFilterCriteria(FilterCriteriaTestFactory.createBuilder().assignedTo(Optional.empty()).build());
+				var filterCriteria = createFilterBy(FilterCriteriaTestFactory.createBuilder().assignedTo(Optional.empty()).build());
 
 				assertThat(filterCriteria.getAssignedTo()).isEqualTo(StringUtils.EMPTY);
 			}
@@ -242,14 +315,14 @@ class VorgangRemoteServiceTest {
 
 			@Test
 			void shouldBeSetIfExists() {
-				var filterCriteria = mapFilterCriteria();
+				var filterCriteria = createFilterBy();
 
 				assertThat(filterCriteria.getStatusList()).containsExactly(FilterCriteriaTestFactory.VORGANG_STATUS.toString());
 			}
 
 			@Test
 			void shouldNotBeSetIfNotExist() {
-				var filterCriteria = mapFilterCriteria(FilterCriteriaTestFactory.createBuilder().status(Optional.empty()).build());
+				var filterCriteria = createFilterBy(FilterCriteriaTestFactory.createBuilder().status(Optional.empty()).build());
 
 				assertThat(filterCriteria.getStatusCount()).isZero();
 
@@ -262,25 +335,25 @@ class VorgangRemoteServiceTest {
 
 			@Test
 			void shouldBeSetToFalse() {
-				var filterCriteria = mapFilterCriteria(FilterCriteriaTestFactory.createBuilder().hasNextWiedervorlageFrist(false).build());
+				var filterCriteria = createFilterBy(FilterCriteriaTestFactory.createBuilder().hasNextWiedervorlageFrist(false).build());
 
 				assertThat(filterCriteria.getHasNextWiedervorlageFrist()).isFalse();
 			}
 
 			@Test
 			void shouldNotBeSetToTrue() {
-				var filterCriteria = mapFilterCriteria(FilterCriteriaTestFactory.createBuilder().hasNextWiedervorlageFrist(true).build());
+				var filterCriteria = createFilterBy(FilterCriteriaTestFactory.createBuilder().hasNextWiedervorlageFrist(true).build());
 
 				assertThat(filterCriteria.getHasNextWiedervorlageFrist()).isTrue();
 			}
 		}
 
-		private GrpcFilterBy mapFilterCriteria() {
-			return mapFilterCriteria(FilterCriteriaTestFactory.create());
+		private GrpcFilterBy createFilterBy() {
+			return createFilterBy(FilterCriteriaTestFactory.create());
 		}
 
-		private GrpcFilterBy mapFilterCriteria(FilterCriteria filterCriteria) {
-			return service.mapFilterCriteria(filterCriteria);
+		private GrpcFilterBy createFilterBy(FilterCriteria filterCriteria) {
+			return service.createFilterBy(filterCriteria);
 		}
 	}
 
@@ -300,14 +373,14 @@ class VorgangRemoteServiceTest {
 				when(serviceStub.findVorgangWithEingang(any()))
 						.thenReturn(GrpcVorgangWithEingangResponseTestFactory.createVorgangWithEingangResponse());
 				when(vorgangWithEingangMapper.toVorgangWithEingang(any())).thenReturn(vorgangWithEingang);
-				doReturn(filterBy).when(service).mapFilterCriteria(any());
+				doReturn(filterBy).when(service).createFilterBy(any());
 			}
 
 			@Test
 			void shouldCreateFilterBy() {
 				callService();
 
-				verify(service).mapFilterCriteria(any());
+				verify(service).createFilterBy(any());
 			}
 
 			@Test
@@ -345,7 +418,7 @@ class VorgangRemoteServiceTest {
 
 			@BeforeEach
 			void mockReturnValue() {
-				doReturn(filterBy).when(service).mapFilterCriteria(any());
+				doReturn(filterBy).when(service).createFilterBy(any());
 			}
 
 			@Test
diff --git a/pom.xml b/pom.xml
index 4f00d84c16a1cc6f981d55ab11f3d1d05e2eb9fd..63d83b82f45e7cb960bc3f0d3382c29e7a999119 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-		<vorgang-manager.version>2.3.0</vorgang-manager.version>
+		<vorgang-manager.version>2.4.0-SNAPSHOT</vorgang-manager.version>
 		<ozgcloud-common-pdf.version>3.0.1</ozgcloud-common-pdf.version>
 		<user-manager.version>2.2.0</user-manager.version>