diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudFileService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudFileService.java
index dc5f3852f2f4c538b782c0d0adf60a7f120b74b5..e9b82efd4c69c629c0b01d7a074ef1f076f5d737 100644
--- a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudFileService.java
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudFileService.java
@@ -1,5 +1,6 @@
 package de.ozgcloud.apilib.file;
 
+import java.io.InputStream;
 import java.io.OutputStream;
 
 public interface OzgCloudFileService {
@@ -7,4 +8,6 @@ public interface OzgCloudFileService {
 	OzgCloudFile getFile(OzgCloudFileId id);
 
 	void writeFileDataToStream(OzgCloudFileId id, OutputStream streamToWriteData);
+
+	OzgCloudFileId uploadFile(OzgCloudUploadFile file, InputStream dataStream);
 }
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudUploadFile.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudUploadFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..fed2503ff74b805ca65b7d9a3d93160cbeb70b89
--- /dev/null
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/OzgCloudUploadFile.java
@@ -0,0 +1,14 @@
+package de.ozgcloud.apilib.file;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Builder
+@Getter
+public class OzgCloudUploadFile {
+
+	private String fileName;
+	private String contentType;
+	private String vorgangId;
+	private String fieldName;
+}
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/dummy/DummyOzgCloudFileService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/dummy/DummyOzgCloudFileService.java
index 367db8f4899b22062a28cceb55e649ff17900d97..03a5bbd363d6cfe17236e70f0211d8e5df59ecbe 100644
--- a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/dummy/DummyOzgCloudFileService.java
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/dummy/DummyOzgCloudFileService.java
@@ -1,14 +1,17 @@
 package de.ozgcloud.apilib.file.dummy;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.file.OzgCloudFile;
 import de.ozgcloud.apilib.file.OzgCloudFileId;
 import de.ozgcloud.apilib.file.OzgCloudFileService;
+import de.ozgcloud.apilib.file.OzgCloudUploadFile;
 import de.ozgcloud.common.errorhandling.TechnicalException;
 
 @Service
@@ -34,8 +37,14 @@ public class DummyOzgCloudFileService implements OzgCloudFileService {
 		try {
 			streamToWriteData.write(TEST_DATA);
 		} catch (IOException e) {
-			throw new TechnicalException("Erro wrting dummy data.", e);
+			throw new TechnicalException("Error writing dummy data.", e);
 		}
 	}
 
+	@Override
+	public OzgCloudFileId uploadFile(OzgCloudUploadFile file, InputStream dataStream) {
+		IOUtils.closeQuietly(dataStream);
+		return OzgCloudFileId.from("%s-%s".formatted(file.getFileName(), file.getVorgangId()));
+	}
+
 }
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java
index 139931e2c9c5b6ef6d7b5b9f4a4d57b52b9da3c7..a3a6af6ba7375e0ef74b9e6b208a120f3f160dab 100644
--- a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java
@@ -1,5 +1,6 @@
 package de.ozgcloud.apilib.file.grpc;
 
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
@@ -7,23 +8,34 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.logging.Level;
 
+import org.apache.commons.io.IOUtils;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.stereotype.Service;
 
+import com.google.protobuf.ByteString;
+
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.apilib.common.errorhandling.NotFoundException;
 import de.ozgcloud.apilib.file.OzgCloudFile;
 import de.ozgcloud.apilib.file.OzgCloudFileId;
 import de.ozgcloud.apilib.file.OzgCloudFileService;
+import de.ozgcloud.apilib.file.OzgCloudUploadFile;
 import de.ozgcloud.common.binaryfile.FileId;
+import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils;
+import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender;
 import de.ozgcloud.common.errorhandling.TechnicalException;
 import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub;
 import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcBinaryFilesRequest;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcFindFilesResponse;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcGetBinaryFileDataRequest;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse;
 import de.ozgcloud.vorgang.grpc.file.GrpcOzgFile;
+import io.grpc.stub.CallStreamObserver;
+import io.grpc.stub.StreamObserver;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.java.Log;
 import net.devh.boot.grpc.client.inject.GrpcClient;
@@ -54,8 +66,8 @@ public class GrpcOzgCloudFileService implements OzgCloudFileService {
 
 	GrpcBinaryFilesRequest buildFindFileRequest(OzgCloudFileId id) {
 		return GrpcBinaryFilesRequest.newBuilder()
-				.addFileId(id.toString())
-				.build();
+			.addFileId(id.toString())
+			.build();
 	}
 
 	GrpcOzgFile getSingleResponse(GrpcFindFilesResponse response, OzgCloudFileId id) {
@@ -99,7 +111,53 @@ public class GrpcOzgCloudFileService implements OzgCloudFileService {
 		return blockingStub.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider));
 	}
 
