diff --git a/README.md b/README.md
index 9e2d81a9d779ab9b7ea0397ce5850415a1ea9998..16fe92f86e739dbcfc7ad5a9832351f1c36ad6e4 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,157 @@
 # OSIv2-Postfach-Anbindung für OZG-Cloud-Nachrichten
 
-Anbindung des OSIv2-Postfachs für die OZG-Cloud.
+Senden und Empfangen von Postfach-Nachrichten über die OSI-Postfach-Facade 2.0 (OPF).
 
+Das Maven-Artefakt `osiv2-postach` kann in ein Spring-Boot eingebunden werden.
+Die Spring-Bean `osiPostfachRemoteService` mit dem Interface
+`PostfachRemoteService` kann mit `ozgcloud.osiv2.enabled: true` aktiviert werden.
 
+## Konfiguration
+Um auf die Postfach-Facade zugreifen zu können, muss der Client sich beim Servicekonto anmelden.
+Hierzu wird `ozgcloud.osiv2.auth` konfiguriert, wie bspw. hier für Stage-Schleswig-Holstein:
+```yaml
+client-id: 'OZG-Kopfstelle-SH'
+client-secret: 'changeme'
+scope: default, access_urn:dataport:osi:sh:stage:ozgkopfstelle
+token-uri: 'https://idp.serviceportal-stage.schleswig-holstein.de/webidp2/connect/token'
+resource: 'urn:dataport:osi:postfach:rz2:stage:sh'
+```
+Für die Postfach-Facade muss zudem die URL, der Tenant, und der SAML-Name-Identifier konfiguriert werden.
+Beim Nachschlagen des Postfachs der Antragsteller*in wird ein Postfach mit übereinstimmenden Tenant präferiert.
+Zudem werden Tenant und SAML-Name-Identifier beim Upload von Anhängen angegeben.
+
+Hierzu wird `ozgcloud.osiv2.api` konfiguriert:
+```yaml
+url: 'https://api-gateway-stage.dataport.de:443/api/osi_postfach/1.0.0'
+tenant: 'SH'
+name-identifier: 'ozgkopfstelle'
+```
+<small>(Der Wert von `name-identifier` wird momentan nicht von der Postfach-Facade geprüft.)</small>
+
+## Senden einer Postfach-Nachricht
+Der Aufruf `sendMessage(PostfachNachricht)` sendet eine Nachricht an die Antragsteller*in. Jede Nachricht ist stets in Bezug zu einem Vorgang.
+
+1. Mit dem SAML-Name-Identifier der Antragsteller*in wird ein Postfach nachgeschlagen, welches die Nachricht empfangen soll.
+2. Vor dem Senden der Nachricht werden alle Anhänge in die Quarantäne hochgeladen und auf Viren geprüft.
+3. Nach dem erfolgreichen Hochladen der Anhänge wird die Nachricht an das Postfach gesendet.
+```mermaid
+%% Senden einer Nachricht
+  sequenceDiagram
+    participant N as nachrichten-manager
+    participant A as file-manager
+    participant B as Client
+    participant C as OPF
+    activate N
+    N->>B: OsiPostfachRemoteService::sendMessage
+    activate B
+    Note left of B: (1) Nachschlagen einer Empfänger-Postfach-Adresse
+    B->>C: POST /MailboxDirectory/v1/Lookup
+    activate C
+    C-->>B: {mailboxId}
+    deactivate C
+    Note left of B: (2) Hochladen der Anhänge
+    B->>A: GRPC findBinaryFilesMetaData
+    activate A
+    A-->>B: {Liste an Anhang-Metadaten}
+    deactivate A
+    loop Für jeden Anhang
+      B->>A: GRPC GetBinaryFileContent
+      activate A
+      loop Für jeden Daten-Chunk
+        B->>C: POST /Quarantine/v1/Upload/Chunked (chunk)
+        activate C
+        C-->>B: 
+        deactivate C
+      end
+      A-->>B: 
+      deactivate A
+      B->>C: POST /Quarantine/v1/Upload/Chunked (empty chunk)
+      activate C
+      C-->>B: 
+      deactivate C
+    end
+    loop Regelmäßiges Polling bis alle Anhänge geprüft sind
+      loop Für jeden Anhang
+        B->>C: GET /Quarantine/v1/Upload/{guid}
+        activate C
+        C-->>B: 
+        deactivate C
+      end
+    end
+    Note left of B: (3) Nachricht senden
+    B->>C: POST /MessageExchange/v1/Send/{mailboxId}
+    activate C
+    C-->>B: 
+    deactivate C
+    B-->>N: 
+    deactivate B
+    deactivate N
+```
+
+## Empfangen von Postfach-Nachrichten
+Der Aufruf `getAllMessages()` holt alle Nachrichten, die an das OZG-Cloud-Postfach gerichtet sind ab.
+
+1. Es wird eine Liste an Nachrichten-Kennungen abgerufen.
+2. Für jede Nachricht wird die Nachricht abgerufen und die Anhänge heruntergeladen.
+3. Ein Stream an Nachrichten wird zurückgegeben. Anhand der Vorgangs-Kennung lässt sich jede Nachricht stets einem Vorgang zugordnen.
+```mermaid
+%% Empfangen von Nachrichten
+  sequenceDiagram
+    participant N as nachrichten-manager
+    participant A as file-manager
+    participant B as Client
+    participant C as OPF
+    activate N
+    N->>B: OsiPostfachRemoteService::getAllMessages
+    activate B
+    B->>C: GET /MessageExchange/v1/Receive
+    activate C
+    C-->>B: {Liste an Nachrichten-Kennungen (max 100)}
+    deactivate C
+    loop Für jede Nachrichten-Kennung (messageId)
+      Note left of B: (1) Nachricht abrufen
+      B->>C: GET /MessageExchange/v1/Receive/{messageId}
+      activate C
+      C-->>B: {Nachricht mit Anhang-Metadaten}
+      deactivate C
+      Note left of B: (2) Herunterladen der Anhänge
+      loop Für jeden Anhang
+        B->>C: GET /MessageExchange/v1/Receive/{messageId}/Attachment/{attachmentId}
+        activate C
+        B->>A: GRPC UploadBinaryFileAsStream
+        activate A
+        A-->>B: 
+        deactivate A
+        C-->>B: 
+        deactivate C
+      end
+      Note left of B: (3) Bereitstellung der Postfach-Nachricht
+      B-->>N: {Postfach-Nachricht als Stream-Element}
+    end
+    deactivate B
+    deactivate N
+```
+
+Der nachrichten-manager erhält beim Aufruf von `getAllMessages` einen Stream von Postfach-Nachrichten. Nach der erfolgreichen Verarbeitung einer Nachricht sollte er `deleteMessage` aufrufen:
+
+```mermaid
+%% Empfangen einer Nachricht
+  sequenceDiagram
+    participant N as nachrichten-manager
+    participant B as Client
+    participant C as OPF
+    
+    activate N
+    N->>B: OsiPostfachRemoteService::deleteMessage
+    activate B
+    B->>C: GET /MessageExchange/v1/Delete/{messageId}
+    activate C
+    C->>B: 
+    deactivate C
+    B-->>N: 
+    deactivate B
+    deactivate N
+```
 
 ## Client-Authentifizierung beim Servicekonto
 
