diff --git a/archive-manager-server/pom.xml b/archive-manager-server/pom.xml
index e227c8c5824f7dafe3c82935cdd23efb486ab370..1fb65a9297a092b47a988edd515d797f37d77a0e 100644
--- a/archive-manager-server/pom.xml
+++ b/archive-manager-server/pom.xml
@@ -95,6 +95,10 @@
 			<groupId>de.ozgcloud.document</groupId>
 			<artifactId>document-manager-interface</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>de.ozgcloud.xta</groupId>
+			<artifactId>xta-client-lib</artifactId>
+		</dependency>
 
 		<!-- Spring -->
 		<dependency>
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java
index cae0d47eb139ac4eb1733ee9802a8276dccf5b29..90f158d548309ca8961473fb78cafec16219e6d4 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java
@@ -81,7 +81,6 @@ public class ArchiveManagerConfiguration {
 	public static final String CALL_CONTEXT_PROVIDER_NAME = "archive_CallContextProvider";
 	public static final String CALL_CONTEXT_MAPPER_NAME = "archive_CallContextMapper";
 
-	public static final String CLIENT_ATTRIBUTE_SERVICE_NAME = "archive_ClientAttributeService";
 	public static final String OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME = "archive_OzgCloudClientAttributeService";
 
 	public static final String KOMMENTAR_SERVICE_NAME = "archive_KommentarService";
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveEventListener.java
similarity index 63%
rename from archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java
rename to archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveEventListener.java
index 83e74246a033293f93b5790a2c74d50f982043ae..1525b91fcbe26e08c3b1464869a5e23b8f380f41 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveEventListener.java
@@ -21,7 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.archive.vorgang;
+package de.ozgcloud.archive.archivierung;
 
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -34,48 +34,81 @@ import org.springframework.security.core.context.SecurityContext;
 import org.springframework.stereotype.Component;
 
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.attributes.ClientAttributeService;
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
 import de.ozgcloud.archive.common.callcontext.CurrentUserService;
+import de.ozgcloud.archive.common.command.CommandService;
+import de.ozgcloud.archive.common.errorhandling.TimeoutException;
+import de.ozgcloud.archive.vorgang.VorgangService;
 import de.ozgcloud.command.Command;
 import de.ozgcloud.command.CommandCreatedEvent;
 import de.ozgcloud.command.CommandFailedEvent;
+import de.ozgcloud.command.VorgangLockedEvent;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
-@Component()
+@Component
 @RequiredArgsConstructor
 @Log4j2
-class ArchiveEventListener {
+public class ArchiveEventListener {
 
+	static final int MAXIMUM_CHECKS_FOR_PENDING_COMMANDS = 3;
+	static final int WAIT_INTERVAL = 30 * 1000;
 	private static final String LOG_MESSAGE_TEMPLATE = "{}. Command failed.";
 	private static final String ERROR_MESSAGE_TEMPLATE = "Error on executing %s Command (id: %s).";
 
 	static final String ARCHIVE_VORGANG_ORDER = "ARCHIVE_VORGANG";
-	private static final String IS_ARCHIVE_VORGANG_EVENT =
-			"{T(de.ozgcloud.archive.vorgang.ArchiveEventListener).IS_ARCHIVE_VORGANG_COMMAND.test(event.getSource())}";
+	private static final String IS_ARCHIVE_VORGANG_EVENT = "{T(de.ozgcloud.archive.archivierung.ArchiveEventListener).IS_ARCHIVE_VORGANG_COMMAND.test(event.getSource())}";
 	public static final Predicate<Command> IS_ARCHIVE_VORGANG_COMMAND = command -> ARCHIVE_VORGANG_ORDER.equals(command.getOrder());
 
+	private static final String IS_LOCKED_BY_ARCHIVE_MANAGER_EVENT = "{T(de.ozgcloud.archive.archivierung.ArchiveEventListener)."
+			+ "IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND.test(event.getCommand())}";
+	public static final Predicate<Command> IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND = command -> CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME
+			.equals(command.getCreatedByClientName());
+
 	@Qualifier(ArchiveManagerConfiguration.CURRENT_USER_SERVICE_NAME) // NOSONAR
 	private final CurrentUserService currentUserService;
 
-	@Qualifier(ArchiveManagerConfiguration.CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
-	private final ClientAttributeService clientAttributeService;
-
 	@Qualifier(ArchiveManagerConfiguration.VORGANG_SERVICE_NAME) // NOSONAR
 	private final VorgangService vorgangService;
 
 	private final ApplicationEventPublisher eventPublisher;
 
+	@Qualifier(ArchiveManagerConfiguration.COMMAND_SERVICE_NAME) // NOSONAR
+	private final CommandService commandService;
+	private final ArchiveService archiveService;
+
 	@EventListener(condition = IS_ARCHIVE_VORGANG_EVENT)
 	void onArchiveVorgangEvent(CommandCreatedEvent event) {
 		runWithSecurityContext(event.getSource(), this::doLockVorgang);
 	}
 
 	void doLockVorgang(Command command) {
-		clientAttributeService.setVorgangArchiving(command.getVorgangId());
+		archiveService.setVorgangArchiving(command.getVorgangId());
 		vorgangService.lockVorgang(command);
 	}
 
+	@EventListener(condition = IS_LOCKED_BY_ARCHIVE_MANAGER_EVENT)
+	public void onVorgangLockedEvent(VorgangLockedEvent event) {
+		waitForPendingCommandsToFinish(event.getCommand().getVorgangId(), WAIT_INTERVAL);
+		runWithSecurityContext(event.getCommand(), archiveService::archiveVorgang);
+	}
+
+	void waitForPendingCommandsToFinish(String vorgangId, long waitIntervalInMillis) {
+		var numberOfAttempts = 0;
+		while (commandService.hasPendingCommandsExceptWithOrder(vorgangId, ARCHIVE_VORGANG_ORDER)) {
+			numberOfAttempts++;
+			if (numberOfAttempts >= MAXIMUM_CHECKS_FOR_PENDING_COMMANDS) {
+				throw new TimeoutException("Waiting for pending commands");
+			}
+			try {
+				Thread.sleep(waitIntervalInMillis);
+			} catch (InterruptedException e) {
+				LOG.error("Error while waiting for commands to finish.", e);
+				Thread.currentThread().interrupt();
+			}
+		}
+	}
+
 	void runWithSecurityContext(Command command, Consumer<Command> commandExecutor) {
 		SecurityContext prevContext = null;
 		try {
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveService.java
similarity index 59%
rename from archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java
rename to archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveService.java
index 21d24f804eb7d430b399243e9af5baaa8affecb8..dc45d255352044fa6b333ff08bc590851cb88274 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/archivierung/ArchiveService.java
@@ -21,7 +21,14 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.archive.attributes;
+package de.ozgcloud.archive.archivierung;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.UUID;
+
+import jakarta.activation.DataHandler;
+import jakarta.activation.FileDataSource;
 
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
@@ -32,17 +39,22 @@ import de.ozgcloud.apilib.client_attribute.OzgCloudClientAttributeService;
 import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import de.ozgcloud.archive.common.callcontext.CallContextUser;
+import de.ozgcloud.archive.common.xta.XtaService;
+import de.ozgcloud.archive.export.ExportService;
+import de.ozgcloud.command.Command;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.model.XtaFile;
 import lombok.RequiredArgsConstructor;
 
-@Service(ArchiveManagerConfiguration.CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
+@Service
 @RequiredArgsConstructor
-public class ClientAttributeService {
+class ArchiveService {
 
 	public static final String ATTRIBUTE_NAME_ANTRAG_ARCHIVING = "ARCHIVING";
-
+	private final XtaService xtaService;
+	private final ExportService exportService;
 	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
 	private final OzgCloudClientAttributeService ozgCloudAttributesService;
-
 	private final OzgCloudVorgangIdMapper vorgangIdMapper;
 
 	public void setVorgangArchiving(String vorgangId) {
@@ -58,4 +70,37 @@ public class ClientAttributeService {
 				.build();
 	}
 
+	public void archiveVorgang(Command command) {
+		xtaService.sendXdomeaFile(buildXdomeaXtaFile(command.getVorgangId()));
+	}
+
+	XtaFile buildXdomeaXtaFile(String vorgangId) {
+		var fileNameId = createFileNameId();
+		return XtaFile.builder()
+				.name(exportService.buildXdomeaFileName(fileNameId))
+				.content(createFileContent(vorgangId, fileNameId))
+				.contentType("application/zip")
+				.build();
+	}
+
+	String createFileNameId() {
+		return UUID.randomUUID().toString();
+	}
+
+	DataHandler createFileContent(String vorgangId, String fileNameId) {
+		try {
+			var tempFile = createTempFile(fileNameId);
+			var fileDataSource = new FileDataSource(tempFile);
+			exportService.writeXdomeaFileContent(vorgangId, fileNameId, fileDataSource.getOutputStream());
+			return new DataHandler(fileDataSource);
+		} catch (IOException e) {
+			throw new TechnicalException("Error on creating file content for xDomea file!", e);
+		}
+	}
+
+	File createTempFile(String fileNameId) throws IOException {
+		var tempFile = File.createTempFile(fileNameId, ".zip");
+		tempFile.deleteOnExit();
+		return tempFile;
+	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java
index cceb21c3920a447cd89382196b08de1ca99d9e7f..58344ce3e7a567afcb01183f18c351480c6cc973 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java
@@ -33,6 +33,7 @@ import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterce
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub;
+import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest;
 import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest;
 import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
@@ -64,6 +65,15 @@ class CommandRemoteService {
 		return builder.build();
 	}
 
+	public boolean hasPendingCommands(String vorgangId) {
+		var response = getGrpcServiceWithInterceptor().existsPendingCommands(buildHasPendingCommandRequest(vorgangId));
+		return response.getExistsPendingCommands();
+	}
+
+	GrpcExistsPendingCommandsRequest buildHasPendingCommandRequest(String vorgangId) {
+		return GrpcExistsPendingCommandsRequest.newBuilder().setVorgangId(vorgangId).build();
+	}
+
 	CommandServiceBlockingStub getGrpcServiceWithInterceptor() {
 		return grpcService.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider));
 	}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java
index 2a0f5d9fe635f48335405f1f8a040a54721eb82d..a1f4e512ba5723b7c28c322812a0784bf56473e6 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java
@@ -24,11 +24,16 @@
 package de.ozgcloud.archive.common.command;
 
 import java.util.Optional;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
+import de.ozgcloud.apilib.common.command.OzgCloudCommand;
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
@@ -39,9 +44,20 @@ public class CommandService {
 
 	@Qualifier(ArchiveManagerConfiguration.COMMAND_REMOTE_SERVICE_NAME) // NOSONAR
 	private final CommandRemoteService remoteService;
+	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_COMMAND_SERVICE_NAME) // NOSONAR
+	private final OzgCloudCommandService ozgCloudCommandService;
 
 	public Stream<ArchiveManagerCommand> findFinishedCommands(@NonNull String vorgangId) {
 		return remoteService.findCommands(vorgangId, Optional.of("FINISHED"), Optional.empty());
 	}
 
+	public boolean hasPendingCommandsExceptWithOrder(String vorgangId, String order) {
+		var pendingCommands = ozgCloudCommandService.getPendingCommands(OzgCloudVorgangId.from(vorgangId));
+		return pendingCommands.stream().anyMatch(hasNotOrder(order));
+	}
+
+	private Predicate<? super OzgCloudCommand> hasNotOrder(String order) {
+		return command -> !StringUtils.equals(command.getOrder(), order);
+	}
+
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/errorhandling/TimeoutException.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/errorhandling/TimeoutException.java
new file mode 100644
index 0000000000000000000000000000000000000000..1de21d85e04f3c422d4de01560a7798f28aa2393
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/errorhandling/TimeoutException.java
@@ -0,0 +1,17 @@
+package de.ozgcloud.archive.common.errorhandling;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+
+public class TimeoutException extends TechnicalException {
+
+	private static final String MESSAGE_TEMPLATE = "%s exceeded its time limit.";
+
+	public TimeoutException(String request) {
+		super(MESSAGE_TEMPLATE.formatted(request));
+	}
+
+	public TimeoutException(String request, Throwable cause) {
+		super(MESSAGE_TEMPLATE.formatted(request), cause);
+	}
+
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d112b2c26dbfe68d4d97b819afd6a9b667e20549
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java
@@ -0,0 +1,34 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.List;
+
+import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.model.XtaIdentifier;
+import lombok.RequiredArgsConstructor;
+
+@Component
+@ConfigurationPropertiesBinding
+@RequiredArgsConstructor
+public class JsonToXtaIdentifierListConverter implements Converter<String, List<XtaIdentifier>> {
+
+	private final ObjectMapper objectMapper;
+
+	@Override
+	public List<XtaIdentifier> convert(String source) {
+		try {
+			return objectMapper.readValue(source, new TypeReference<List<XtaIdentifier>>() {
+			});
+		} catch (JsonProcessingException e) {
+			throw new TechnicalException("Error on converting XtaIdentifier!", e);
+		}
+	}
+
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..174f5862deb05402b3200b9aedd221f5cdd5e96b
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java
@@ -0,0 +1,61 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.io.IOException;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ozgcloud.archive.common.xta.XtaProperties.XtaClientKeyStore;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.XtaClient;
+import de.ozgcloud.xta.client.config.XtaClientConfig;
+import de.ozgcloud.xta.client.config.XtaClientConfig.KeyStore;
+import de.ozgcloud.xta.client.exception.XtaClientInitializationException;
+
+@Configuration
+class XtaConfiguration {
+
+	@Bean
+	@ConditionalOnProperty(prefix = XtaProperties.XTA_PROPERTIES_PREFIX, name = "enabled")
+	XtaClient xtaClient(XtaProperties xtaProperties) {
+		try {
+			return XtaClient.from(buildXtaClientConfig(xtaProperties));
+		} catch (XtaClientInitializationException e) {
+			throw new TechnicalException("Error on initializing Xta client.", e);
+		}
+	}
+
+	XtaClientConfig buildXtaClientConfig(XtaProperties xtaProperties) {
+		return XtaClientConfig.builder()
+				.sendServiceUrl(xtaProperties.getSendServiceUrl())
+				.managementServiceUrl(xtaProperties.getManagementServiceUrl())
+				.msgBoxServiceUrl(xtaProperties.getMsgBoxServiceUrl())
+				.clientCertKeystore(buildKeystore(xtaProperties.getKeyStore()))
+				.trustStore(buildKeystore(xtaProperties.getTrustStore()))
+				.maxListItems(xtaProperties.getMaxLoadedMessages())
+				.clientIdentifiers(xtaProperties.getClientIdentifiers())
+				.build();
+	}
+
+	private KeyStore buildKeystore(XtaClientKeyStore clientCert) {
+		try {
+			return XtaClientConfig.KeyStore.builder()
+					.content(clientCert.getFile().getContentAsByteArray())
+					.type(clientCert.getType())
+					.password(clientCert.getPassword())
+					.build();
+		} catch (IOException e) {
+			throw new TechnicalException("Error on reading Xta client certificate.", e);
+		}
+	}
+
+	@Bean
+	@Lazy
+	ObjectMapper objectMapper() {
+		return new ObjectMapper();
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5409da8ffaf6e8b7d7ecb408f631007a45f9a6d
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java
@@ -0,0 +1,70 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.List;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+
+import de.ozgcloud.xta.client.model.XtaIdentifier;
+import lombok.Getter;
+import lombok.Setter;
+
+@Configuration
+@ConfigurationProperties(prefix = XtaProperties.XTA_PROPERTIES_PREFIX)
+@Getter
+@Setter
+public class XtaProperties {
+
+	static final String XTA_PROPERTIES_PREFIX = "ozgcloud.xta";
+
+	/*
+	 * Flag to enable/disable XTA adapter usage.
+	 */
+	private boolean enabled = false;
+	/*
+	 * XTA endpoint messages are sent to.
+	 */
+	private String sendServiceUrl;
+	/*
+	 * XTA endpoint to message box.
+	 */
+	private String msgBoxServiceUrl;
+	/*
+	 * XTA endpoint to management information
+	 */
+	private String managementServiceUrl;
+	/*
+	 * Maximum number of messages loaded from message box.
+	 */
+	private int maxLoadedMessages = 50;
+	/*
+	 * Reference to client certification key store.
+	 */
+	private XtaClientKeyStore keyStore;
+	/*
+	 * Reference to trust store.
+	 */
+	private XtaClientKeyStore trustStore;
+	/*
+	 * Client identifiers used to identify client at XTA adapter.
+	 */
+	private List<XtaIdentifier> clientIdentifiers;
+
+	@Getter
+	@Setter
+	public static class XtaClientKeyStore {
+		/*
+		 * Reference to key store reference.
+		 */
+		private Resource file;
+		/*
+		 * Type of the referenced key store.
+		 */
+		private String type;
+		/*
+		 * Password to access key store.
+		 */
+		private char[] password;
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java
new file mode 100644
index 0000000000000000000000000000000000000000..9aac41082bcaaa23dbb2b1acbadaf85411791ef5
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java
@@ -0,0 +1,41 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.Optional;
+
+import org.springframework.stereotype.Service;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.XtaClient;
+import de.ozgcloud.xta.client.exception.XtaClientException;
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaMessage;
+import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+@Service
+public class XtaService {
+	private static final String XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE = "XtaClient is not configured! Cannot send message to DMS.";
+
+	private final Optional<XtaClient> xtaClient;
+
+	public void sendXdomeaFile(XtaFile xdomeaFile) {
+		try {
+			getXtaClient().sendMessage(createMessage(xdomeaFile));
+		} catch (XtaClientException e) {
+			throw new TechnicalException("Error on sending xDomea message!", e);
+		}
+	}
+
+	XtaMessage createMessage(XtaFile xdomeaFile) {
+		try {
+			return XdomeaXtaMessageCreator.createInstance().createMessage(xdomeaFile);
+		} catch (XtaClientException e) {
+			throw new TechnicalException("Error on creating xDomea message!", e);
+		}
+	}
+
+	XtaClient getXtaClient() {
+		return xtaClient.orElseThrow(() -> new TechnicalException(XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE));
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java
index 6aee7b10575fc54a6b42a132a3b93eba83059148..65893226e8a3cf0cf17e40914a0eaa7241eb7e6b 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java
@@ -44,8 +44,6 @@ import net.devh.boot.grpc.server.service.GrpcService;
 @RequiredArgsConstructor
 class ExportGrpcService extends ExportServiceImplBase {
 
-	private static final String EXPORT_FILENAME_TEMPLATE = "%s_Abgabe.Abgabe.0401.xdomea";
-
 	static final int CHUNK_SIZE = 256 * 1024;
 
 	private final ExportService exportService;
@@ -64,14 +62,10 @@ class ExportGrpcService extends ExportServiceImplBase {
 
 	void sendFileName(StreamObserver<GrpcExportVorgangResponse> responseObserver, String fileNameId) {
 		responseObserver.onNext(GrpcExportVorgangResponse.newBuilder()
-				.setVorgangFile(GrpcFile.newBuilder().setFileName(buildXdomeaFileName(fileNameId)).build())
+				.setVorgangFile(GrpcFile.newBuilder().setFileName(exportService.buildXdomeaFileName(fileNameId)).build())
 				.build());
 	}
 
-	String buildXdomeaFileName(String fileNameId) {
-		return String.format(EXPORT_FILENAME_TEMPLATE, fileNameId);
-	}
-
 	GrpcBinaryFileServerDownloader<GrpcExportVorgangResponse> buildExportDownloader(String vorgangId, String fileNameId,
 			StreamObserver<GrpcExportVorgangResponse> responseObserver) {
 		return GrpcBinaryFileServerDownloader.<GrpcExportVorgangResponse>builder()
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java
index 6f1c42f2869ada9c9b5c7db8f86acee7101ee481..555dd08ff192966cb4f0a90396053f8cec20be61 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java
@@ -56,10 +56,11 @@ import lombok.RequiredArgsConstructor;
 
 @RequiredArgsConstructor
 @Service
-class ExportService {
+public class ExportService {
 
 	static final String EXPORT_FILENAME_SUFFIX = "_Abgabe.Abgabe.0401.xml";
 	private static final String EXPORT_FILENAME_TEMPLATE = "%s" + EXPORT_FILENAME_SUFFIX;
+	private static final String EXPORT_XDOMEA_FILENAME_TEMPLATE = "%s_Abgabe.Abgabe.0401.xdomea";
 
 	private final XdomeaXmlMarshaller xDomeaXmlMarshaller;
 
@@ -72,6 +73,10 @@ class ExportService {
 	private final ExportNachrichtService exportNachrichtService;
 	private final ExportBescheidService exportBescheidService;
 
+	public String buildXdomeaFileName(String fileNameId) {
+		return String.format(EXPORT_XDOMEA_FILENAME_TEMPLATE, fileNameId);
+	}
+
 	public void writeXdomeaFileContent(String vorgangId, String filenameId, OutputStream outputStream) {
 		var exportData = collectExportData(vorgangId, filenameId);
 		writeZipFile(exportData, outputStream);
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java
index 6fb11b68a9d9edc41668d66a302f3a07c7dabfb3..44c5f661718557c8c10b7f625e06b965cc4f2cd3 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java
@@ -98,8 +98,8 @@ public class VorgangService {
 		return allgemeineMetadatenType;
 	}
 
-	public void lockVorgang(Command command) {
-		ozgCloudCommandService.addSubCommands(buildCreateSubCommandsRequest(command.getId(), buildLockVorgangSubCommand(command)));
+	public void lockVorgang(Command parentCommand) {
+		ozgCloudCommandService.addSubCommands(buildCreateSubCommandsRequest(parentCommand.getId(), buildLockVorgangSubCommand(parentCommand)));
 	}
 
 	OzgCloudCommand buildLockVorgangSubCommand(Command command) {
@@ -129,5 +129,4 @@ public class VorgangService {
 				.executionMode(SUB_COMMAND_EXECUTION_MODE)
 				.build();
 	}
-
 }
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerITCase.java
similarity index 72%
rename from archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java
rename to archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerITCase.java
index e72c6347f66a6c5e27cf33583a37198bcb84a71a..121c50c0f22613bce9ecb97ce1ab1b2a560076c9 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerITCase.java
@@ -21,8 +21,9 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.archive.vorgang;
+package de.ozgcloud.archive.archivierung;
 
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 import org.junit.jupiter.api.Nested;
@@ -31,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.mock.mockito.SpyBean;
 import org.springframework.context.ApplicationEventPublisher;
 
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
 import de.ozgcloud.command.Command;
 import de.ozgcloud.command.CommandCreatedEventTestFactory;
 import de.ozgcloud.command.CommandTestFactory;
@@ -68,4 +70,30 @@ class ArchiveEventListenerITCase {
 			verifyNoInteractions(eventListener);
 		}
 	}
+
+	@Nested
+	class TestOnVorgangLockedEvent {
+
+		private static final Command COMMAND = CommandTestFactory.createBuilder()
+				.createdByClientName(CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME)
+				.build();
+
+		@Test
+		void shouldReactOnOrder() {
+			var event = VorgangLockedEventTestFactory.withCommand(COMMAND);
+			doNothing().when(eventListener).onVorgangLockedEvent(any());
+
+			publisher.publishEvent(event);
+
+			verify(eventListener).onVorgangLockedEvent(event);
+		}
+
+		@Test
+		void shouldNotReactOnOtherOrder() {
+			publisher
+					.publishEvent(VorgangLockedEventTestFactory.withCommand(CommandTestFactory.createBuilder().createdByClientName("OTHER").build()));
+
+			verifyNoInteractions(eventListener);
+		}
+	}
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerTest.java
similarity index 58%
rename from archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java
rename to archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerTest.java
index 0a2f444469ebf75b153eeeb3c64d5bd68f29ed5a..2e8379ee8653f773140c170fa5e453d706b0c9b0 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveEventListenerTest.java
@@ -21,7 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.archive.vorgang;
+package de.ozgcloud.archive.archivierung;
 
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
@@ -40,12 +40,16 @@ import org.mockito.Spy;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.security.core.context.SecurityContext;
 
-import de.ozgcloud.archive.attributes.ClientAttributeService;
 import de.ozgcloud.archive.common.callcontext.CurrentUserService;
+import de.ozgcloud.archive.common.command.CommandService;
+import de.ozgcloud.archive.common.errorhandling.TimeoutException;
+import de.ozgcloud.archive.vorgang.VorgangService;
+import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
 import de.ozgcloud.command.Command;
 import de.ozgcloud.command.CommandCreatedEventTestFactory;
 import de.ozgcloud.command.CommandFailedEvent;
 import de.ozgcloud.command.CommandTestFactory;
+import de.ozgcloud.command.VorgangLockedEvent;
 
 class ArchiveEventListenerTest {
 
@@ -58,11 +62,13 @@ class ArchiveEventListenerTest {
 	@Mock
 	private CurrentUserService currentUserService;
 	@Mock
-	private ClientAttributeService clientAttributeService;
-	@Mock
 	private VorgangService vorgangService;
 	@Mock
 	private ApplicationEventPublisher eventPublisher;
+	@Mock
+	private CommandService commandService;
+	@Mock
+	private ArchiveService archiveService;
 
 	@Captor
 	private ArgumentCaptor<Consumer<Command>> commandExecutorCapture;
@@ -94,7 +100,7 @@ class ArchiveEventListenerTest {
 		void shouldCallSetVorgangArchiving() {
 			doLockVorgang();
 
-			verify(clientAttributeService).setVorgangArchiving(CommandTestFactory.VORGANG_ID);
+			verify(archiveService).setVorgangArchiving(CommandTestFactory.VORGANG_ID);
 		}
 
 		@Test
@@ -165,4 +171,103 @@ class ArchiveEventListenerTest {
 			assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isNotEmpty();
 		}
 	}
+
+	@Nested
+	class TestOnVorgangLockedEvent {
+
+		private final Command command = CommandTestFactory.create();
+		private final VorgangLockedEvent event = new VorgangLockedEvent(command);
+
+		@BeforeEach
+		void mock() {
+			doNothing().when(eventListener).waitForPendingCommandsToFinish(any(), anyLong());
+		}
+
+		@Test
+		void shouldCallWaitForPendingCommandsToFinish() {
+			onVorgangLockedEvent();
+
+			verify(eventListener).waitForPendingCommandsToFinish(CommandTestFactory.VORGANG_ID, ArchiveEventListener.WAIT_INTERVAL);
+		}
+
+		@Test
+		void shouldCallRunWithSecurityContext() {
+			onVorgangLockedEvent();
+
+			verify(eventListener).runWithSecurityContext(eq(command), any());
+		}
+
+		@Nested
+		class TestCommandExecuter {
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(eventListener).runWithSecurityContext(any(), any());
+			}
+
+			@Test
+			void shouldCallRunWithSecurityContext() {
+				onVorgangLockedEvent();
+
+				verify(eventListener).runWithSecurityContext(eq(command), commandExecutorCapture.capture());
+				commandExecutorCapture.getValue().accept(command);
+
+				verify(archiveService).archiveVorgang(command);
+
+			}
+		}
+
+		private void onVorgangLockedEvent() {
+			eventListener.onVorgangLockedEvent(event);
+		}
+	}
+
+	@Nested
+	class TestWaitForPendingCommandsToFinish {
+
+		@Test
+		void shouldCallCommandServiceForPendingCommandsOnce() {
+			when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(false);
+
+			waitForPendingCommandsToFinish();
+
+			verify(commandService).hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, ArchiveEventListener.ARCHIVE_VORGANG_ORDER);
+		}
+
+		@Test
+		void shouldCallCommandServiceForPendingCommandsTwice() {
+			when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(true)
+					.thenReturn(false);
+
+			waitForPendingCommandsToFinish();
+
+			verify(commandService, times(2)).hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID,
+					ArchiveEventListener.ARCHIVE_VORGANG_ORDER);
+		}
+
+		@Test
+		void shouldCallAbortWaitingAfterMaxAttempts() {
+			when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(true);
+
+			var timeoutExceptionThrown = waitForPendingCommandsToFinishAndCatchException();
+
+			verify(commandService, times(ArchiveEventListener.MAXIMUM_CHECKS_FOR_PENDING_COMMANDS))
+					.hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, ArchiveEventListener.ARCHIVE_VORGANG_ORDER);
+			assertThat(timeoutExceptionThrown).isTrue();
+		}
+
+		private boolean waitForPendingCommandsToFinishAndCatchException() {
+			try {
+				waitForPendingCommandsToFinish();
+			} catch (TimeoutException e) {
+				return true;
+			}
+			return false;
+		}
+
+		private void waitForPendingCommandsToFinish() {
+			eventListener.waitForPendingCommandsToFinish(VorgangWithEingangTestFactory.ID, 1);
+		}
+	}
+
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e1213a6c62b4966f2d1299ef6fa42b02dff2db5
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/ArchiveServiceTest.java
@@ -0,0 +1,333 @@
+package de.ozgcloud.archive.archivierung;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.UUID;
+
+import jakarta.activation.DataHandler;
+import jakarta.activation.FileDataSource;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedConstruction;
+import org.mockito.Spy;
+
+import de.ozgcloud.apilib.client_attribute.OzgCloudAccessPermission;
+import de.ozgcloud.apilib.client_attribute.OzgCloudClientAttributeService;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper;
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
+import de.ozgcloud.archive.common.xta.XtaService;
+import de.ozgcloud.archive.export.ExportService;
+import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
+import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory;
+import de.ozgcloud.command.Command;
+import de.ozgcloud.command.CommandTestFactory;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.model.XtaFile;
+import lombok.SneakyThrows;
+
+class ArchiveServiceTest {
+
+	@Spy
+	@InjectMocks
+	private ArchiveService service;
+
+	@Mock
+	private ExportService exportService;
+	@Mock
+	private XtaService xtaService;
+	@Mock
+	private OzgCloudClientAttributeService ozgCloudAttributesService;
+	@Mock
+	private OzgCloudVorgangIdMapper vorgangIdMapper;
+
+	@Nested
+	class TestSetVorgangArchiving {
+
+		@Test
+		void shouldBuildBooleanClientAttribute() {
+			setVorgangArchiving();
+
+			verify(service).buildBooleanClientAttribute(true);
+		}
+
+		@Test
+		void shouldCallVorgangIdMapper() {
+			setVorgangArchiving();
+
+			verify(vorgangIdMapper).fromString(VorgangWithEingangTestFactory.ID);
+		}
+
+		@Test
+		void shouldSetClientAttribute() {
+			var attribute = OzgCloudBooleanClientAttributeTestFactory.create();
+			doReturn(attribute).when(service).buildBooleanClientAttribute(true);
+			when(vorgangIdMapper.fromString(VorgangWithEingangTestFactory.ID)).thenReturn(OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID));
+
+			setVorgangArchiving();
+
+			verify(ozgCloudAttributesService).setClientAttribute(attribute, OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID));
+		}
+
+		private void setVorgangArchiving() {
+			service.setVorgangArchiving(VorgangWithEingangTestFactory.ID);
+		}
+	}
+
+	@Nested
+	class TestBuildBooleanClientAttribute {
+
+		@Test
+		void shouldSetClientName() {
+			var attribute = service.buildBooleanClientAttribute(false);
+
+			assertThat(attribute.getClientName()).isEqualTo(CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME);
+		}
+
+		@Test
+		void shouldSetAccess() {
+			var attribute = service.buildBooleanClientAttribute(false);
+
+			assertThat(attribute.getAccess()).isEqualTo(OzgCloudAccessPermission.READ_ONLY);
+		}
+
+		@Test
+		void shouldSetAttributeName() {
+			var attribute = service.buildBooleanClientAttribute(false);
+
+			assertThat(attribute.getAttributeName()).isEqualTo(ArchiveService.ATTRIBUTE_NAME_ANTRAG_ARCHIVING);
+		}
+
+		@ParameterizedTest
+		@ValueSource(booleans = { true, false })
+		void shouldSetValue(boolean isArchiving) {
+			var attribute = service.buildBooleanClientAttribute(isArchiving);
+
+			assertThat(attribute.getValue()).isEqualTo(isArchiving);
+		}
+	}
+
+	@Nested
+	class TestArchiveVorgang {
+
+		private final Command command = CommandTestFactory.create();
+		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			doReturn(xdomeaFile).when(service).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID);
+		}
+
+		@Test
+		void shouldCallBuildXdomeaXtaFile() {
+			archiveVorgang();
+
+			verify(service).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID);
+		}
+
+		@Test
+		void shouldCallSendXdomeaFile() {
+			archiveVorgang();
+
+			verify(xtaService).sendXdomeaFile(xdomeaFile);
+		}
+
+		private void archiveVorgang() {
+			service.archiveVorgang(command);
+		}
+	}
+
+	@Nested
+	class TestBuildXdomeaXtaFile {
+
+		private final String fileNameId = UUID.randomUUID().toString();
+
+		@BeforeEach
+		void mock() {
+			doReturn(fileNameId).when(service).createFileNameId();
+			when(exportService.buildXdomeaFileName(any())).thenReturn(XdomeaXtaFileTestFactory.FILE_NAME);
+			doReturn(XdomeaXtaFileTestFactory.DATA_HANDLER).when(service).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
+		}
+
+		@Test
+		void shouldCallCreateFileNameId() {
+			buildXdomeaXtaFile();
+
+			verify(service).createFileNameId();
+		}
+
+		@Test
+		void shouldCallBuildXdomeaFileName() {
+			buildXdomeaXtaFile();
+
+			verify(exportService).buildXdomeaFileName(fileNameId);
+		}
+
+		@Test
+		void shouldCallCreateFileContent() {
+			buildXdomeaXtaFile();
+
+			verify(service).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
+		}
+
+		@Test
+		void shouldReturnXdomeaFile() {
+			var xdomeaFile = buildXdomeaXtaFile();
+
+			assertThat(xdomeaFile).usingRecursiveComparison().isEqualTo(XdomeaXtaFileTestFactory.create());
+		}
+
+		private XtaFile buildXdomeaXtaFile() {
+			return service.buildXdomeaXtaFile(VorgangWithEingangTestFactory.ID);
+		}
+	}
+
+	@Nested
+	class TestCreateFileNameId {
+
+		private final UUID uuid = UUID.randomUUID();
+
+		@Test
+		void shouldReturnRandomUUID() {
+			try (var mockedStaticUUID = mockStatic(UUID.class)) {
+				mockedStaticUUID.when(UUID::randomUUID).thenReturn(uuid);
+
+				var returnedFileNameId = service.createFileNameId();
+
+				assertThat(returnedFileNameId).isEqualTo(uuid.toString());
+			}
+		}
+	}
+
+	@Nested
+	class TestCreateFileContent {
+
+		private final String fileNameId = UUID.randomUUID().toString();
+
+		@Nested
+		class TestOnNoExceptionThrown {
+			private MockedConstruction<FileDataSource> fileDataSourceConstruction;
+			private FileDataSource fileDataSource;
+			private File dataSourceFile;
+
+			private MockedConstruction<DataHandler> dataHandlerConstruction;
+			private DataHandler dataHandler;
+			private FileDataSource dataHandlerSource;
+
+			@Mock
+			private File tempFile;
+			@Mock
+			private OutputStream outputStream;
+
+			@BeforeEach
+			@SneakyThrows
+			void setUpMock() {
+				doReturn(tempFile).when(service).createTempFile(fileNameId);
+				fileDataSourceConstruction = mockConstruction(FileDataSource.class,
+						(fileDataSource, context) -> {
+							dataSourceFile = (File) context.arguments().get(0);
+							this.fileDataSource = fileDataSource;
+							when(fileDataSource.getOutputStream()).thenReturn(outputStream);
+						});
+				dataHandlerConstruction = mockConstruction(DataHandler.class, (dataHandler, context) -> {
+					this.dataHandler = dataHandler;
+					dataHandlerSource = (FileDataSource) context.arguments().get(0);
+				});
+			}
+
+			@AfterEach
+			void cleanUp() {
+				fileDataSourceConstruction.close();
+				dataHandlerConstruction.close();
+			}
+
+			@Test
+			@SneakyThrows
+			void shouldCallCreateTempFile() {
+				createFileContent();
+
+				verify(service).createTempFile(fileNameId);
+			}
+
+			@Test
+			void shouldCreateFileDataSourceWithTempFile() {
+				createFileContent();
+
+				assertThat(dataSourceFile).isEqualTo(tempFile);
+			}
+
+			@Test
+			@SneakyThrows
+			void shouldGetOutputStreamOfFileDataSource() {
+				createFileContent();
+
+				verify(fileDataSource).getOutputStream();
+			}
+
+			@Test
+			void shouldWriteXdomeaContentToOutputStream() {
+				createFileContent();
+
+				verify(exportService).writeXdomeaFileContent(VorgangWithEingangTestFactory.ID, fileNameId, outputStream);
+			}
+
+			@Test
+			void shouldConstructDataHandlerFromFileDataSource() {
+				createFileContent();
+
+				assertThat(dataHandlerConstruction.constructed()).hasSize(1);
+				assertThat(dataHandlerSource).isEqualTo(fileDataSource);
+			}
+
+			@Test
+			void shouldReturnDataHandler() {
+				var resultDataHandler = createFileContent();
+
+				assertThat(resultDataHandler).isEqualTo(dataHandler);
+			}
+		}
+
+		@Nested
+		class TestOnIOExceptionThrown {
+			@Test
+			@SneakyThrows
+			void shouldThrowTechnicalExcpetion() {
+				doThrow(IOException.class).when(service).createTempFile(any());
+
+				assertThrows(TechnicalException.class, () -> createFileContent());
+			}
+		}
+
+		private DataHandler createFileContent() {
+			return service.createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
+		}
+	}
+
+	@Nested
+	class TestCreateTempFile {
+
+		private final String fileNameId = UUID.randomUUID().toString();
+
+		@Test
+		@SneakyThrows
+		void shouldReturnFile() {
+			var file = service.createTempFile(fileNameId);
+
+			assertThat(file).isNotNull().isInstanceOf(File.class);
+		}
+	}
+
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/OzgCloudBooleanClientAttributeTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/OzgCloudBooleanClientAttributeTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..954b23b8ace8a76a6951b1e091d090c8c233fee9
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/OzgCloudBooleanClientAttributeTestFactory.java
@@ -0,0 +1,29 @@
+package de.ozgcloud.archive.archivierung;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.apilib.client_attribute.OzgCloudAccessPermission;
+import de.ozgcloud.apilib.client_attribute.OzgCloudBooleanClientAttribute;
+import de.ozgcloud.apilib.client_attribute.OzgCloudBooleanClientAttribute.OzgCloudBooleanClientAttributeBuilder;
+import de.ozgcloud.archive.common.callcontext.CallContextUserTestFactory;
+
+public class OzgCloudBooleanClientAttributeTestFactory {
+
+	private static final boolean VALUE = true;
+	private static final String ATTRIBUTE_NAME = LoremIpsum.getInstance().getWords(1);
+	private static final OzgCloudAccessPermission ACCESS = OzgCloudAccessPermission.READ_ONLY;
+	private static final String CLIENT_NAME = CallContextUserTestFactory.CLIENT_NAME;
+
+	public static OzgCloudBooleanClientAttribute create() {
+		return createBuilder().build();
+	}
+
+	private static OzgCloudBooleanClientAttributeBuilder<?, ?> createBuilder() {
+		return OzgCloudBooleanClientAttribute.builder()
+				.clientName(CLIENT_NAME)
+				.access(ACCESS)
+				.attributeName(ATTRIBUTE_NAME)
+				.value(VALUE);
+	}
+
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/VorgangLockedEventTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/VorgangLockedEventTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fb4dc2005d62f7699d1d6c26ca2e41800df4afc
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/archivierung/VorgangLockedEventTestFactory.java
@@ -0,0 +1,12 @@
+package de.ozgcloud.archive.archivierung;
+
+import de.ozgcloud.command.Command;
+import de.ozgcloud.command.VorgangLockedEvent;
+
+public class VorgangLockedEventTestFactory {
+
+	public static VorgangLockedEvent withCommand(Command command) {
+		return new VorgangLockedEvent(command);
+	}
+
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java
index 517fbd26e956a7ba10fdb503a6dfbf6e1c0ecfc4..27f26a2fdebd76cb97a6fd81379f40d5314e2ed7 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandRemoteServiceTest.java
@@ -34,6 +34,8 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.InjectMocks;
@@ -48,6 +50,8 @@ import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
 import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub;
 import de.ozgcloud.vorgang.grpc.command.GrpcCommand;
 import de.ozgcloud.vorgang.grpc.command.GrpcCommandsResponse;
+import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest;
+import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsResponse;
 import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest;
 
 class CommandRemoteServiceTest {
@@ -187,4 +191,67 @@ class CommandRemoteServiceTest {
 		}
 	}
 
+	@Nested
+	class TestHasPendingCommands {
+
+		private final GrpcExistsPendingCommandsRequest request = GrpcExistsPendingCommandsRequestTestFactory.create();
+
+		@Mock
+		private CommandServiceBlockingStub serviceStubWithInterceptor;
+
+		@BeforeEach
+		void mock() {
+			doReturn(serviceStubWithInterceptor).when(service).getGrpcServiceWithInterceptor();
+			doReturn(request).when(service).buildHasPendingCommandRequest(VorgangWithEingangTestFactory.ID);
+			var response = GrpcExistsPendingCommandsResponse.newBuilder().setExistsPendingCommands(true).build();
+			when(serviceStubWithInterceptor.existsPendingCommands(any())).thenReturn(response);
+		}
+
+		@Test
+		void shouldCallBuildHasPendingCommandRequest() {
+			hasPendingCommands();
+
+			verify(service).buildHasPendingCommandRequest(VorgangWithEingangTestFactory.ID);
+		}
+
+		@Test
+		void shouldCallGetCommandServiceStub() {
+			hasPendingCommands();
+
+			verify(service).getGrpcServiceWithInterceptor();
+		}
+
+		@Test
+		void shouldCallServiceStubWithInterceptor() {
+			hasPendingCommands();
+
+			verify(serviceStubWithInterceptor).existsPendingCommands(request);
+		}
+
+		@ParameterizedTest
+		@ValueSource(booleans = { true, false })
+		void shouldReturnIfCommandsArePending(boolean hasPendingCommands) {
+			var response = GrpcExistsPendingCommandsResponse.newBuilder().setExistsPendingCommands(hasPendingCommands).build();
+			when(serviceStubWithInterceptor.existsPendingCommands(any())).thenReturn(response);
+
+			var result = hasPendingCommands();
+
+			assertThat(result).isEqualTo(hasPendingCommands);
+		}
+
+		private boolean hasPendingCommands() {
+			return service.hasPendingCommands(VorgangWithEingangTestFactory.ID);
+		}
+	}
+
+	@Nested
+	class TestBuildHasPendingCommandRequest {
+
+		@Test
+		void shouldReturnRequest() {
+			var request = service.buildHasPendingCommandRequest(VorgangWithEingangTestFactory.ID);
+
+			assertThat(request).isEqualTo(GrpcExistsPendingCommandsRequestTestFactory.create());
+		}
+	}
 }
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java
index 493b639403a05b9e953f66b63ecf2c085fe41dc3..b4a09e172312f7e956b92cd758c662649ba69e7e 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java
@@ -23,8 +23,12 @@
  */
 package de.ozgcloud.archive.common.command;
 
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 
 import org.junit.jupiter.api.Nested;
@@ -33,6 +37,11 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId;
 import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
 
 class CommandServiceTest {
@@ -41,6 +50,8 @@ class CommandServiceTest {
 	private CommandService service;
 	@Mock
 	private CommandRemoteService remoteService;
+	@Mock
+	private OzgCloudCommandService ozgCloudCommandService;
 
 	@Nested
 	class TestFindFinishedCommands {
@@ -54,4 +65,50 @@ class CommandServiceTest {
 			verify(remoteService).findCommands(VorgangWithEingangTestFactory.ID, Optional.of(VORGANG_STATUS_FINISHED), Optional.empty());
 		}
 	}
+
+	@Nested
+	class TestHasPendingCommandsExceptArchive {
+
+		private final String order = LoremIpsum.getInstance().getWords(1);
+
+		@Test
+		void shouldCallOzgCloudCommandService() {
+			hasPendingCommandsExceptWithOrder();
+
+			verify(ozgCloudCommandService).getPendingCommands(OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID));
+		}
+
+		@Test
+		void shouldReturnFalseOnNoPendingCommands() {
+			when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(Collections.emptyList());
+
+			var result = hasPendingCommandsExceptWithOrder();
+
+			assertThat(result).isFalse();
+		}
+
+		@Test
+		void shouldReturnTrueOnPendingCommands() {
+			when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(List.of(OzgCloudCommandTestFactory.create()));
+
+			var result = hasPendingCommandsExceptWithOrder();
+
+			assertThat(result).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseOnCommandWithExcpetionOrder() {
+			when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(List.of(OzgCloudCommandTestFactory.createBuilder()
+					.order(order)
+					.build()));
+
+			var result = hasPendingCommandsExceptWithOrder();
+
+			assertThat(result).isFalse();
+		}
+
+		private boolean hasPendingCommandsExceptWithOrder() {
+			return service.hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, order);
+		}
+	}
 }
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/GrpcExistsPendingCommandsRequestTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/GrpcExistsPendingCommandsRequestTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a5780c56ebb1bf57a717f87f704f0cb4da390ff
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/GrpcExistsPendingCommandsRequestTestFactory.java
@@ -0,0 +1,18 @@
+package de.ozgcloud.archive.common.command;
+
+import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
+import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest;
+import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest.Builder;
+
+public class GrpcExistsPendingCommandsRequestTestFactory {
+	public static final String VORGAND_ID = VorgangWithEingangTestFactory.ID.toString();
+
+	public static GrpcExistsPendingCommandsRequest create() {
+		return createBuilder().build();
+	}
+
+	public static Builder createBuilder() {
+		return GrpcExistsPendingCommandsRequest.newBuilder()
+				.setVorgangId(VORGAND_ID);
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..be5d9a974e360c0fdea92a0261e52a7c150553f1
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java
@@ -0,0 +1,48 @@
+package de.ozgcloud.archive.common.xta;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Spy;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import lombok.SneakyThrows;
+
+class JsonToXtaIdentifierListConverterTest {
+
+	@InjectMocks
+	private JsonToXtaIdentifierListConverter converter;
+
+	@Spy
+	private ObjectMapper objectMapper;
+
+	@Nested
+	class TestConvert {
+
+		@Test
+		void shouldReturnListOfXtaIdentifier() {
+			var jsonInput = XtaIdentifierTestFactory.createAsJson();
+
+			var identifiers = converter.convert(jsonInput);
+
+			assertThat(identifiers).usingRecursiveFieldByFieldElementComparator().containsExactly(XtaIdentifierTestFactory.create());
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldThrowTechnicalException() {
+			doThrow(JsonProcessingException.class).when(objectMapper).readValue(anyString(), any(TypeReference.class));
+
+			assertThrows(TechnicalException.class, () -> converter.convert("invalid input"));
+		}
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..35f2f02f7a09728f1293a89fa4c808c44aecdf91
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java
@@ -0,0 +1,30 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.UUID;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.xta.client.model.XtaIdentifier;
+import de.ozgcloud.xta.client.model.XtaIdentifier.XtaIdentifierBuilder;
+
+public class XtaIdentifierTestFactory {
+
+	public static final String CATEGORY = LoremIpsum.getInstance().getWords(1);
+	public static final String VALUE = UUID.randomUUID().toString();
+	public static final String NAME = LoremIpsum.getInstance().getName();
+
+	public static XtaIdentifier create() {
+		return createBuilder().build();
+	}
+
+	public static XtaIdentifierBuilder createBuilder() {
+		return XtaIdentifier.builder()
+				.name(NAME)
+				.value(VALUE)
+				.category(CATEGORY);
+	}
+
+	public static String createAsJson() {
+		return "[{\"category\":\"%s\",\"name\":\"%s\",\"value\":\"%s\"}]".formatted(CATEGORY, NAME, VALUE);
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..536adb305f6e1acdac5731ff29f1c78eca0fec9a
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java
@@ -0,0 +1,186 @@
+package de.ozgcloud.archive.common.xta;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Spy;
+
+import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.XtaClient;
+import de.ozgcloud.xta.client.exception.XtaClientException;
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaMessage;
+import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator;
+import lombok.SneakyThrows;
+
+class XtaServiceTest {
+
+	@Spy
+	@InjectMocks
+	private XtaService service;
+
+	@Mock
+	private XtaClient xtaClient;
+
+	@Nested
+	class TestSendXdomeaFile {
+
+		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
+		@Mock
+		private XtaMessage xtaMessage;
+
+		@BeforeEach
+		void mock() {
+			doReturn(xtaMessage).when(service).createMessage(xdomeaFile);
+			doReturn(xtaClient).when(service).getXtaClient();
+		}
+
+		@Test
+		void shouldGetXtaClient() {
+			sendXdomeaFile();
+
+			verify(service).getXtaClient();
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldCallCreateMessage() {
+			sendXdomeaFile();
+
+			verify(service).createMessage(xdomeaFile);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldSendMessage() {
+			sendXdomeaFile();
+
+			verify(xtaClient).sendMessage(xtaMessage);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldThrowTechnicalException() {
+			when(xtaClient.sendMessage(any())).thenThrow(XtaClientException.class);
+
+			assertThrows(TechnicalException.class, () -> sendXdomeaFile());
+		}
+
+		private void sendXdomeaFile() {
+			service.sendXdomeaFile(xdomeaFile);
+		}
+	}
+
+	@Nested
+	class TestCreateMessage {
+		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
+
+		private MockedStatic<XdomeaXtaMessageCreator> mockedStaticXdomeaXtaMessageCreator;
+
+		@Mock
+		private XdomeaXtaMessageCreator xdomeaXtaMessageCreator;
+		@Mock
+		private XtaMessage xtaMessage;
+
+		@BeforeEach
+		void setUpMock() {
+			mockedStaticXdomeaXtaMessageCreator = mockStatic(XdomeaXtaMessageCreator.class);
+			mockedStaticXdomeaXtaMessageCreator.when(XdomeaXtaMessageCreator::createInstance).thenReturn(xdomeaXtaMessageCreator);
+		}
+
+		@AfterEach
+		void cleanUp() {
+			mockedStaticXdomeaXtaMessageCreator.close();
+		}
+
+		@Test
+		void shouldCreateXdomeaXtaMessageCreator() {
+			createMessage();
+
+			mockedStaticXdomeaXtaMessageCreator.verify(XdomeaXtaMessageCreator::createInstance);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldCallCreateMessage() {
+			createMessage();
+
+			verify(xdomeaXtaMessageCreator).createMessage(xdomeaFile);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldReturnMessage() {
+			when(xdomeaXtaMessageCreator.createMessage(any())).thenReturn(xtaMessage);
+
+			var message = createMessage();
+
+			assertThat(message).isEqualTo(xtaMessage);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldThrowTechnicalException() {
+			when(xdomeaXtaMessageCreator.createMessage(any())).thenThrow(XtaClientException.class);
+
+			assertThrows(TechnicalException.class, () -> createMessage());
+		}
+
+		private XtaMessage createMessage() {
+			return service.createMessage(xdomeaFile);
+		}
+	}
+
+	@Nested
+	class TestGetXtaClient {
+
+		private XtaService xtaService;
+
+		@Nested
+		class TestOnConfiguredXtaClient {
+
+			@BeforeEach
+			void givenXtaClientConfigured() {
+				xtaService = spy(new XtaService(Optional.of(xtaClient)));
+			}
+
+			@Test
+			void shouldReturnXtaClient() {
+				var returnedXtaClient = getXtaClient();
+
+				assertThat(returnedXtaClient).isSameAs(xtaClient);
+			}
+
+		}
+
+		@Nested
+		class TestOnUnconfiguredXtaClient {
+
+			@BeforeEach
+			void givenXtaClientNotConfigured() {
+				xtaService = spy(new XtaService(Optional.empty()));
+			}
+
+			@Test
+			void shouldThrowTechnicalException() {
+				assertThrows(TechnicalException.class, () -> getXtaClient());
+			}
+		}
+
+		private XtaClient getXtaClient() {
+			return xtaService.getXtaClient();
+		}
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java
index 42c3ceed2734357237282b51f6c101a99a5c2680..a783e3294b091987560488060a093cca416a806f 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java
@@ -122,7 +122,7 @@ class ExportGrpcServiceITCase {
 		}
 
 		@Nested
-		class OnMinimalVorgang {
+		class TestOnMinimalVorgang {
 
 			@BeforeEach
 			void setUpMock() {
@@ -159,7 +159,7 @@ class ExportGrpcServiceITCase {
 		}
 
 		@Nested
-		class OnVorgangWithKommentarAndAttachment {
+		class TestOnVorgangWithKommentarAndAttachment {
 			private final String attachmentContent = LoremIpsum.getInstance().getWords(5);
 
 			@BeforeEach
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java
index 68c2d08c0c8c667cdb647936c8023e2998c8c8cc..52694de1c9a693475348ab5174472e74be5de8f3 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceTest.java
@@ -78,37 +78,38 @@ class ExportGrpcServiceTest {
 		void setUpMocks() {
 			doReturn(fileNameId).when(service).createFileNameId();
 			doReturn(downloader).when(service).buildExportDownloader(VorgangWithEingangTestFactory.ID, fileNameId, responseObserver);
+			doNothing().when(service).sendFileName(any(), any());
 		}
 
 		@Test
 		void shouldCreateFileNameId() {
-			callService();
+			exportVorgang();
 
 			verify(service).createFileNameId();
 		}
 
 		@Test
 		void shouldSendFileName() {
-			callService();
+			exportVorgang();
 
 			verify(service).sendFileName(responseObserver, fileNameId);
 		}
 
 		@Test
 		void shouldBuildExportDownloader() {
-			callService();
+			exportVorgang();
 
 			verify(service).buildExportDownloader(VorgangWithEingangTestFactory.ID, fileNameId, responseObserver);
 		}
 
 		@Test
 		void shouldStartDownloader() {
-			callService();
+			exportVorgang();
 
 			verify(downloader).start();
 		}
 
-		private void callService() {
+		private void exportVorgang() {
 			service.exportVorgang(request, responseObserver);
 		}
 	}
@@ -141,17 +142,20 @@ class ExportGrpcServiceTest {
 		private final String fileNameId = UUID.randomUUID().toString();
 		private final String fileName = LoremIpsum.getInstance().getName();
 
+		@BeforeEach
+		void mock() {
+			when(exportService.buildXdomeaFileName(fileNameId)).thenReturn(fileName);
+		}
+
 		@Test
 		void shouldCallBuildXdomeaFileName() {
 			sendFileName();
 
-			verify(service).buildXdomeaFileName(fileNameId);
+			verify(exportService).buildXdomeaFileName(fileNameId);
 		}
 
 		@Test
 		void shouldSendFileName() {
-			doReturn(fileName).when(service).buildXdomeaFileName(fileNameId);
-
 			sendFileName();
 
 			verify(responseObserver).onNext(argThat((response) -> response.getVorgangFile().getFileName().equals(fileName)));
@@ -259,17 +263,4 @@ class ExportGrpcServiceTest {
 
 		}
 	}
-
-	@Nested
-	class TestBuildXdomeaFileName {
-
-		private final String id = UUID.randomUUID().toString();
-
-		@Test
-		void shouldReturnFileName() {
-			var fileName = service.buildXdomeaFileName(id);
-
-			assertThat(fileName).isEqualTo(id + "_Abgabe.Abgabe.0401.xdomea");
-		}
-	}
 }
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java
index 4e596932b22ff474e755f1b1369d429835cb6c52..08221c17a7dff76148d00a4dc20c13cc8886560a 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java
@@ -54,6 +54,7 @@ import de.ozgcloud.archive.bescheid.ExportBescheidService;
 import de.ozgcloud.archive.common.ExportFilenameGenerator;
 import de.ozgcloud.archive.common.HistorienProtokollInformationTypeTestFactory;
 import de.ozgcloud.archive.common.XDomeaTestUtils;
+import de.ozgcloud.archive.common.xta.XtaService;
 import de.ozgcloud.archive.file.ExportFileService;
 import de.ozgcloud.archive.file.OzgFile;
 import de.ozgcloud.archive.file.OzgFileTestFactory;
@@ -100,6 +101,8 @@ class ExportServiceTest {
 	private ExportNachrichtService exportNachrichtService;
 	@Mock
 	private ExportBescheidService exportBescheidService;
+	@Mock
+	private XtaService xtaService;
 
 	@DisplayName("Write Xdomea File")
 	@Nested
@@ -665,4 +668,18 @@ class ExportServiceTest {
 			assertThat(formEngineName).isEqualTo(EingangHeaderTestFactory.FORM_ENGINE_NAME);
 		}
 	}
+
+	@Nested
+	class TestBuildXdomeaFileName {
+
+		private final String id = UUID.randomUUID().toString();
+
+		@Test
+		void shouldReturnFileName() {
+			var fileName = service.buildXdomeaFileName(id);
+
+			assertThat(fileName).isEqualTo(id + "_Abgabe.Abgabe.0401.xdomea");
+		}
+	}
+
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java
index cb8c7167208f4591816aa16b83f1ffab7e9eeeed..265be54c9f8fcaa4ebd1d17c2b256fb07442f357 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/GrpcIntegrationTestConfiguration.java
@@ -39,5 +39,4 @@ import net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguratio
 })
 @ComponentScan({ "de.ozgcloud.*" })
 public class GrpcIntegrationTestConfiguration {
-
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java
index d6c0b70d93b3fad5af0772dac927581a48c19edd..e5c9b728a196f3c6331de4f6f4e9a3e5d4c4e261 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java
@@ -71,7 +71,7 @@ class XdomeaPropertiesValidatorTest {
 		}
 
 		@Nested
-		class OnUriNotSet {
+		class TestOnUriNotSet {
 
 			private static final String PROPERTY_NAME = "behoerdenschluesselUri";
 			public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME;
@@ -113,7 +113,7 @@ class XdomeaPropertiesValidatorTest {
 		}
 
 		@Nested
-		class OnVersionNotSet {
+		class TestOnVersionNotSet {
 
 			public static final String PROPERTY_NAME = "behoerdenschluesselVersion";
 			public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME;
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java
index a81cf33e3e421c9f43546aa8891c9f1006aaf625..cdb972dc4e6495e1b71d7ce3e7588f26fd0a0084 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java
@@ -216,7 +216,7 @@ class KopfCreatorTest {
 	class TestCreateKontaktType {
 
 		@Nested
-		class OnBehoerdenschluesselNotSet {
+		class TestOnBehoerdenschluesselNotSet {
 
 			@ParameterizedTest
 			@NullAndEmptySource
@@ -240,7 +240,7 @@ class KopfCreatorTest {
 		}
 
 		@Nested
-		class OnBehoerdenschluesselSet {
+		class TestOnBehoerdenschluesselSet {
 
 			private static final BehoerdenkennungType expectedValue = new BehoerdenkennungType();
 
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java
index e5e23a8c0935db70042829ef6da1662496b636bc..3d5fc793a3dbdbd9cfe70a2f13a32f7fef8b3dff 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java
@@ -24,6 +24,7 @@
 package de.ozgcloud.archive.vorgang;
 
 import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 import java.util.Map;
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/XdomeaXtaFileTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/XdomeaXtaFileTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..3743f9d26eec05088a3935348f31aa5cc4821e45
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/XdomeaXtaFileTestFactory.java
@@ -0,0 +1,34 @@
+package de.ozgcloud.archive.vorgang;
+
+import jakarta.activation.DataHandler;
+import jakarta.activation.DataSource;
+
+import org.mockito.Mock;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaFile.XtaFileBuilder;
+import lombok.SneakyThrows;
+
+public class XdomeaXtaFileTestFactory {
+
+	public static final String FILE_NAME = LoremIpsum.getInstance().getWords(1);
+
+	@Mock
+	public static DataSource DATA_SOURCE;
+
+	public static final DataHandler DATA_HANDLER = new DataHandler(DATA_SOURCE);
+
+	public static XtaFile create() {
+		return createBuilder().build();
+	}
+
+	@SneakyThrows
+	public static XtaFileBuilder createBuilder() {
+		return XtaFile.builder()
+				.content(DATA_HANDLER)
+				.name(FILE_NAME)
+				.contentType("application/zip");
+	}
+}
diff --git a/archive-manager-server/src/test/resources/application-itcase.yaml b/archive-manager-server/src/test/resources/application-itcase.yaml
index 04ca541b6f2396d09a347684021e152ce0812abe..9bd1a3bb14e6dac750aca9251cb49cad90684702 100644
--- a/archive-manager-server/src/test/resources/application-itcase.yaml
+++ b/archive-manager-server/src/test/resources/application-itcase.yaml
@@ -3,6 +3,15 @@ ozgcloud:
     behoerdenschluessel: ABC
     behoerdenschluesselUri: http://meine.behoer.de
     behoerdenschluesselVersion: 1.0.15b
+  xta:
+    sendServiceUrl: https://my-xta-server.de/MB_XTA-WS/XTA210sendPort.svc
+    msgBoxServiceUrl: https://my-xta-server.de/MB_XTA-WS/XTA210msgBoxPort.svc
+    managementServiceUrl: https://my-xta-server.de/MB_XTA-WS/XTA210managementPort.svc
+    maxListItems: 5
+    keystore:
+      file: classpath:xtaTestStore.p12
+      password: changeit
+    clientIdentifiers: '[{"category":"Generischer Antragsempfänger","name":"ozg-cloud dev","value":"gae:dev-environment@ozg-cloud.de"}]'
 
 grpc:
   server:
diff --git a/archive-manager-server/src/test/resources/xtaTestStore.p12 b/archive-manager-server/src/test/resources/xtaTestStore.p12
new file mode 100644
index 0000000000000000000000000000000000000000..a0cc212c49745a428186d0d4f2f73dd6ac7f24ff
Binary files /dev/null and b/archive-manager-server/src/test/resources/xtaTestStore.p12 differ
diff --git a/pom.xml b/pom.xml
index 8a2a1c0d314c0660bb33dff0b13bb51f233776bc..2f8e05ec7188ed7f0f76945c904d73eb489ab225 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,11 +53,12 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<vorgang-manager.version>2.18.0</vorgang-manager.version>
 		<nachrichten-manager.version>2.15.0</nachrichten-manager.version>
-		<api-lib.version>0.14.0</api-lib.version>
+		<api-lib.version>0.16.0-SNAPSHOT</api-lib.version>
 		<find-and-replace-maven-plugin.version>1.2.0</find-and-replace-maven-plugin.version>
 		<protoc-jar-plugin.version>3.11.4</protoc-jar-plugin.version>
 		<ozgcloud-common.version>4.7.0</ozgcloud-common.version>
 		<document-manager.version>1.1.0</document-manager.version>
+		<xta-client-lib.version>0.1.0</xta-client-lib.version>
 	</properties>
 	<dependencyManagement>
 		<dependencies>
@@ -107,6 +108,11 @@
 				<artifactId>document-manager-interface</artifactId>
 				<version>${document-manager.version}</version>
 			</dependency>
+			<dependency>
+				<groupId>de.ozgcloud.xta</groupId>
+				<artifactId>xta-client-lib</artifactId>
+				<version>${xta-client-lib.version}</version>
+			</dependency>
 
 			<!-- test -->
 			<dependency>