+	@Override
+	public OzgCloudFileId uploadFile(OzgCloudUploadFile uploadFile, InputStream dataStream) {
+		var resultFuture = GrpcFileUploadUtils.createSender(this::buildChunkRequest, dataStream, this::buildCallStreamObserver)
+			.withMetaData(buildMetaDataRequest(uploadFile))
+			.send();
+		var uploadBinaryFileResponse = waitUntilFutureToComplete(resultFuture, dataStream);
+		return OzgCloudFileId.from(uploadBinaryFileResponse.getFileId());
+	}
+
+	GrpcUploadBinaryFileRequest buildChunkRequest(byte[] bytes, Integer length) {
+		return GrpcUploadBinaryFileRequest.newBuilder().setFileContent((ByteString.copyFrom(bytes, 0, length))).build();
+	}
+
+	CallStreamObserver<GrpcUploadBinaryFileRequest> buildCallStreamObserver(
+		StreamObserver<GrpcUploadBinaryFileResponse> responseObserver) {
+		return (CallStreamObserver<GrpcUploadBinaryFileRequest>) getAsyncServiceStub().uploadBinaryFileAsStream(responseObserver);
+	}
+
 	BinaryFileServiceStub getAsyncServiceStub() {
 		return asyncServiceStub.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider));
 	}