@@ -17,7 +166,7 @@ Der Resource-Server liest die Resource-URI aus dem `aud`-Claim (siehe [RFC 9068,
 curl -v --output auth_response.json \
      -H "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode "grant_type=client_credentials" \
-     --data-urlencode "client_id=OZG-Kopfstelle" \
+     --data-urlencode "client_id=OZG-Kopfstelle-SH" \
      --data-urlencode "client_secret=${SH_STAGE_CLIENT_SECRET}" \
      --data-urlencode "scope=default access_urn:dataport:osi:sh:stage:ozgkopfstelle" \
      --data-urlencode "resource=urn:dataport:osi:postfach:rz2:stage:sh" \
diff --git a/spec/postfach-api-facade.yaml b/spec/postfach-api-facade.yaml
index 9a67d1cbd7ec9a71af0f96dfbc0512d6a5abd6aa..d494dbb4bf978d68832eb6b2b1eae40eac4677fc 100644
--- a/spec/postfach-api-facade.yaml
+++ b/spec/postfach-api-facade.yaml
@@ -756,6 +756,7 @@ paths:
                 detail: Der Dienst ist zurzeit nicht verfügbar.
   /MailboxDirectory/v1/Lookup:
     post:
+      operationId: lookupMailboxIds
       tags:
       - MailboxDirectory
       summary: Liefert eine Liste der zu NameIdentifiern gehörenden OSI-Postfächer
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java
index 6b28b57315c3cce2c26f9e88c6275fafe3f989a4..50496cab096aca2ec5c3bc87bb0f9bd128df3de9 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java
@@ -29,6 +29,7 @@ import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestClient;
 
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.ApiClient;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MailboxDirectoryApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.QuarantineApi;
 import lombok.RequiredArgsConstructor;
@@ -57,6 +58,11 @@ public class ApiClientConfiguration {
 		return new QuarantineApi(apiClient);
 	}
 
+	@Bean
+	MailboxDirectoryApi mailboxDirectoryApi(ApiClient apiClient) {
+		return new MailboxDirectoryApi(apiClient);
+	}
+
 	@Bean
 	@SneakyThrows
 	ApiClient apiClient() {
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandler.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandler.java
index 395f4272265f5695cb06f9a0cd91ae9ddc396949..f7e42d6e24bdab325a7cfe25083c5f0e3895aebc 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandler.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandler.java
@@ -19,6 +19,9 @@ public class Osi2ExceptionHandler {
 		if (exception instanceof ResourceAccessException) {
 			return PostfachMessageCode.SERVER_CONNECTION_FAILED_MESSAGE_CODE;
 		}
+		if (exception instanceof Osi2MailboxNotFoundException) {
+			return PostfachMessageCode.SEND_FAILED_UNKNOWN_POSTFACH_ID_MESSAGE_CODE;
+		}
 		return PostfachMessageCode.PROCESS_FAILED_MESSAGE_CODE;
 	}
 
@@ -33,5 +36,4 @@ public class Osi2ExceptionHandler {
 		return restClientResponseException.getStatusCode().isSameCodeAs(HttpStatusCode.valueOf(404));
 	}
 
-
 }
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2MailboxNotFoundException.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2MailboxNotFoundException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a44f277641c52bb6a77aef30a26f073ba710f81
--- /dev/null
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2MailboxNotFoundException.java
@@ -0,0 +1,7 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.exception;
+
+public class Osi2MailboxNotFoundException extends Osi2RuntimeException {
+	public Osi2MailboxNotFoundException(String message) {
+		super(message);
+	}
+}
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/FileChunkInfo.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/FileChunkInfo.java
index a119cbaf62538ee51a8f5c30e680936a06d207f8..f63abe3450e3864847791d12e6e6e85e6a754197 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/FileChunkInfo.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/FileChunkInfo.java
@@ -16,6 +16,12 @@ public record FileChunkInfo(
 ) {
 	public AbstractResource createUploadResource(InputStream fileInputStream) {
 		return new AbstractResource() {
+
+			@Override
+			public String getFilename() {
+				return upload.file().getName();
+			}
+
 			@Override
 			public String getDescription() {
 				return "File chunk " + chunkIndex + " of " + upload.getLoggableString();
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Attachment.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Attachment.java
index dc41ec7685a33e83990ce954b9097e523dfe57cc..a948a1a1017236c3fba12508d4bcafb242287105 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Attachment.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Attachment.java
@@ -10,7 +10,7 @@ public record Osi2Attachment(
 		String guid,
 		OzgCloudFile file
 ) {
-	public static final long CHUNK_SIZE = 100L * (2L << 10);
+	public static final long CHUNK_SIZE = (2L << 14);
 
 	public static Osi2Attachment from(OzgCloudFile file) {
 		return Osi2Attachment.builder()
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Message.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Message.java
index f527fceac71309d1bc39f427e1e8e08f367ce89c..ecda0e2648b2ae43cd56cd39013013181a6eedc6 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Message.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/model/Osi2Message.java
@@ -3,14 +3,13 @@ package de.ozgcloud.nachrichten.postfach.osiv2.model;
 import java.time.ZonedDateTime;
 import java.util.List;
 
-import de.ozgcloud.nachrichten.postfach.PostfachAddress;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import lombok.Builder;
 
 @Builder
 public record Osi2Message(
 		String vorgangId,
-		PostfachAddress postfachAddress,
+		String mailboxId,
 		String messageId,
 		ZonedDateTime createdAt,
 		String subject,
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapper.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapper.java
index 7d81f6f6a4a39d30952f08314ce8204ea72d6562..006fe52f3c5822efa48000eacc88887c209ab735 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapper.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapper.java
@@ -1,16 +1,31 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
+import org.mapstruct.Named;
 import org.mapstruct.ReportingPolicy;
 
+import de.ozgcloud.nachrichten.postfach.PostfachAddress;
+import de.ozgcloud.nachrichten.postfach.PostfachAddressIdentifier;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+import de.ozgcloud.nachrichten.postfach.StringBasedIdentifier;
+import de.ozgcloud.nachrichten.postfach.osiv2.OsiPostfachRemoteService;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.AttachmentInfo;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 
 @Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
 public interface Osi2MessageMapper {
+	String POSTFACH_ADDRESS_VERSION = "2.0";
+	int POSTFACH_ADDRESS_TYPE = 2;
+
 	@Mapping(target = "id", ignore = true)
 	@Mapping(target = "referencedNachricht", ignore = true)
 
@@ -20,7 +35,57 @@ public interface Osi2MessageMapper {
 	@Mapping(target = "sentSuccessful", ignore = true)
 	@Mapping(target = "messageCode", ignore = true)
 
+	@Mapping(target = "postfachAddress", source = "osi2Message.mailboxId", qualifiedByName = "createPostfachAddressByMailboxId")
 	@Mapping(target = "attachments", source = "attachmentIds")
 	@Mapping(target = "direction", constant = "IN")
-	PostfachNachricht toPostfachNachricht(Osi2Message osi2Message, List<String> attachmentIds);
+	PostfachNachricht mapPostfachNachricht(Osi2Message osi2Message, List<String> attachmentIds);
+
+	@Named("createPostfachAddressByMailboxId")
+	default PostfachAddress createPostfachAddressByMailboxId(String mailBoxId) {
+		return PostfachAddress.builder()
+				.type(POSTFACH_ADDRESS_TYPE)
+				.version(POSTFACH_ADDRESS_VERSION)
+				.identifier(StringBasedIdentifier.builder()
+						// Note: this should be a nameIdentifier for sending but is a mailboxGuid/messageBox.
+						// Thus, the PostfachAddress in this mapped response can not be used for sending
+						.postfachId(mailBoxId)
+						.build())
+				.serviceKontoType(OsiPostfachRemoteService.POSTFACH_TYPE_OSI)
+				.build();
+
+	}
+
+	default String getNameIdentifier(PostfachNachricht nachricht) {
+		return Optional.ofNullable(nachricht.getPostfachAddress())
+				.map(PostfachAddress::getIdentifier)
+				.map(PostfachAddressIdentifier::getStringRepresentation)
+				.orElseThrow(() -> new IllegalArgumentException("Missing nameIdentifier!"));
+	}
+
+	@Mapping(target = "mailboxId", source = "mailboxId")
+	@Mapping(target = "attachments", expression = "java( mapAttachmentInfosInOriginalOrder(nachricht, uploadAttachments) )")
+	Osi2Message mapOsi2Message(PostfachNachricht nachricht, String mailboxId, List<Osi2Attachment> uploadAttachments);
+
+	default List<AttachmentInfo> mapAttachmentInfosInOriginalOrder(PostfachNachricht nachricht, List<Osi2Attachment> files) {
+		var filesById = associateUploadWithAttachmentId(files);
+		return nachricht.getAttachments()
+				.stream()
+				.map(fileId -> Objects.requireNonNull(
+						filesById.get(fileId),
+						"Expect all attachmentIds are uploaded!"
+				))
+				.map(this::mapAttachmentInfo)
+				.toList();
+	}
+
+	@Mapping(target = "contentType", source = "file.contentType")
+	@Mapping(target = "name", source = "file.name")
+	@Mapping(target = "size", source = "file.size")
+	AttachmentInfo mapAttachmentInfo(Osi2Attachment file);
+
+	default Map<String, Osi2Attachment> associateUploadWithAttachmentId(List<Osi2Attachment> uploads) {
+		return uploads.stream()
+				.filter(upload -> upload.file() != null && upload.file().getId() != null)
+				.collect(Collectors.toMap(upload -> upload.file().getId().toString(), Function.identity()));
+	}
 }
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachService.java
index 754a9458fcf09d45e7ea55bd5c18e574b10de913..dc08ac22f05c51102d7dff14801fe153527faa30 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachService.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachService.java
@@ -19,8 +19,11 @@ public class Osi2PostfachService {
 
 	public void sendMessage(PostfachNachricht nachricht) {
 		postfachApiFacadeService.sendMessage(
-				nachricht,
-				quarantineService.uploadAttachments(nachricht.getAttachments())
+				messageMapper.mapOsi2Message(
+						nachricht,
+						postfachApiFacadeService.lookupMailboxId(messageMapper.getNameIdentifier(nachricht)),
+						quarantineService.uploadAttachments(nachricht.getAttachments())
+				)
 		);
 	}
 
@@ -32,7 +35,7 @@ public class Osi2PostfachService {
 
 	PostfachNachricht fetchPostfachNachricht(String messageGuid) {
 		var message = postfachApiFacadeService.fetchMessageById(messageGuid);
-		return messageMapper.toPostfachNachricht(
+		return messageMapper.mapPostfachNachricht(
 				message,
 				persistAttachmentService.persistAttachments(message)
 		);
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapper.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapper.java
index 86aa86d13ffd80d919a5f4c8b92ae31c4d39bf22..de83be90b0db68e0949dec8abfbad538ed9cfcee 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapper.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapper.java
@@ -2,67 +2,43 @@ package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
+import org.mapstruct.Named;
 import org.mapstruct.ReportingPolicy;
 
-import de.ozgcloud.nachrichten.postfach.PostfachAddress;
-import de.ozgcloud.nachrichten.postfach.PostfachAddressIdentifier;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.DomainChunkMetaData;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeFiles;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1References;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.AttachmentInfo;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
-import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 
 @Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
 public interface Osi2RequestMapper {
 
 	int MAX_NUMBER_RECEIVED_MESSAGES = 100;
 
-	@Mapping(target = "sequencenumber", source = "nachricht.vorgangId")
-	@Mapping(target = "body", source = "nachricht.mailBody")
+	@Mapping(target = "sequencenumber", source = "vorgangId")
+	@Mapping(target = "body", source = "mailBody")
 	@Mapping(target = "displayName", ignore = true)
 	@Mapping(target = "originSender", ignore = true)
-	@Mapping(target = "replyAction", source = "nachricht.replyOption")
+	@Mapping(target = "replyAction", source = "replyOption")
 	@Mapping(target = "eidasLevel", constant = "LOW")
 	@Mapping(target = "isObligatory", expression = "java( false )")
 	@Mapping(target = "isHtml", expression = "java( false )")
-	@Mapping(target = "files", expression = "java( mapMessageExchangeFiles(nachricht, files) )")
+	@Mapping(target = "files", source = "attachments", qualifiedByName = "mapMessageExchangeFile")
 	@Mapping(target = "references", expression = "java( mapReferences() )")
-	OutSendMessageRequestV2 mapOutSendMessageRequestV2(PostfachNachricht nachricht, List<Osi2Attachment> files);
+	OutSendMessageRequestV2 mapOutSendMessageRequestV2(Osi2Message message);
 
-	default List<MessageExchangeFiles> mapMessageExchangeFiles(PostfachNachricht nachricht, List<Osi2Attachment> files) {
-		var filesById = associateUploadWithAttachmentId(files);
-		return nachricht.getAttachments()
-				.stream()
-				.map(fileId -> Objects.requireNonNull(
-						filesById.get(fileId),
-						"Expect all attachmentIds are uploaded!"
-				))
-				.map(this::mapMessageExchangeFile)
-				.toList();
-	}
-
-	default Map<String, Osi2Attachment> associateUploadWithAttachmentId(List<Osi2Attachment> uploads) {
-		return uploads.stream()
-				.filter(upload -> upload.file() != null && upload.file().getId() != null)
-				.collect(Collectors.toMap(upload -> upload.file().getId().toString(), Function.identity()));
-	}
-
-	@Mapping(target = "mimeType", source = "file.contentType")
-	@Mapping(target = "name", source = "file.name")
-	@Mapping(target = "size", source = "file.size")
+	@Mapping(target = "mimeType", source = "contentType")
 	@Mapping(target = "isOriginalMessage", expression = "java( false )")
-	MessageExchangeFiles mapMessageExchangeFile(Osi2Attachment fileUpload);
+	@Named("mapMessageExchangeFile")
+	MessageExchangeFiles mapMessageExchangeFile(AttachmentInfo fileUpload);
 
 	default List<V1References> mapReferences() {
 		return Collections.emptyList();
@@ -83,12 +59,4 @@ public interface Osi2RequestMapper {
 	@Mapping(target = "totalChunks", expression = "java( (int) fileChunkInfo.upload().numberOfChunks() )")
 	@Mapping(target = "totalFileSize", source = "upload.file.size")
 	DomainChunkMetaData mapDomainChunkMetaData(FileChunkInfo fileChunkInfo);
-
-	default String mapMailboxId(PostfachNachricht nachricht) {
-		return Optional.ofNullable(nachricht.getPostfachAddress())
-				.map(PostfachAddress::getIdentifier)
-				.map(PostfachAddressIdentifier::getStringRepresentation)
-				.orElseThrow(() -> new IllegalArgumentException("Missing MailboxId!"));
-	}
-
 }
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapper.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapper.java
index 74a34e0487b9e48ef2ee046d8a5f1ac707778fe6..a1ab4aa8615a72f161ae9418cb4f90c892a03936 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapper.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapper.java
@@ -7,23 +7,26 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
+import java.util.stream.Stream;
+
+import jakarta.validation.constraints.NotNull;
 
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Named;
 import org.mapstruct.ReportingPolicy;
 
-import de.ozgcloud.nachrichten.postfach.PostfachAddress;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
-import de.ozgcloud.nachrichten.postfach.StringBasedIdentifier;
-import de.ozgcloud.nachrichten.postfach.osiv2.OsiPostfachRemoteService;
+import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2MailboxNotFoundException;
 import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2RuntimeException;
 import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2UploadException;
-import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveAttachment;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.DTOMailboxScopeData;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MddiMailboxIndexData;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessage;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessagesResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.QuarantineFileResult;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.QuarantineStatus;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.ResponsesMailboxDirectoryResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyFiles;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage;
@@ -33,11 +36,8 @@ import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 @Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, imports = { Osi2HtmlDocument.class })
 public interface Osi2ResponseMapper {
 
-	String POSTFACH_ADDRESS_VERSION = "2.0";
-	int POSTFACH_ADDRESS_TYPE = 2;
-
 	@Mapping(target = "vorgangId", source = "sequencenumber")
-	@Mapping(target = "postfachAddress", source = "messageBox")
+	@Mapping(target = "mailboxId", source = "messageBox")
 	@Mapping(target = "messageId", source = "guid")
 	@Mapping(target = "createdAt", source = "responseTime", qualifiedByName = "mapOffsetDateTimeToZoned")
 	@Mapping(target = "subject", source = "subject")
@@ -66,20 +66,6 @@ public interface Osi2ResponseMapper {
 				: body;
 	}
 
-	default PostfachAddress buildPostfachAddressByPostfachId(UUID messageBox) {
-		return messageBox == null
-				? null
-				: PostfachAddress.builder()
-						.type(POSTFACH_ADDRESS_TYPE)
-						.version(POSTFACH_ADDRESS_VERSION)
-						.identifier(StringBasedIdentifier.builder()
-								.postfachId(messageBox.toString())
-								.build())
-						.serviceKontoType(OsiPostfachRemoteService.POSTFACH_TYPE_OSI)
-						.build();
-
-	}
-
 	default PostfachNachricht.ReplyOption mapReplyAction(V1ReplyBehavior replyOption) {
 		return replyOption == null
 				? PostfachNachricht.ReplyOption.FORBIDDEN
@@ -113,18 +99,29 @@ public interface Osi2ResponseMapper {
 	}
 
 	default void checkChunkUploadSuccess(QuarantineFileResult quarantineFileResult) {
-		if (!Boolean.TRUE.equals(quarantineFileResult.getSuccess())) {
+		if (!Optional.ofNullable(quarantineFileResult.getError()).map(String::isBlank).orElse(true)) {
 			throw new Osi2RuntimeException(
 					"Chunk-Upload of file %s failed: %s".formatted(quarantineFileResult.getFileUid(), quarantineFileResult.getError()), null);
 		}
 	}
 
-	@Named("mapMessageExchangeReceiveAttachment")
-	default String mapMessageExchangeReceiveAttachment(MessageExchangeReceiveAttachment attachment) {
-		return Optional.ofNullable(attachment)
-				.map(MessageExchangeReceiveAttachment::getGuid)
-				.map(UUID::toString)
-				.orElse(null);
+	default Optional<String> extractMailboxIdByTenantOrFirst(@NotNull List<MddiMailboxIndexData> mailBoxes, String tenant) {
+		return mailBoxes.stream()
+				.filter(mailbox -> tenant.equals(mailbox.getTenant()))
+				.findFirst()
+				.or(() -> mailBoxes.stream().findFirst())
+				.map(MddiMailboxIndexData::getMailboxguid)
+				.map(UUID::toString);
 	}
 
+	default String getMailboxIdByTenantOrFirst(ResponsesMailboxDirectoryResponse responsesMailboxDirectoryResponse, String tenant) {
+		return Optional.ofNullable(responsesMailboxDirectoryResponse)
+				.map(ResponsesMailboxDirectoryResponse::getMailBoxIndex)
+				.map(Collection::stream)
+				.flatMap(Stream::findFirst)
+				.map(DTOMailboxScopeData::getMemberscope)
+				.flatMap(mailBoxes -> extractMailboxIdByTenantOrFirst(mailBoxes, tenant))
+				.orElseThrow(() -> new Osi2MailboxNotFoundException("Empty mailbox lookup response! %s".formatted(
+						responsesMailboxDirectoryResponse != null ? responsesMailboxDirectoryResponse.toString() : "(response null)")));
+	}
 }
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
index 989ae00cba9f3caa4f564fc9ac37b77e323a6efa..65010e59039cc40e20e6cd08adde2f0897651fa4 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
@@ -8,14 +8,13 @@ import java.util.UUID;
 import org.springframework.core.io.AbstractResource;
 import org.springframework.core.io.Resource;
 
-import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.ServiceIfOsi2Enabled;
 import de.ozgcloud.nachrichten.postfach.osiv2.config.Osi2PostfachProperties;
 import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2UploadException;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MailboxDirectoryApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.QuarantineApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
-import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
@@ -27,14 +26,15 @@ public class PostfachApiFacadeService {
 
 	private final MessageExchangeApi messageExchangeApi;
 	private final QuarantineApi quarantineApi;
+	private final MailboxDirectoryApi mailboxDirectoryApi;
 	private final Osi2RequestMapper requestMapper;
 	private final Osi2ResponseMapper responseMapper;
 	private final Osi2PostfachProperties.ApiConfiguration apiConfiguration;
 
-	public void sendMessage(PostfachNachricht nachricht, List<Osi2Attachment> attachments) {
+	public void sendMessage(Osi2Message message) {
 		messageExchangeApi.sendMessage(
-				requestMapper.mapMailboxId(nachricht),
-				requestMapper.mapOutSendMessageRequestV2(nachricht, attachments)
+				message.mailboxId(),
+				requestMapper.mapOutSendMessageRequestV2(message)
 		);
 	}
 
@@ -75,4 +75,11 @@ public class PostfachApiFacadeService {
 	public Resource downloadAttachment(String messageGuid, String attachmentGuid) {
 		return messageExchangeApi.getMessageAttachment(UUID.fromString(messageGuid), UUID.fromString(attachmentGuid));
 	}
+
+	public String lookupMailboxId(String nameIdentifier) {
+		return responseMapper.getMailboxIdByTenantOrFirst(
+				mailboxDirectoryApi.lookupMailboxIds(List.of(UUID.fromString(nameIdentifier))),
+				apiConfiguration.getTenant()
+		);
+	}
 }
diff --git a/src/main/resources/application-stage.yml b/src/main/resources/application-stage.yml
index 2618fc516f3b8383f3ad2d4ddfccb4c8c06eeccb..e69cb9d817c200ebe67b7f5827fac3826e273cf0 100644
--- a/src/main/resources/application-stage.yml
+++ b/src/main/resources/application-stage.yml
@@ -2,7 +2,7 @@ ozgcloud:
   osiv2:
     enabled: false
     auth:
-      client-id: 'OZG-Kopfstelle'
+      client-id: 'OZG-Kopfstelle-SH'
       client-secret: 'changeme'
       scope: default, access_urn:dataport:osi:sh:stage:ozgkopfstelle
       token-uri: 'https://idp.serviceportal-stage.schleswig-holstein.de/webidp2/connect/token'
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java
index 550d15b32897a7017dd46e2954b9d11379249078..51dd44b370569b53609c2fbd4b558466e40c76ef 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java
@@ -35,6 +35,7 @@ import de.ozgcloud.nachrichten.postfach.osiv2.factory.JsonUtil;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.MessageExchangeReceiveMessagesResponseTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.MessageExchangeSendMessageResponseTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.ResponsesMailboxDirectoryResponseTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyFilesTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.QuarantineFileResult;
@@ -83,6 +84,7 @@ class OsiPostfachRemoteServiceITCase {
 	@SneakyThrows
 	void shouldSendRequestWithJwt() {
 		var postfachNachricht = PostfachNachrichtTestFactory.create();
+		mockLookupResponse();
 		mockSendResponse();
 
 		osiPostfachRemoteService.sendMessage(postfachNachricht);
@@ -110,6 +112,7 @@ class OsiPostfachRemoteServiceITCase {
 		var postfachNachrichtWithAttachment = PostfachNachrichtTestFactory.createBuilder()
 				.attachments(List.of(textFileId))
 				.build();
+		mockLookupResponse();
 		mockSendResponse();
 
 		osiPostfachRemoteService.sendMessage(postfachNachrichtWithAttachment);
@@ -130,6 +133,10 @@ class OsiPostfachRemoteServiceITCase {
 				exactly(1),
 				postRequestedFor(urlPathTemplate("/MessageExchange/v1/Send/{mailboxId}"))
 		);
+		postfachFacadeMockServer.verify(
+				exactly(1),
+				postRequestedFor(urlPathTemplate("/MailboxDirectory/v1/Lookup"))
+		);
 	}
 
 	@DisplayName("should throw postfach exception with connection error code")
@@ -173,6 +180,7 @@ class OsiPostfachRemoteServiceITCase {
 		var postfachNachrichtWithAttachment = PostfachNachrichtTestFactory.createBuilder()
 				.attachments(List.of(textFileId))
 				.build();
+		mockLookupResponse();
 
 		try {
 			osiPostfachRemoteService.sendMessage(postfachNachrichtWithAttachment);
@@ -204,6 +212,7 @@ class OsiPostfachRemoteServiceITCase {
 		var postfachNachrichtWithAttachment = PostfachNachrichtTestFactory.createBuilder()
 				.attachments(List.of(textFileId))
 				.build();
+		mockLookupResponse();
 
 		try {
 			osiPostfachRemoteService.sendMessage(postfachNachrichtWithAttachment);
@@ -217,6 +226,17 @@ class OsiPostfachRemoteServiceITCase {
 		);
 	}
 
+	private void mockLookupResponse() {
+		// Stub mailboxids lookup response (MessageExchangeApi::lookupMailboxIds)
+		postfachFacadeMockServer.stubFor(post(urlPathTemplate("/MailboxDirectory/v1/Lookup"))
+				.willReturn(
+						okJsonObj(
+								ResponsesMailboxDirectoryResponseTestFactory.create()
+						)
+				)
+		);
+	}
+
 	private void mockSendResponse() {
 		// Stub message send response (MessageExchangeApi::sendMessage)
 		postfachFacadeMockServer.stubFor(post(urlPathTemplate("/MessageExchange/v1/Send/{mailboxId}"))
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/attachment/Osi2PersistAttachmentServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/attachment/Osi2PersistAttachmentServiceTest.java
index 2fcf40037503cf91d20e4ce5206c5c0518e6d72d..92b590f0a2727c7a7cb7890d245ae73d7e76b091 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/attachment/Osi2PersistAttachmentServiceTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/attachment/Osi2PersistAttachmentServiceTest.java
@@ -3,7 +3,6 @@ package de.ozgcloud.nachrichten.postfach.osiv2.attachment;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.GrpcOzgFileTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory.*;
-import static de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandlerTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandlerTest.java
index df51704620bc574bcbf1c1f01c4c5ff7786ab3fc..986571b9fe186418e8cd85d879d044209cfe72d1 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandlerTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/exception/Osi2ExceptionHandlerTest.java
@@ -11,6 +11,7 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 import org.springframework.http.HttpStatusCode;
+import org.springframework.web.client.ResourceAccessException;
 import org.springframework.web.client.RestClientResponseException;
 
 class Osi2ExceptionHandlerTest {
@@ -36,6 +37,22 @@ class Osi2ExceptionHandlerTest {
 			assertThat(result).isEqualTo(SERVER_CONNECTION_FAILED_MESSAGE_CODE);
 		}
 
+		@DisplayName("should return connection failed message code")
+		@Test
+		void shouldReturnConnectionFailedMessageCode() {
+			var result = handler.deriveMessageCode(new ResourceAccessException(""));
+
+			assertThat(result).isEqualTo(SERVER_CONNECTION_FAILED_MESSAGE_CODE);
+		}
+
+		@DisplayName("should return unknown postfach id message code")
+		@Test
+		void shouldReturnUnknownPostfachIdMessageCode() {
+			var result = handler.deriveMessageCode(new Osi2MailboxNotFoundException(""));
+
+			assertThat(result).isEqualTo(SEND_FAILED_UNKNOWN_POSTFACH_ID_MESSAGE_CODE);
+		}
+
 		@DisplayName("should return processed failed error code by default")
 		@Test
 		void shouldReturnProcessedFailedErrorCodeByDefault() {
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/extension/AttachmentExampleUploadUtil.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/extension/AttachmentExampleUploadUtil.java
index 8aa54916936532edcdc288378702867186469fe6..97cc84d99b4783bb08df5d933bc7fb171ac28c58 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/extension/AttachmentExampleUploadUtil.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/extension/AttachmentExampleUploadUtil.java
@@ -12,7 +12,7 @@ import lombok.extern.log4j.Log4j2;
 @Log4j2
 public class AttachmentExampleUploadUtil {
 
-	public static final byte[] EXAMPLE_TEXT_DATA = LoremIpsum.getInstance().getParagraphs(5,100).getBytes();
+	public static final byte[] EXAMPLE_TEXT_DATA = LoremIpsum.getInstance().getParagraphs(5,10).getBytes();
 
 	public static String uploadTextFile(Osi2AttachmentFileService remoteService) {
 
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2AttachmentTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2AttachmentTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..662d3d3e0de6c38b10e7f134b3ba30263b1ca47e
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2AttachmentTestFactory.java
@@ -0,0 +1,21 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.factory;
+
+import java.util.UUID;
+
+import de.ozgcloud.apilib.file.OzgCloudFileTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
+
+public class Osi2AttachmentTestFactory {
+	public static final String ATTACHMENT_GUID = UUID.randomUUID().toString();
+	public static final String ATTACHMENT_GUID_2 = UUID.randomUUID().toString();
+
+	public static Osi2Attachment create() {
+		return createBuilder().build();
+	}
+
+	public static Osi2Attachment.Osi2AttachmentBuilder createBuilder() {
+		return Osi2Attachment.builder()
+				.guid(ATTACHMENT_GUID)
+				.file(OzgCloudFileTestFactory.create());
+	}
+}
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2MessageTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2MessageTestFactory.java
index 8d40f117e113c3c070288228e011c27c3ead4500..b609152b4840b7533ede5c574ee7b0b3de10ac45 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2MessageTestFactory.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/Osi2MessageTestFactory.java
@@ -1,29 +1,31 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.factory;
 
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory.*;
-import static de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageTestFactory.*;
 
 import java.time.ZonedDateTime;
 import java.util.List;
+import java.util.UUID;
 
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 
 public class Osi2MessageTestFactory {
 
+	public static final String MAILBOX_ID = UUID.randomUUID().toString();
+
 	public static Osi2Message create() {
 		return createBuilder().build();
 	}
 
 	public static Osi2Message.Osi2MessageBuilder createBuilder() {
 		return Osi2Message.builder()
+				.vorgangId(VORGANG_ID)
+				.mailboxId(MAILBOX_ID)
 				.messageId(MESSAGE_ID)
 				.mailBody(MAIL_BODY)
 				.subject(MAIL_SUBJECT)
 				.replyOption(PostfachNachricht.ReplyOption.FORBIDDEN)
 				.createdAt(ZonedDateTime.now())
-				.vorgangId(VORGANG_ID)
-				.attachments(List.of())
-				.postfachAddress(PostfachAddressTestFactory.create());
+				.attachments(List.of());
 	}
 }
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java
index de986e02f39c9781e3af9be92741d4d0b64994de..415054d28d7d399f271c100bf16f2b54d1861339 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java
@@ -7,7 +7,7 @@ import de.ozgcloud.nachrichten.postfach.StringBasedIdentifier;
 
 public class PostfachAddressTestFactory {
 
-	public static final String MAILBOX_ID = UUID.randomUUID().toString();
+	public static final String NAME_IDENTIFIER = UUID.randomUUID().toString();
 	public static final String SERVICE_KONTO_TYPE = "TYPE1";
 
 	public static PostfachAddress create() {
@@ -19,7 +19,7 @@ public class PostfachAddressTestFactory {
 				.type(1)
 				.serviceKontoType(SERVICE_KONTO_TYPE)
 				.identifier(StringBasedIdentifier.builder()
-						.postfachId(MAILBOX_ID)
+						.postfachId(NAME_IDENTIFIER)
 						.build());
 	}
 }
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java
index aaf929ea7d99c7b3262df9458295e8bc7c647e90..3424251bc054764b96b6fbf49454806974b923f2 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java
@@ -12,7 +12,9 @@ public class PostfachNachrichtTestFactory {
 	public static final String MAIL_SUBJECT = "AW: " + LoremIpsum.getInstance().getTitle(2, 6);
 	public static final String VORGANG_ID = "test-vorgang-id";
 	public static final String USER_ID = "test-user-id";
-
+	public static final String MESSAGE_ID = UUID.randomUUID().toString();
+	public static final ZonedDateTime CREATED_AT = ZonedDateTime.now();
+	public static final PostfachNachricht.ReplyOption REPLY_OPTION = PostfachNachricht.ReplyOption.FORBIDDEN;
 
 	public static PostfachNachricht create() {
 		return createBuilder().build();
@@ -22,8 +24,9 @@ public class PostfachNachrichtTestFactory {
 		return PostfachNachricht.builder()
 				.mailBody(MAIL_BODY)
 				.subject(MAIL_SUBJECT)
-				.replyOption(PostfachNachricht.ReplyOption.FORBIDDEN)
-				.createdAt(ZonedDateTime.now())
+				.messageId(MESSAGE_ID)
+				.replyOption(REPLY_OPTION)
+				.createdAt(CREATED_AT)
 				.createdBy(USER_ID)
 				.vorgangId(VORGANG_ID)
 				.postfachAddress(PostfachAddressTestFactory.create());
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/ResponsesMailboxDirectoryResponseTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/ResponsesMailboxDirectoryResponseTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..9681f8d86be37e8d7766f77ba287649cc07ba264
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/ResponsesMailboxDirectoryResponseTestFactory.java
@@ -0,0 +1,56 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.factory;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.DTOMailboxScopeData;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MddiMailboxIndexData;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MddiMailboxType;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.ResponsesMailboxDirectoryResponse;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1Meta;
+
+public class ResponsesMailboxDirectoryResponseTestFactory {
+
+	public static final String NAME_ID = UUID.randomUUID().toString();
+	public static final String MAILBOX_GUID_SH = UUID.randomUUID().toString();
+	public static final String MAILBOX_GUID_HH = UUID.randomUUID().toString();
+	public static final String TENANT_SH = "SH";
+	public static final String TENANT_HH = "HH";
+
+	public static ResponsesMailboxDirectoryResponse create() {
+		return createBuilder(
+				buildMailboxWithSHTenant().build(),
+				buildMailboxWithHHTenant().build()
+		).build();
+	}
+
+	public static ResponsesMailboxDirectoryResponse.Builder createBuilder(MddiMailboxIndexData... mailBoxes) {
+		return ResponsesMailboxDirectoryResponse.builder()
+				.mailBoxIndex(List.of(createScopeData(mailBoxes)))
+				.meta(V1Meta.builder().build());
+	}
+
+	public static MddiMailboxIndexData.Builder buildMailboxWithSHTenant() {
+		return MddiMailboxIndexData.builder()
+				.mailboxguid(UUID.fromString(MAILBOX_GUID_SH))
+				.tenant(TENANT_SH)
+				.mailboxname("")
+				.mailboxdescription("")
+				.mailboxtype(MddiMailboxType.PERSONAL);
+	}
+
+	public static MddiMailboxIndexData.Builder buildMailboxWithHHTenant() {
+		return MddiMailboxIndexData.builder()
+				.mailboxguid(UUID.fromString(MAILBOX_GUID_HH))
+				.tenant(TENANT_HH)
+				.mailboxtype(MddiMailboxType.PERSONAL);
+	}
+
+	private static DTOMailboxScopeData createScopeData(MddiMailboxIndexData... mailBoxes) {
+		return DTOMailboxScopeData.builder()
+				.membershipcontext(UUID.fromString(NAME_ID))
+				.memberscope(Arrays.asList(mailBoxes))
+				.build();
+	}
+}
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapperTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapperTest.java
index 89d64bac79517999fc840fd5c2857126c879fa51..31584b2b4441a33bda5d98d3bed1a8f40e9963cb 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapperTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2MessageMapperTest.java
@@ -1,27 +1,45 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
+import static de.ozgcloud.apilib.file.OzgCloudFileTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2AttachmentTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory.*;
-import static java.util.Collections.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.transfer.Osi2MessageMapper.*;
 import static org.assertj.core.api.Assertions.*;
 
 import java.util.List;
+import java.util.UUID;
+import java.util.stream.Stream;
 
 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.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mapstruct.factory.Mappers;
 
+import de.ozgcloud.apilib.file.OzgCloudFileId;
+import de.ozgcloud.apilib.file.OzgCloudFileTestFactory;
+import de.ozgcloud.nachrichten.postfach.PostfachAddress;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+import de.ozgcloud.nachrichten.postfach.osiv2.OsiPostfachRemoteService;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2AttachmentTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.AttachmentInfo;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 
 class Osi2MessageMapperTest {
 
 	private final Osi2MessageMapper mapper = Mappers.getMapper(Osi2MessageMapper.class);
 
-	@DisplayName("to PostfachNachricht")
+	@DisplayName("map PostfachNachricht")
 	@Nested
-	class TestToPostfachNachricht {
+	class TestMapPostfachNachricht {
 		private final Osi2Message osi2Message = Osi2MessageTestFactory.create();
 		private final String attachmentId1 = "attachmentId1";
 		private final String attachmentId2 = "attachmentId2";
@@ -71,7 +89,9 @@ class Osi2MessageMapperTest {
 		void shouldMapPostfachAddress() {
 			var result = doMapping();
 
-			assertThat(result.getPostfachAddress()).isEqualTo(osi2Message.postfachAddress());
+			assertThat(result.getPostfachAddress()).usingRecursiveComparison().isEqualTo(
+					mapper.createPostfachAddressByMailboxId(osi2Message.mailboxId())
+			);
 		}
 
 		@DisplayName("should map direction")
@@ -91,7 +111,218 @@ class Osi2MessageMapperTest {
 		}
 
 		private PostfachNachricht doMapping() {
-			return mapper.toPostfachNachricht(osi2Message, List.of(attachmentId1, attachmentId2));
+			return mapper.mapPostfachNachricht(osi2Message, List.of(attachmentId1, attachmentId2));
+		}
+	}
+
+	@DisplayName("create postfach address by mailboxId")
+	@Nested
+	class TestCreatePostfachAddressByMailboxId {
+
+		@DisplayName("should map postfach address type")
+		@Test
+		void shouldMapPostfachAddressType() {
+			var result = doMapping();
+
+			assertThat(result.getType()).isEqualTo(POSTFACH_ADDRESS_TYPE);
+		}
+
+		@DisplayName("should map version")
+		@Test
+		void shouldMapVersion() {
+			var result = doMapping();
+
+			assertThat(result.getVersion()).isEqualTo(POSTFACH_ADDRESS_VERSION);
+		}
+
+		@DisplayName("should map postfachId")
+		@Test
+		void shouldMapPostfachId() {
+			var result = doMapping();
+
+			assertThat(result.getIdentifier().getStringRepresentation()).isEqualTo(MAILBOX_ID);
+		}
+
+		@DisplayName("should map servicekontotype")
+		@Test
+		void shouldMapServicekontotype() {
+			var result = doMapping();
+
+			assertThat(result.getServiceKontoType()).isEqualTo(OsiPostfachRemoteService.POSTFACH_TYPE_OSI);
+		}
+
+		private PostfachAddress doMapping() {
+			return mapper.createPostfachAddressByMailboxId(MAILBOX_ID);
+		}
+	}
+
+	@DisplayName("map osi2 message")
+	@Nested
+	class TestMapOsi2Message {
+
+		private static final String FILE_ID2 = UUID.randomUUID().toString();
+		private final Osi2Attachment attachment1 = Osi2AttachmentTestFactory.createBuilder()
+				.build();
+		private final Osi2Attachment attachment2 = Osi2AttachmentTestFactory.createBuilder()
+				.guid(ATTACHMENT_GUID_2)
+				.file(OzgCloudFileTestFactory.createBuilder()
+						.id(OzgCloudFileId.from(FILE_ID2))
+						.build())
+				.build();
+		private final PostfachNachricht nachricht = PostfachNachrichtTestFactory.createBuilder()
+				.attachments(List.of(ID_STR, FILE_ID2))
+				.build();
+
+		@DisplayName("should map vorgangId")
+		@Test
+		void shouldMapVorgangId() {
+			var result = doMapping();
+
+			assertThat(result.vorgangId()).isEqualTo(VORGANG_ID);
+		}
+
+		@DisplayName("should map mailboxId")
+		@Test
+		void shouldMapMailboxId() {
+			var result = doMapping();
+
+			assertThat(result.mailboxId()).isEqualTo(MAILBOX_ID);
+		}
+
+		@DisplayName("should map messsageId")
+		@Test
+		void shouldMapMesssageId() {
+			var result = doMapping();
+
+			assertThat(result.messageId()).isEqualTo(MESSAGE_ID);
+		}
+
+		@DisplayName("should map createdAt")
+		@Test
+		void shouldMapCreatedAt() {
+			var result = doMapping();
+
+			assertThat(result.createdAt()).isEqualTo(CREATED_AT);
+		}
+
+		@DisplayName("should map subject")
+		@Test
+		void shouldMapSubject() {
+			var result = doMapping();
+
+			assertThat(result.subject()).isEqualTo(MAIL_SUBJECT);
+		}
+
+		@DisplayName("should map mailBody")
+		@Test
+		void shouldMapMailBody() {
+			var result = doMapping();
+
+			assertThat(result.mailBody()).isEqualTo(MAIL_BODY);
+		}
+
+		@DisplayName("should map replyOption")
+		@Test
+		void shouldMapReplyOption() {
+			var result = doMapping();
+
+			assertThat(result.replyOption()).isEqualTo(REPLY_OPTION);
+		}
+
+		@DisplayName("should map attachments")
+		@Test
+		void shouldMapAttachments() {
+			var result = doMapping();
+
+			assertThat(result.attachments()).containsExactly(
+					mapper.mapAttachmentInfo(attachment1),
+					mapper.mapAttachmentInfo(attachment2)
+			);
+		}
+
+		private Osi2Message doMapping() {
+			return mapper.mapOsi2Message(
+					nachricht,
+					MAILBOX_ID,
+					List.of(attachment2, attachment1)
+			);
+		}
+	}
+
+	@DisplayName("map attachment info")
+	@Nested
+	class TestMapAttachmentInfo {
+
+		private final Osi2Attachment attachment = Osi2AttachmentTestFactory.create();
+
+		@DisplayName("should map guid")
+		@Test
+		void shouldMapGuid() {
+			var result = doMapping();
+
+			assertThat(result.guid()).isEqualTo(ATTACHMENT_GUID);
+		}
+
+		@DisplayName("should map name")
+		@Test
+		void shouldMapName() {
+			var result = doMapping();
+
+			assertThat(result.name()).isEqualTo(OzgCloudFileTestFactory.NAME);
+		}
+
+		@DisplayName("should map contentType")
+		@Test
+		void shouldMapContentType() {
+			var result = doMapping();
+
+			assertThat(result.contentType()).isEqualTo(OzgCloudFileTestFactory.CONTENT_TYPE);
+		}
+
+		@DisplayName("should map size")
+		@Test
+		void shouldMapSize() {
+			var result = doMapping();
+
+			assertThat(result.size()).isEqualTo(OzgCloudFileTestFactory.SIZE);
+		}
+
+		private AttachmentInfo doMapping() {
+			return mapper.mapAttachmentInfo(attachment);
+		}
+	}
+
+	@DisplayName("get nameIdentifier")
+	@Nested
+	class TestGetNameIdentifier {
+
+		@DisplayName("should map postfach address to nameIdentifier")
+		@Test
+		void shouldMapPostfachAddressToNameIdentifier() {
+			var result = mapper.getNameIdentifier(PostfachNachrichtTestFactory.create());
+
+			assertThat(result).isEqualTo(NAME_IDENTIFIER);
+		}
+
+		@DisplayName("should throw on missing postfach address")
+		@ParameterizedTest
+		@MethodSource("badPostfachAddresses")
+		void shouldThrowOnMissingPostfachAddress(PostfachAddress badPostfachAddress) {
+			var nachrichtWithBadPostfachAddress = PostfachNachrichtTestFactory.createBuilder()
+					.postfachAddress(badPostfachAddress)
+					.build();
+
+			assertThatThrownBy(() -> mapper.getNameIdentifier(nachrichtWithBadPostfachAddress))
+					.isInstanceOf(IllegalArgumentException.class);
+		}
+
+		static Stream<Arguments> badPostfachAddresses() {
+			return Stream.of(
+					null,
+					Arguments.of(PostfachAddressTestFactory.createBuilder()
+							.identifier(null)
+							.build())
+			);
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachServiceTest.java
index 7077d02f8f7ad83c5dd3171056079beac450b06e..8f19f2c08e1d15028b897067e39a3e1ec23ebf38 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachServiceTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2PostfachServiceTest.java
@@ -1,6 +1,10 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
+import static de.ozgcloud.apilib.file.OzgCloudFileTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.MessageExchangeReceiveMessagesResponseTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
@@ -16,9 +20,12 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+import de.ozgcloud.nachrichten.postfach.osiv2.attachment.Osi2PersistAttachmentService;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 
 class Osi2PostfachServiceTest {
 
@@ -30,33 +37,65 @@ class Osi2PostfachServiceTest {
 	private PostfachApiFacadeService postfachApiFacadeService;
 	@Mock
 	private Osi2QuarantineService quarantineService;
+	@Mock
+	private Osi2PersistAttachmentService persistAttachmentService;
+	@Mock
+	private Osi2MessageMapper messageMapper;
 
 	@DisplayName("send message")
 	@Nested
 	class TestSendOsi2Message {
 		private final PostfachNachricht nachricht = PostfachNachrichtTestFactory.create();
+		private final Osi2Message osi2Message = Osi2MessageTestFactory.create();
 		private final List<Osi2Attachment> uploadFiles = List.of(Osi2FileUploadTestFactory.create());
 
 		@BeforeEach
 		void mock() {
+			when(messageMapper.getNameIdentifier(any())).thenReturn(NAME_IDENTIFIER);
+			when(messageMapper.mapOsi2Message(any(), any(), any())).thenReturn(osi2Message);
 			when(quarantineService.uploadAttachments(any())).thenReturn(uploadFiles);
+			when(postfachApiFacadeService.lookupMailboxId(any())).thenReturn(MAILBOX_ID);
+		}
+
+		@DisplayName("should call getNameIdentifier")
+		@Test
+		void shouldCallGetNameIdentifier() {
+			service.sendMessage(nachricht);
+
+			verify(messageMapper).getNameIdentifier(nachricht);
+		}
+
+		@DisplayName("should call lookupMailboxId")
+		@Test
+		void shouldCallLookupMailboxId() {
+			service.sendMessage(nachricht);
+
+			verify(postfachApiFacadeService).lookupMailboxId(NAME_IDENTIFIER);
 		}
 
-		@DisplayName("should send message")
+		@DisplayName("should call mapOsi2Message")
 		@Test
-		void shouldSendMessage() {
+		void shouldCallMapOsi2Message() {
 			service.sendMessage(nachricht);
 
-			verify(postfachApiFacadeService).sendMessage(nachricht, uploadFiles);
+			verify(messageMapper).mapOsi2Message(nachricht, MAILBOX_ID, uploadFiles);
 		}
 
-		@DisplayName("should upload attachments of nachricht")
+		@DisplayName("should call uploadAttachments")
 		@Test
-		void shouldUploadAttachmentsOfNachricht() {
+		void shouldCallUploadAttachments() {
 			service.sendMessage(nachricht);
 
 			verify(quarantineService).uploadAttachments(nachricht.getAttachments());
 		}
+
+		@DisplayName("should call sendMessage")
+		@Test
+		void shouldCallSendMessage() {
+			service.sendMessage(nachricht);
+
+			verify(postfachApiFacadeService).sendMessage(osi2Message);
+		}
 	}
 
 	@DisplayName("receive messages")
@@ -93,4 +132,47 @@ class Osi2PostfachServiceTest {
 		}
 	}
 
+	@DisplayName("fetch PostfachNachricht")
+	@Nested
+	class TestFetchPostfachNachricht {
+
+		private final Osi2Message message = Osi2MessageTestFactory.create();
+		private final PostfachNachricht postfachNachricht = PostfachNachrichtTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			when(postfachApiFacadeService.fetchMessageById(any())).thenReturn(message);
+			when(messageMapper.mapPostfachNachricht(any(), any())).thenReturn(postfachNachricht);
+			when(persistAttachmentService.persistAttachments(any())).thenReturn(List.of(ID_STR));
+		}
+
+		@DisplayName("should call fetchMessageById")
+		@Test
+		void shouldCallFetchMessageById() {
+			fetchPostfachNachricht();
+
+			verify(postfachApiFacadeService).fetchMessageById(MESSAGE_ID);
+		}
+
+		@DisplayName("should call mapPostfachNachricht")
+		@Test
+		void shouldCallMapPostfachNachricht() {
+			fetchPostfachNachricht();
+
+			verify(messageMapper).mapPostfachNachricht(message, List.of(ID_STR));
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = fetchPostfachNachricht();
+
+			assertThat(result).isEqualTo(postfachNachricht);
+		}
+
+		private PostfachNachricht fetchPostfachNachricht() {
+			return service.fetchPostfachNachricht(MESSAGE_ID);
+		}
+	}
+
 }
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapperTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapperTest.java
index bdf27c7d4d9171eb1c1b60da3ede0638510b176b..b6cda51ed4e9722a8ff08f0f04c7f53eb64bce37 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapperTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2RequestMapperTest.java
@@ -1,80 +1,46 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory.*;
-import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory.*;
-import static java.util.Collections.*;
 import static org.assertj.core.api.Assertions.*;
 
 import java.util.List;
 import java.util.UUID;
-import java.util.stream.Stream;
 
 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.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
 import org.mapstruct.factory.Mappers;
 
-import de.ozgcloud.apilib.file.OzgCloudFileTestFactory;
-import de.ozgcloud.nachrichten.postfach.PostfachAddress;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.AttachmentInfoTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.FileChunkInfoTestFactory;
-import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory;
-import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory;
-import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.DomainChunkMetaData;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeFiles;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1EidasLevel;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1FilestorageTarget;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.AttachmentInfo;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 
 class Osi2RequestMapperTest {
 
 	private final Osi2RequestMapper mapper = Mappers.getMapper(Osi2RequestMapper.class);
 
-	@DisplayName("map mailbox id")
-	@Nested
-	class TestMapMailboxId {
-
-		@DisplayName("should map postfach address to mailbox id")
-		@Test
-		void shouldMapPostfachAddressToMailboxId() {
-			var result = mapper.mapMailboxId(PostfachNachrichtTestFactory.create());
-
-			assertThat(result).isEqualTo(MAILBOX_ID);
-		}
-
-		@DisplayName("should throw on missing postfach address")
-		@ParameterizedTest
-		@MethodSource("badPostfachAddresses")
-		void shouldThrowOnMissingPostfachAddress(PostfachAddress badPostfachAddress) {
-			var nachrichtWithBadPostfachAddress = PostfachNachrichtTestFactory.createBuilder()
-					.postfachAddress(badPostfachAddress)
-					.build();
-
-			assertThatThrownBy(() -> mapper.mapMailboxId(nachrichtWithBadPostfachAddress))
-					.isInstanceOf(IllegalArgumentException.class);
-		}
-
-		static Stream<Arguments> badPostfachAddresses() {
-			return Stream.of(
-					null,
-					Arguments.of(PostfachAddressTestFactory.createBuilder()
-							.identifier(null)
-							.build())
-			);
-		}
-	}
-
 	@DisplayName("map OutSendMessageRequestV2")
 	@Nested
 	class TestMapOutSendOsi2MessageRequestV2 {
 
+		private final Osi2Message osi2Message = Osi2MessageTestFactory.create();
+
+		private final AttachmentInfo attachment1 = AttachmentInfoTestFactory.create();
+		private final AttachmentInfo attachment2 = AttachmentInfoTestFactory.createBuilder()
+				.guid(UPLOAD_GUID2)
+				.build();
+
 		@DisplayName("should map sequence number")
 		@Test
 		void shouldMapSequenceNumber() {
@@ -118,11 +84,11 @@ class Osi2RequestMapperTest {
 		@DisplayName("should map possible reply action")
 		@Test
 		void shouldMapPossibleReplyAction() {
-			var nachricht = PostfachNachrichtTestFactory.createBuilder()
+			var message = Osi2MessageTestFactory.createBuilder()
 					.replyOption(PostfachNachricht.ReplyOption.POSSIBLE)
 					.build();
 
-			var result = mapper.mapOutSendMessageRequestV2(nachricht, emptyList());
+			var result = mapper.mapOutSendMessageRequestV2(message);
 
 			assertThat(result.getReplyAction()).isEqualTo(V1ReplyBehavior.REPLYPOSSIBLE);
 		}
@@ -130,11 +96,11 @@ class Osi2RequestMapperTest {
 		@DisplayName("should map mandatory reply action")
 		@Test
 		void shouldMapMandatoryReplyAction() {
-			var nachricht = PostfachNachrichtTestFactory.createBuilder()
+			var message = Osi2MessageTestFactory.createBuilder()
 					.replyOption(PostfachNachricht.ReplyOption.MANDATORY)
 					.build();
 
-			var result = mapper.mapOutSendMessageRequestV2(nachricht, emptyList());
+			var result = mapper.mapOutSendMessageRequestV2(message);
 
 			assertThat(result.getReplyAction()).isEqualTo(V1ReplyBehavior.REPLYMANDATORY);
 		}
@@ -171,36 +137,19 @@ class Osi2RequestMapperTest {
 			assertThat(result.getFiles()).isEmpty();
 		}
 
-		@DisplayName("should map two files")
+		@DisplayName("should map files")
 		@Test
-		void shouldMapTwoFiles() {
-			var files = List.of(
-					Osi2FileUploadTestFactory.create(),
-					Osi2FileUploadTestFactory.createBuilder()
-							.file(OzgCloudFileTestFactory.create())
-							.guid(UPLOAD_GUID2)
-							.build()
-			);
-			var nachricht = PostfachNachrichtTestFactory.createBuilder()
-					.attachments(List.of(UPLOAD_FILE_ID, OzgCloudFileTestFactory.ID_STR))
+		void shouldMapFiles() {
+			var message = Osi2MessageTestFactory.createBuilder()
+					.attachments(List.of(attachment1, attachment2))
 					.build();
 
-			var result = mapper.mapOutSendMessageRequestV2(nachricht, files);
+			var result = mapper.mapOutSendMessageRequestV2(message);
 
-			assertThat(result.getFiles())
-					.usingRecursiveComparison()
-					.isEqualTo(files.stream().map(mapper::mapMessageExchangeFile).toList());
-		}
-
-		@DisplayName("should map files")
-		@Test
-		void shouldMapFiles() {
-			var result = mapper.mapOutSendMessageRequestV2(
-					PostfachNachrichtTestFactory.create(),
-					List.of(Osi2FileUploadTestFactory.create())
+			assertThat(result.getFiles()).containsExactly(
+					mapper.mapMessageExchangeFile(attachment1),
+					mapper.mapMessageExchangeFile(attachment2)
 			);
-
-			assertThat(result.getFiles()).isEmpty();
 		}
 
 		@DisplayName("should map references")
@@ -212,7 +161,7 @@ class Osi2RequestMapperTest {
 		}
 
 		private OutSendMessageRequestV2 doMapping() {
-			return mapper.mapOutSendMessageRequestV2(PostfachNachrichtTestFactory.create(), emptyList());
+			return mapper.mapOutSendMessageRequestV2(osi2Message);
 		}
 	}
 
@@ -252,7 +201,7 @@ class Osi2RequestMapperTest {
 		}
 
 		private MessageExchangeFiles mapFile() {
-			return mapper.mapMessageExchangeFile(Osi2FileUploadTestFactory.create());
+			return mapper.mapMessageExchangeFile(AttachmentInfoTestFactory.create());
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapperTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapperTest.java
index ff5a336d4e16028c186505786504021ef711f814..154bf87a8ede99cc7bf7585e02dafe43737da24d 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapperTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2ResponseMapperTest.java
@@ -5,6 +5,7 @@ import static de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyFilesTestFac
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 
+import java.util.List;
 import java.util.stream.Stream;
 
 import org.junit.jupiter.api.DisplayName;
@@ -18,13 +19,16 @@ import org.mapstruct.factory.Mappers;
 import org.mockito.InjectMocks;
 
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2MailboxNotFoundException;
 import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2RuntimeException;
 import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2UploadException;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.QuarantineFileResultTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.ResponsesMailboxDirectoryResponseTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyFilesTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.QuarantineStatus;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.ResponsesMailboxDirectoryResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyFiles;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage;
@@ -53,8 +57,7 @@ class Osi2ResponseMapperTest {
 		void shouldMapPostfachAddress() {
 			var result = doMapping();
 
-			assertThat(result.postfachAddress().getIdentifier())
-					.hasToString(MESSAGE_BOX_ID);
+			assertThat(result.mailboxId()).isEqualTo(MESSAGE_BOX_ID);
 		}
 
 		@Test
@@ -295,4 +298,67 @@ class Osi2ResponseMapperTest {
 					.hasMessageContaining(Osi2FileUploadTestFactory.UPLOAD_GUID);
 		}
 	}
+
+	@DisplayName("get mailboxId by tenant or first")
+	@Nested
+	class TestGetMailboxIdByTenantOrFirst {
+
+		private final ResponsesMailboxDirectoryResponse response = ResponsesMailboxDirectoryResponseTestFactory.create();
+
+		@DisplayName("should throw with null response")
+		@Test
+		void shouldThrowWithNullResponse() {
+
+			assertThatThrownBy(() -> mapper.getMailboxIdByTenantOrFirst(null, ""))
+					.isInstanceOf(Osi2MailboxNotFoundException.class);
+		}
+
+		@DisplayName("should throw with missing index")
+		@Test
+		void shouldThrowWithMissingIndex() {
+			var responseWithoutMailboxIds = ResponsesMailboxDirectoryResponseTestFactory.createBuilder()
+					.mailBoxIndex(List.of())
+					.build();
+
+			assertThatThrownBy(
+					() -> mapper.getMailboxIdByTenantOrFirst(responseWithoutMailboxIds, ResponsesMailboxDirectoryResponseTestFactory.TENANT_SH))
+					.isInstanceOf(Osi2MailboxNotFoundException.class);
+		}
+
+		@DisplayName("should throw with missing mailboxes")
+		@Test
+		void shouldThrowWithMissingMailboxes() {
+			var responseWithoutMailboxIds = ResponsesMailboxDirectoryResponseTestFactory.createBuilder()
+					.build();
+
+			assertThatThrownBy(
+					() -> mapper.getMailboxIdByTenantOrFirst(responseWithoutMailboxIds, ResponsesMailboxDirectoryResponseTestFactory.TENANT_SH))
+					.isInstanceOf(Osi2MailboxNotFoundException.class);
+		}
+
+		@DisplayName("should return mailboxId for SH")
+		@Test
+		void shouldReturnMailboxIdForSH() {
+			var result = mapper.getMailboxIdByTenantOrFirst(response, ResponsesMailboxDirectoryResponseTestFactory.TENANT_SH);
+
+			assertThat(result).isEqualTo(ResponsesMailboxDirectoryResponseTestFactory.MAILBOX_GUID_SH);
+		}
+
+		@DisplayName("should return mailboxId for HH")
+		@Test
+		void shouldReturnMailboxIdForHh() {
+			var result = mapper.getMailboxIdByTenantOrFirst(response, ResponsesMailboxDirectoryResponseTestFactory.TENANT_HH);
+
+			assertThat(result).isEqualTo(ResponsesMailboxDirectoryResponseTestFactory.MAILBOX_GUID_HH);
+		}
+
+		@DisplayName("should return first mailboxId for unknown tenant")
+		@Test
+		void shouldReturnFirstMailboxIdForUnknownTenant() {
+			var result = mapper.getMailboxIdByTenantOrFirst(response, "unknown");
+
+			assertThat(result).isEqualTo(ResponsesMailboxDirectoryResponseTestFactory.MAILBOX_GUID_SH);
+		}
+
+	}
 }
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java
index 0e6e97f9263715e2f246471e0364cf0e351a6e03..eafc3e250a330de08954023c11baa28ea712456d 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java
@@ -1,7 +1,10 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.MessageExchangeReceiveMessagesResponseTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.ResponsesMailboxDirectoryResponseTestFactory.*;
 import static de.ozgcloud.nachrichten.postfach.osiv2.transfer.Osi2RequestMapper.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
@@ -18,14 +21,13 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 import org.springframework.core.io.AbstractResource;
 
-import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.config.Osi2PostfachProperties;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.FileChunkInfoTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.MessageExchangeReceiveMessagesResponseTestFactory;
-import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2FileUploadTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.Osi2MessageTestFactory;
-import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.ResponsesMailboxDirectoryResponseTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MailboxDirectoryApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.QuarantineApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.DomainChunkMetaData;
@@ -34,9 +36,9 @@ import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMe
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeSendMessageResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.QuarantineStatus;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.ResponsesMailboxDirectoryResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
-import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message;
 import lombok.SneakyThrows;
 
@@ -52,6 +54,9 @@ class PostfachApiFacadeServiceTest {
 	@Mock
 	QuarantineApi quarantineApi;
 
+	@Mock
+	MailboxDirectoryApi mailboxDirectoryApi;
+
 	@Mock
 	Osi2RequestMapper osi2RequestMapper;
 
@@ -71,37 +76,26 @@ class PostfachApiFacadeServiceTest {
 		@Mock
 		MessageExchangeSendMessageResponse messageExchangeSendMessageResponse;
 
-		private final List<Osi2Attachment> files = List.of(Osi2FileUploadTestFactory.create());
-
-		private final PostfachNachricht nachricht = PostfachNachrichtTestFactory.create();
+		private final Osi2Message message = Osi2MessageTestFactory.create();
 
 		@BeforeEach
 		void mock() {
-			when(osi2RequestMapper.mapMailboxId(any())).thenReturn(MAILBOX_ID);
-			when(osi2RequestMapper.mapOutSendMessageRequestV2(any(), any())).thenReturn(outSendMessageRequestV2);
+			when(osi2RequestMapper.mapOutSendMessageRequestV2(any())).thenReturn(outSendMessageRequestV2);
 			when(messageExchangeApi.sendMessage(any(), any())).thenReturn(messageExchangeSendMessageResponse);
 		}
 
-		@DisplayName("should call mapMailboxId")
-		@Test
-		void shouldCallMapMailboxId() {
-			service.sendMessage(nachricht, files);
-
-			verify(osi2RequestMapper).mapMailboxId(nachricht);
-		}
-
 		@DisplayName("should call mapOutSendMessageRequestV2")
 		@Test
 		void shouldCallMapOutSendMessageRequestV2() {
-			service.sendMessage(nachricht, files);
+			service.sendMessage(message);
 
-			verify(osi2RequestMapper).mapOutSendMessageRequestV2(nachricht, files);
+			verify(osi2RequestMapper).mapOutSendMessageRequestV2(message);
 		}
 
 		@DisplayName("should call sendMessage")
 		@Test
 		void shouldCallSendMessage() {
-			service.sendMessage(nachricht, files);
+			service.sendMessage(message);
 
 			verify(messageExchangeApi).sendMessage(MAILBOX_ID, outSendMessageRequestV2);
 		}
@@ -323,4 +317,74 @@ class PostfachApiFacadeServiceTest {
 		}
 	}
 
+	@DisplayName("download attachment")
+	@Nested
+	class TestDownloadAttachment {
+		@Mock
+		AbstractResource resource;
+
+		@BeforeEach
+		void mock() {
+			when(messageExchangeApi.getMessageAttachment(any(), any())).thenReturn(resource);
+		}
+
+		@DisplayName("should call getMessageAttachment")
+		@Test
+		void shouldCallGetMessageAttachment() {
+			service.downloadAttachment(MESSAGE_ID_1, UPLOAD_GUID);
+
+			verify(messageExchangeApi).getMessageAttachment(UUID.fromString(MESSAGE_ID_1), UUID.fromString(UPLOAD_GUID));
+		}
+
+		@DisplayName("should return resource")
+		@Test
+		void shouldReturnResource() {
+			var result = service.downloadAttachment(MESSAGE_ID_1, UPLOAD_GUID);
+
+			assertThat(result).isEqualTo(resource);
+		}
+	}
+
+	@DisplayName("lookup mailboxId")
+	@Nested
+	class TestLookupMailboxId {
+
+		private final ResponsesMailboxDirectoryResponse response = ResponsesMailboxDirectoryResponseTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			when(osi2ResponseMapper.getMailboxIdByTenantOrFirst(any(), any())).thenReturn(MAILBOX_ID);
+			when(mailboxDirectoryApi.lookupMailboxIds(any())).thenReturn(response);
+			when(apiConfiguration.getTenant()).thenReturn(TENANT_SH);
+		}
+
+		@DisplayName("should call lookupMailboxIds")
+		@Test
+		void shouldCallLookupMailboxIds() {
+			lookupMailboxId();
+
+			verify(mailboxDirectoryApi).lookupMailboxIds(List.of(UUID.fromString(NAME_IDENTIFIER)));
+		}
+
+		@DisplayName("should call getMailBoxIdByTenantOrFirst")
+		@Test
+		void shouldCallGetMailBoxIdByTenantOrFirst() {
+			lookupMailboxId();
+
+			verify(osi2ResponseMapper).getMailboxIdByTenantOrFirst(response, TENANT_SH);
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = lookupMailboxId();
+
+			assertThat(result).isEqualTo(MAILBOX_ID);
+		}
+
+		private String lookupMailboxId() {
+			return service.lookupMailboxId(NAME_IDENTIFIER);
+		}
+	}
+
 }
\ No newline at end of file