+
+	GrpcUploadBinaryFileRequest buildMetaDataRequest(OzgCloudUploadFile uploadFile) {
+		return GrpcUploadBinaryFileRequest.newBuilder()
+			.setMetadata(GrpcUploadBinaryFileMetaData.newBuilder()
+				.setFileName(uploadFile.getFileName())
+				.setContentType(uploadFile.getContentType())
+				.setVorgangId(uploadFile.getVorgangId())
+				.setField(uploadFile.getFieldName())
+				.build())
+			.build();
+	}
+
+	GrpcUploadBinaryFileResponse waitUntilFutureToComplete(FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> fileSender,
+		InputStream fileContentStream) {
+		try {
+			return fileSender.getResultFuture().get(10, TimeUnit.MINUTES);
+		} catch (InterruptedException e) {
+			Thread.currentThread().interrupt();
+			fileSender.cancelOnError(e);
+			throw new TechnicalException("Waiting for finishing upload was interrupted.", e);
+		} catch (ExecutionException | TimeoutException e) {
+			fileSender.cancelOnTimeout();
+			throw new TechnicalException("Error / Timeout on uploading data.", e);
+		} finally {
+			IOUtils.closeQuietly(fileContentStream);
+		}
+	}
+
 }
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/file/OzgCloudUploadFileTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/OzgCloudUploadFileTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..18ea65029ef254594100ef67b3d5d3bdaac9855b
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/OzgCloudUploadFileTestFactory.java
@@ -0,0 +1,24 @@
+package de.ozgcloud.apilib.file;
+
+import de.ozgcloud.apilib.file.OzgCloudUploadFile.OzgCloudUploadFileBuilder;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory;
+
+public class OzgCloudUploadFileTestFactory {
+
+	public static final String FILE_NAME = "test.txt";
+	public static final String CONTENT_TYPE = "text/plain";
+	public static final String FIELD_NAME = "field";
+
+	public static OzgCloudUploadFile create() {
+		return createBuilder().build();
+	}
+
+	private static OzgCloudUploadFileBuilder createBuilder() {
+		return OzgCloudUploadFile.builder()
+			.fileName(FILE_NAME)
+			.contentType(CONTENT_TYPE)
+			.vorgangId(OzgCloudVorgangTestFactory.ID.toString())
+			.fieldName(FIELD_NAME);
+	}
+
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java
index 7886016ee152f5479471a94cb31ad90150118317..8a648e34e975be9adb94b28ec9ae85848228e5f4 100644
--- a/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java
@@ -1,29 +1,55 @@
 package de.ozgcloud.apilib.file.grpc;
 
 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.InputStream;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.commons.io.IOUtils;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.mapstruct.factory.Mappers;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.Spy;
 
 import de.ozgcloud.apilib.common.errorhandling.NotFoundException;
 import de.ozgcloud.apilib.file.OzgCloudFileTestFactory;
+import de.ozgcloud.apilib.file.OzgCloudUploadFileTestFactory;
+import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils;
+import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender;
+import de.ozgcloud.common.errorhandling.TechnicalException;
 import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub;
+import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcFindFilesResponse;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse;
+import io.grpc.stub.CallStreamObserver;
+import io.grpc.stub.StreamObserver;
+import lombok.SneakyThrows;
 
 class GrpcOzgCloudFileServiceTest {
 
+	@Spy
 	@InjectMocks
 	private GrpcOzgCloudFileService service;
 
 	@Mock
 	private BinaryFileServiceBlockingStub blockingStub;
+	@Mock
+	private BinaryFileServiceStub asyncServiceStub;
 	@Spy
 	private OzgCloudFileMapper mapper = Mappers.getMapper(OzgCloudFileMapper.class);
 
@@ -35,7 +61,8 @@ class GrpcOzgCloudFileServiceTest {
 			@BeforeEach
 			void init() {
 				when(blockingStub.withInterceptors(any())).thenReturn(blockingStub);
-				when(blockingStub.findBinaryFilesMetaData(any())).thenReturn(GrpcFindFilesResponse.newBuilder().addFile(GrpcOzgFileTestFactory.create()).build());
+				when(blockingStub.findBinaryFilesMetaData(any())).thenReturn(
+					GrpcFindFilesResponse.newBuilder().addFile(GrpcOzgFileTestFactory.create()).build());
 			}
 
 			@Test
@@ -76,7 +103,7 @@ class GrpcOzgCloudFileServiceTest {
 			@Test
 			void shouldReturnFirstFile() {
 				var response = GrpcFindFilesResponseTestFactory.createBuilder().addFile(GrpcOzgFileTestFactory.createBuilder().setId("2").build())
-						.build();
+					.build();
 
 				var result = service.getSingleResponse(response, OzgCloudFileTestFactory.ID);
 
@@ -88,9 +115,273 @@ class GrpcOzgCloudFileServiceTest {
 				var response = GrpcFindFilesResponseTestFactory.createBuilder().clearFile().build();
 
 				assertThatThrownBy(() -> service.getSingleResponse(response, OzgCloudFileTestFactory.ID))
-						.isInstanceOf(NotFoundException.class);
+					.isInstanceOf(NotFoundException.class);
 			}
 		}
 	}
 
+	@Nested
+	class TestUploadFile {
+
+		@Nested
+		class TestUploadFileData {
+
+			@Mock
+			private FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> fileSender;
+			@Mock
+			private GrpcUploadBinaryFileRequest uploadBinaryFileRequest;
+
+			GrpcUploadBinaryFileResponse response = GrpcUploadBinaryFileResponse.newBuilder().setFileId(OzgCloudFileTestFactory.ID.toString())
+				.build();
+
+			@BeforeEach
+			void init() {
+				doReturn(response).when(service).waitUntilFutureToComplete(any(), any());
+			}
+
+			@Test
+			void shouldCallCreateSender() {
+				when(fileSender.withMetaData(any())).thenReturn(fileSender);
+				try (var uploadUtils = Mockito.mockStatic(GrpcFileUploadUtils.class)) {
+					uploadUtils.when(() -> GrpcFileUploadUtils.createSender(any(), any(), any())).thenReturn(fileSender);
+					var dataStream = InputStream.nullInputStream();
+
+					service.uploadFile(OzgCloudUploadFileTestFactory.create(), dataStream);
+
+					uploadUtils.verify(() -> GrpcFileUploadUtils.createSender(any(), eq(dataStream), any()));
+				}
+			}
+
+			@Test
+			void shouldCallBuildMetadataRequest() {
+				when(asyncServiceStub.withInterceptors(any())).thenReturn(asyncServiceStub);
+				var file = OzgCloudUploadFileTestFactory.create();
+
+				service.uploadFile(file, InputStream.nullInputStream());
+
+				verify(service).buildMetaDataRequest(file);
+			}
+
+			@Test
+			void shoudlSetMetadata() {
+				try (var uploadUtils = Mockito.mockStatic(GrpcFileUploadUtils.class)) {
+					uploadUtils.when(() -> GrpcFileUploadUtils.createSender(any(), any(), any())).thenReturn(fileSender);
+					when(fileSender.withMetaData(any())).thenReturn(fileSender);
+					doReturn(uploadBinaryFileRequest).when(service).buildMetaDataRequest(any());
+
+					service.uploadFile(OzgCloudUploadFileTestFactory.create(), InputStream.nullInputStream());
+
+					verify(fileSender).withMetaData(uploadBinaryFileRequest);
+				}
+			}
+
+			@Test
+			void shouldCallSend() {
+				try (var uploadUtils = Mockito.mockStatic(GrpcFileUploadUtils.class)) {
+					uploadUtils.when(() -> GrpcFileUploadUtils.createSender(any(), any(), any())).thenReturn(fileSender);
+					when(fileSender.withMetaData(any())).thenReturn(fileSender);
+
+					service.uploadFile(OzgCloudUploadFileTestFactory.create(), InputStream.nullInputStream());
+
+					verify(fileSender).send();
+				}
+			}
+
+			@Test
+			void shouldCallWaitUntilFutureToComplete() {
+				try (var uploadUtils = Mockito.mockStatic(GrpcFileUploadUtils.class)) {
+					uploadUtils.when(() -> GrpcFileUploadUtils.createSender(any(), any(), any())).thenReturn(fileSender);
+					when(fileSender.withMetaData(any())).thenReturn(fileSender);
+					when(fileSender.send()).thenReturn(fileSender);
+					var dataStream = InputStream.nullInputStream();
+
+					service.uploadFile(OzgCloudUploadFileTestFactory.create(), dataStream);
+
+					verify(service).waitUntilFutureToComplete(fileSender, dataStream);
+				}
+			}
+
+			@Test
+			void shouldReturnResult() {
+				when(asyncServiceStub.withInterceptors(any())).thenReturn(asyncServiceStub);
+
+				var result = service.uploadFile(OzgCloudUploadFileTestFactory.create(), InputStream.nullInputStream());
+
+				assertThat(result).isEqualTo(OzgCloudFileTestFactory.ID);
+			}
+
+			private GrpcUploadBinaryFileRequest createRequest() {
+				return GrpcUploadBinaryFileRequest.newBuilder()
+					.setMetadata(GrpcUploadBinaryFileMetaDataTestFactory.create())
+					.build();
+			}
+		}
+
+		@Nested
+		class TestBuildChunkResponse {
+
+			private static byte[] FILE_CONTENT = "file content".getBytes();
+
+			@Test
+			void shouldSetFileContent() {
+				var grpcUploadBinaryFileRequest = service.buildChunkRequest(FILE_CONTENT, FILE_CONTENT.length);
+
+				assertThat(grpcUploadBinaryFileRequest.getFileContent().toByteArray()).isEqualTo(FILE_CONTENT);
+			}
+		}
+
+		@Nested
+		class TestBuildCallStreamObserver {
+
+			@Mock
+			private StreamObserver<GrpcUploadBinaryFileResponse> responseObserver;
+			@Mock
+			private CallStreamObserver<GrpcUploadBinaryFileRequest> requestObserver;
+
+			@BeforeEach
+			void init() {
+				doReturn(asyncServiceStub).when(service).getAsyncServiceStub();
+			}
+
+			@Test
+			void shouldCallGetAsyncServiceStub() {
+				service.buildCallStreamObserver(responseObserver);
+
+				verify(service).getAsyncServiceStub();
+			}
+
+			@Test
+			void shouldCallUploadBinaryFileAsStream() {
+				 service.buildCallStreamObserver(responseObserver);
+
+				verify(asyncServiceStub).uploadBinaryFileAsStream(responseObserver);
+			}
+
+			@Test
+			void shouldReturnRequestObserver() {
+				when(asyncServiceStub.uploadBinaryFileAsStream(any())).thenReturn(requestObserver);
+
+				var result = service.buildCallStreamObserver(responseObserver);
+
+				assertThat(result).isEqualTo(requestObserver);
+			}
+		}
+
+		@Nested
+		class TestBuildMetadataRequest {
+
+			@Test
+			void shouldSetMetadata() {
+				var result = buildMetadataRequest();
+
+				assertThat(result.getMetadata()).isNotEqualTo(GrpcUploadBinaryFileMetaData.getDefaultInstance());
+			}
+
+			@Test
+			void shouldSetFileName() {
+				var uploadFile = OzgCloudUploadFileTestFactory.create();
+
+				var result = service.buildMetaDataRequest(uploadFile).getMetadata();
+
+				assertThat(result.getFileName()).isEqualTo(uploadFile.getFileName());
+			}
+
+			@Test
+			void shouldSetContentType() {
+				var uploadFile = OzgCloudUploadFileTestFactory.create();
+
+				var result = service.buildMetaDataRequest(uploadFile).getMetadata();
+
+				assertThat(result.getContentType()).isEqualTo(uploadFile.getContentType());
+			}
+
+			@Test
+			void shouldSetVorgangId() {
+				var uploadFile = OzgCloudUploadFileTestFactory.create();
+
+				var result = service.buildMetaDataRequest(uploadFile).getMetadata();
+
+				assertThat(result.getVorgangId()).isEqualTo(uploadFile.getVorgangId().toString());
+			}
+
+			@Test
+			void shouldSetField() {
+				var uploadFile = OzgCloudUploadFileTestFactory.create();
+
+				var result = service.buildMetaDataRequest(uploadFile).getMetadata();
+
+				assertThat(result.getField()).isEqualTo(uploadFile.getFieldName());
+			}
+
+			private GrpcUploadBinaryFileRequest buildMetadataRequest() {
+				return service.buildMetaDataRequest(OzgCloudUploadFileTestFactory.create());
+			}
+		}
+
+		@Nested
+		class TestWaitUntilFutureToComplete {
+
+			private static final InputStream DATA_STREAM = InputStream.nullInputStream();
+
+			@Mock
+			private FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> fileSender;
+
+			@Mock
+			private CompletableFuture<GrpcUploadBinaryFileResponse> future;
+
+			@Test
+			void shouldWaitUntilFutureToComplete() {
+				when(fileSender.getResultFuture()).thenReturn(future);
+
+				waitUntilFutureToComplete();
+
+				verify(fileSender).getResultFuture();
+			}
+
+			@SneakyThrows
+			@Test
+			void shouldWaitWithTimeout() {
+				when(fileSender.getResultFuture()).thenReturn(future);
+
+				waitUntilFutureToComplete();
+
+				verify(future).get(10, TimeUnit.MINUTES);
+			}
+
+			@Test
+			void shouldCloseDatastream() {
+				try(var ioUtils = Mockito.mockStatic(IOUtils.class)) {
+					when(fileSender.getResultFuture()).thenReturn(future);
+
+					waitUntilFutureToComplete();
+
+					ioUtils.verify(() -> IOUtils.closeQuietly(DATA_STREAM));
+				}
+			}
+
+			@Nested
+			class TestThrowException {
+
+				@BeforeEach
+				void init() {
+					when(fileSender.getResultFuture()).thenReturn(future);
+				}
+
+				@SneakyThrows
+				@DisplayName("should throw TechnicalException")
+				@ParameterizedTest(name = "when {0} is thrown")
+				@ValueSource(classes = { InterruptedException.class, ExecutionException.class, TimeoutException.class })
+				void shouldHandleInterruptedException(Class<? extends Exception> exceptionClass) {
+					when(future.get(anyLong(), any())).thenThrow(exceptionClass);
+
+					assertThrows(TechnicalException.class, TestWaitUntilFutureToComplete.this::waitUntilFutureToComplete);
+				}
+
+			}
+
+			void waitUntilFutureToComplete() {
+				service.waitUntilFutureToComplete(fileSender, DATA_STREAM);
+			}
+		}
+	}
 }
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcUploadBinaryFileMetaDataTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcUploadBinaryFileMetaDataTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..67292cb0f72f19769c6bb1793439aa7de57ccb23
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcUploadBinaryFileMetaDataTestFactory.java
@@ -0,0 +1,20 @@
+package de.ozgcloud.apilib.file.grpc;
+
+import de.ozgcloud.apilib.file.OzgCloudUploadFileTestFactory;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData;
+
+public class GrpcUploadBinaryFileMetaDataTestFactory {
+
+	public static GrpcUploadBinaryFileMetaData create() {
+		return createBuilder().build();
+	}
+
+	private static GrpcUploadBinaryFileMetaData.Builder createBuilder() {
+		return GrpcUploadBinaryFileMetaData.newBuilder()
+			.setFileName(OzgCloudUploadFileTestFactory.FILE_NAME)
+			.setContentType(OzgCloudUploadFileTestFactory.CONTENT_TYPE)
+			.setVorgangId(OzgCloudVorgangTestFactory.ID.toString())
+			.setField(OzgCloudUploadFileTestFactory.FIELD_NAME);
+	}
+}
diff --git a/pom.xml b/pom.xml
index e3e2aa5b453ef01b1609fcc01d04d6070bbbb238..006302f14bc3c58686e0a705153c9e05779f369c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,8 +27,8 @@
 		<source-plugin.version>3.3.0</source-plugin.version>
 		<failsafe-plugin.version>3.2.2</failsafe-plugin.version>
 		<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
-		
-		<vorgang-manager.version>2.0.0</vorgang-manager.version>
+
+		<vorgang-manager.version>2.5.0-SNAPSHOT</vorgang-manager.version>
 		<user-manager.version>2.1.0</user-manager.version>
 	</properties>
 
@@ -47,7 +47,7 @@
 					</execution>
 				</executions>
 			</plugin>
-			
+
 		</plugins>
 	</build>