diff --git a/pom.xml b/pom.xml
index ccb8de3bfd4dcbb34e522ade41b81e7bbe5125cd..915ccea3e9f6dfbca7d73078bb0a325dc625d97e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,10 +89,6 @@
 			<artifactId>spring-boot-configuration-processor</artifactId>
 			<optional>true</optional>
 		</dependency>
-		<dependency>
-			<groupId>net.devh</groupId>
-			<artifactId>grpc-client-spring-boot-starter</artifactId>
-		</dependency>
 
 		<!-- ShedLock -->
 		<dependency>
diff --git a/src/main/java/de/ozgcloud/admin/keycloak/Group.java b/src/main/java/de/ozgcloud/admin/keycloak/Group.java
index 0bf5a9e19b39f24637d9cdd8ef037f6110247609..005a7ce23d0709ade874e9fad35e7be17906ceee 100644
--- a/src/main/java/de/ozgcloud/admin/keycloak/Group.java
+++ b/src/main/java/de/ozgcloud/admin/keycloak/Group.java
@@ -7,7 +7,7 @@ import lombok.Getter;
 import lombok.Singular;
 
 @Getter
-@Builder
+@Builder(toBuilder = true)
 public class Group {
 
 	private String id;
diff --git a/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java b/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java
index 80f607a3b81ae1f6aaa283536cebd6f81cee8a6a..2b3949a5436739f9fe8633a0373a803d060eb06d 100644
--- a/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java
+++ b/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java
@@ -24,14 +24,14 @@ class SyncService {
 	private final OrganisationsEinheitMapper organisationsEinheitMapper;
 
 	public void syncOrganisationsEinheitenFromKeycloak(long syncTimestamp) {
-		keycloakRemoteService.getGroupsWithOrganisationsEinheitId().forEach(group -> syncGroups(group, null, syncTimestamp));
+		keycloakRemoteService.getGroupsWithOrganisationsEinheitId().forEach(group -> syncGroupsWithSubGroups(group, null, syncTimestamp));
 		repository.setUnsyncedAsDeleted(syncTimestamp);
 	}
 
-	void syncGroups(Group group, OrganisationsEinheit parent, long syncTimestamp) {
+	void syncGroupsWithSubGroups(Group group, OrganisationsEinheit parent, long syncTimestamp) {
 		var synced = syncGroup(group, parent, syncTimestamp);
 		var saved = saveSyncedOrganisationsEinheit(synced);
-		group.getSubGroups().forEach(subGroup -> syncGroups(subGroup, saved, syncTimestamp));
+		group.getSubGroups().forEach(subGroup -> syncGroupsWithSubGroups(subGroup, saved, syncTimestamp));
 	}
 
 	OrganisationsEinheit syncGroup(Group group, OrganisationsEinheit parent, long syncTimestamp) {
@@ -90,7 +90,8 @@ class SyncService {
 	}
 
 	public void syncAddedOrganisationsEinheiten(long syncTimestamp) {
-		sortInAdditionOrder(repository.findAllWithoutSyncResult()).forEach(organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
+		sortInAdditionOrder(repository.findAllWithoutSyncResult()).forEach(
+				organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
 	}
 
 	Stream<OrganisationsEinheit> sortInAdditionOrder(Stream<OrganisationsEinheit> organisationsEinheiten) {
@@ -115,23 +116,30 @@ class SyncService {
 	}
 
 	void syncAddedOrganisationsEinheit(long syncTimestamp, OrganisationsEinheit organisationsEinheit) {
-		var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit, findParentKeycloakId(organisationsEinheit));
-		var keycloakId = addGroupInKeycloak(addGroupData);
-		if (keycloakId.isPresent()) {
-			var updatedOrganisationsEinheit = organisationsEinheit.toBuilder()
-					.keycloakId(keycloakId.get())
-					.syncResult(SyncResult.OK)
-					.lastSyncTimestamp(syncTimestamp)
-					.build();
-			repository.save(updatedOrganisationsEinheit);
+		var parent = findParent(organisationsEinheit);
+		if (parent.isEmpty() || parent.get().getKeycloakId() != null) {
+			var parentKeycloakId = parent.map(OrganisationsEinheit::getKeycloakId).orElse(null);
+			addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId).ifPresent(
+					addedGroupId -> updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId));
 		}
 	}
 
-	String findParentKeycloakId(OrganisationsEinheit organisationsEinheit) {
-		if (organisationsEinheit.getParentId() == null) {
-			return null;
-		}
-		return repository.findById(organisationsEinheit.getParentId()).map(OrganisationsEinheit::getKeycloakId).orElse(null);
+	Optional<OrganisationsEinheit> findParent(OrganisationsEinheit organisationsEinheit) {
+		return Optional.ofNullable(organisationsEinheit.getParentId()).flatMap(repository::findById);
+	}
+
+	Optional<String> addAsGroupInKeycloak(OrganisationsEinheit organisationsEinheit, String parentKeycloakId) {
+		var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId);
+		return addGroupInKeycloak(addGroupData);
+	}
+
+	void updateAfterSuccessfulGroupCreation(OrganisationsEinheit organisationsEinheit, long syncTimestamp, String keycloakId) {
+		var updatedOrganisationsEinheit = organisationsEinheit.toBuilder()
+				.keycloakId(keycloakId)
+				.syncResult(SyncResult.OK)
+				.lastSyncTimestamp(syncTimestamp)
+				.build();
+		repository.save(updatedOrganisationsEinheit);
 	}
 
 	Optional<String> addGroupInKeycloak(AddGroupData addGroupData) {
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitControllerTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitControllerTest.java
index 06f4ce43a415aaa113d9505bcf686942a9a8be30..fbf00adebbb5aeb5e7b8c5edd6f2a6ce4d76f09f 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitControllerTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitControllerTest.java
@@ -96,10 +96,12 @@ class OrganisationsEinheitControllerTest {
 	class TestGetById {
 
 		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
+		private final EntityModel<OrganisationsEinheit> entityModel = EntityModel.of(organisationsEinheit);
 
 		@BeforeEach
 		void setUp() {
 			when(organisationsEinheitService.getOrganisationsEinheitById(OrganisationsEinheitTestFactory.ID)).thenReturn(organisationsEinheit);
+			when(assembler.toModel(organisationsEinheit)).thenReturn(entityModel);
 		}
 
 		@Test
@@ -122,6 +124,13 @@ class OrganisationsEinheitControllerTest {
 			doRequest().andExpect(status().isOk());
 		}
 
+		@Test
+		void shouldReturnEntityModel() {
+			var response = controller.getById(OrganisationsEinheitTestFactory.ID);
+
+			assertThat(response).isEqualTo(entityModel);
+		}
+
 		@SneakyThrows
 		private ResultActions doRequest() {
 			return mockMvc.perform(get(OrganisationsEinheitController.PATH + "/" + OrganisationsEinheitTestFactory.ID));
@@ -131,11 +140,15 @@ class OrganisationsEinheitControllerTest {
 	@Nested
 	class TestGetChildren {
 
-		private final List<OrganisationsEinheit> children = List.of(OrganisationsEinheitTestFactory.create());
+		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
+		private final List<OrganisationsEinheit> children = List.of(organisationsEinheit);
+		private final CollectionModel<EntityModel<OrganisationsEinheit>> collectionModel = CollectionModel.of(
+				List.of(EntityModel.of(organisationsEinheit)));
 
 		@BeforeEach
 		void setUp() {
 			when(organisationsEinheitService.getChildren(OrganisationsEinheitTestFactory.ID)).thenReturn(children);
+			when(assembler.toChildrenCollectionModel(OrganisationsEinheitTestFactory.ID, children)).thenReturn(collectionModel);
 		}
 
 		@Test
@@ -158,6 +171,13 @@ class OrganisationsEinheitControllerTest {
 			verify(assembler).toChildrenCollectionModel(OrganisationsEinheitTestFactory.ID, children);
 		}
 
+		@Test
+		void shouldReturnCollectionModel() {
+			var response = controller.getChildren(OrganisationsEinheitTestFactory.ID);
+
+			assertThat(response).isEqualTo(collectionModel);
+		}
+
 		@SneakyThrows
 		private ResultActions doRequest() {
 			return mockMvc.perform(get(OrganisationsEinheitController.PATH + "/" + OrganisationsEinheitTestFactory.ID + "/children"));
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapperTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapperTest.java
index 3298e01121a50ad9858bec40e0828472e894e4a2..9192df6b2e1ac6545099bec61c84006758dadde3 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapperTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapperTest.java
@@ -3,6 +3,7 @@ package de.ozgcloud.admin.organisationseinheit;
 import static org.assertj.core.api.Assertions.*;
 
 import java.util.Collections;
+import java.util.Objects;
 import java.util.UUID;
 
 import org.junit.jupiter.api.Nested;
@@ -22,23 +23,23 @@ class OrganisationsEinheitMapperTest {
 		void shouldMap() {
 			var mapped = mapper.fromGrpc(GrpcOrganisationsEinheitTestFactory.create());
 
-			assertThat(mapped).extracting(
-					OrganisationsEinheit::getName,
-					OrganisationsEinheit::getOrganisationsEinheitId,
-					OrganisationsEinheit::getZufiId,
-					OrganisationsEinheit::getParentId,
-					OrganisationsEinheit::getSyncResult,
-					OrganisationsEinheit::getSettings,
-					OrganisationsEinheit::getChildren
-			).containsExactly(
-					OrganisationsEinheitTestFactory.NAME,
-					OrganisationsEinheitTestFactory.ORGANISATIONS_EINHEIT_ID,
-					OrganisationsEinheitTestFactory.ZUFI_ID,
-					null,
-					null,
-					null,
-					Collections.emptyList()
-			);
+			assertThat(mapped)
+					.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+					.extracting(
+							OrganisationsEinheit::getName,
+							OrganisationsEinheit::getOrganisationsEinheitId,
+							OrganisationsEinheit::getZufiId,
+							OrganisationsEinheit::getParentId,
+							OrganisationsEinheit::getSyncResult,
+							OrganisationsEinheit::getChildren
+					).containsExactly(
+							OrganisationsEinheitTestFactory.NAME,
+							OrganisationsEinheitTestFactory.ORGANISATIONS_EINHEIT_ID,
+							OrganisationsEinheitTestFactory.ZUFI_ID,
+							null,
+							null,
+							Collections.emptyList()
+					);
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitModelAssemblerTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitModelAssemblerTest.java
index d22dfcc1cec283ada2166c4402f1fd20fa711b0f..51c34967555f7f69218f28da26d4e48fd1a8701e 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitModelAssemblerTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitModelAssemblerTest.java
@@ -11,6 +11,8 @@ import java.util.UUID;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.InjectMocks;
 import org.mockito.Spy;
 import org.springframework.hateoas.CollectionModel;
@@ -82,6 +84,10 @@ class OrganisationsEinheitModelAssemblerTest {
 		private CollectionModel<EntityModel<OrganisationsEinheit>> childrenCollectionModel;
 		@Spy
 		private final HalModelBuilder halModelBuilder = HalModelBuilder.emptyHalModel();
+		@Captor
+		private ArgumentCaptor<LinkRelation> linkRelationArgumentCaptor;
+		@Captor
+		private ArgumentCaptor<Collection<EntityModel<OrganisationsEinheit>>> collectionModelContentArgumentCaptor;
 
 		@BeforeEach
 		void setUp() {
@@ -89,8 +95,7 @@ class OrganisationsEinheitModelAssemblerTest {
 			childOrganisationsEinheit = OrganisationsEinheitTestFactory.createBuilder().id(UUID.randomUUID().toString())
 					.parentId(parentOrganisationsEinheit.getId()).build();
 			parentOrganisationsEinheit = parentOrganisationsEinheit.toBuilder().child(childOrganisationsEinheit).build();
-			childrenCollectionModel = CollectionModel.of(
-					List.of(EntityModel.of(childOrganisationsEinheit)));
+			childrenCollectionModel = CollectionModel.of(List.of(EntityModel.of(childOrganisationsEinheit)));
 			doReturn(childrenCollectionModel).when(assembler)
 					.toChildrenCollectionModel(parentOrganisationsEinheit.getId(), parentOrganisationsEinheit.getChildren());
 		}
@@ -106,7 +111,9 @@ class OrganisationsEinheitModelAssemblerTest {
 		void shouldEmbedChildrenModels() {
 			assembler.embedChildOrganisationsEinheiten(parentOrganisationsEinheit, halModelBuilder);
 
-			verify(halModelBuilder).embed(any(Collection.class), any(LinkRelation.class));
+			verify(halModelBuilder).embed(collectionModelContentArgumentCaptor.capture(), linkRelationArgumentCaptor.capture());
+			assertThat(collectionModelContentArgumentCaptor.getValue()).usingRecursiveComparison().isEqualTo(childrenCollectionModel.getContent());
+			assertThat(linkRelationArgumentCaptor.getValue().toString()).isEqualTo(REL_CHILD_ORGANISATIONS_EINHEITEN);
 		}
 
 		@Test
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRepositoryITCase.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRepositoryITCase.java
index ced0b42ccd586c5b3588ed5cb4927f805c243a25..dcfeebde1d6aa5bfb83944ec11c110f72dd833a8 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRepositoryITCase.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRepositoryITCase.java
@@ -111,7 +111,7 @@ class OrganisationsEinheitRepositoryITCase {
 		}
 
 		@Test
-		void shouldReturnEmptyOnNotFoundSyncResultNull() {
+		void shouldReturnEmptyOnSyncResultNull() {
 			operations.save(OrganisationsEinheitTestFactory.createBuilder().id(null).syncResult(null).build());
 
 			var organisationsEinheit = repository.findSyncedByKeycloakId(OrganisationsEinheitTestFactory.KEYCLOAK_ID);
@@ -145,12 +145,12 @@ class OrganisationsEinheitRepositoryITCase {
 		private final OrganisationsEinheit deleted1 = OrganisationsEinheitTestFactory.createBuilder()
 				.id(null)
 				.organisationsEinheitId(DELETED_ORGANISATIONS_EINHEIT_ID_1)
-				.lastSyncTimestamp(Instant.now().minusSeconds(300).toEpochMilli())
+				.lastSyncTimestamp(OrganisationsEinheitTestFactory.LAST_SYNC_UPDATE - 1)
 				.build();
 		private final OrganisationsEinheit deleted2 = OrganisationsEinheitTestFactory.createBuilder()
 				.id(null)
 				.organisationsEinheitId(DELETED_ORGANISATIONS_EINHEIT_ID_2)
-				.lastSyncTimestamp(Instant.now().minusSeconds(30000).toEpochMilli())
+				.lastSyncTimestamp(OrganisationsEinheitTestFactory.LAST_SYNC_UPDATE - 2)
 				.build();
 		private final OrganisationsEinheit synced1 = OrganisationsEinheitTestFactory.createBuilder()
 				.id(null)
@@ -235,7 +235,8 @@ class OrganisationsEinheitRepositoryITCase {
 		void shouldFindAllWithoutSyncResult() {
 			var allWithoutSyncResult = repository.findAllWithoutSyncResult();
 
-			assertThat(allWithoutSyncResult).extracting(OrganisationsEinheit::getId).containsExactlyInAnyOrder(WITHOUT_SYNC_RESULT_ID_1, WITHOUT_SYNC_RESULT_ID_2);
+			assertThat(allWithoutSyncResult).extracting(OrganisationsEinheit::getId)
+					.containsExactlyInAnyOrder(WITHOUT_SYNC_RESULT_ID_1, WITHOUT_SYNC_RESULT_ID_2);
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitServiceTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitServiceTest.java
index 822efd5c057a8b196deac785e1563848070d67c8..aaf92457a1ca0d94efb929733852e1dbf022b03b 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitServiceTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitServiceTest.java
@@ -139,12 +139,26 @@ class OrganisationsEinheitServiceTest {
 	@Nested
 	class TestGetChildren {
 
+		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
+
+		@BeforeEach
+		void setUp() {
+			when(repository.findChildren(OrganisationsEinheitTestFactory.ID)).thenReturn(List.of(organisationsEinheit));
+		}
+
 		@Test
 		void shouldCallRepository() {
 			service.getChildren(OrganisationsEinheitTestFactory.ID);
 
 			verify(repository).findChildren(OrganisationsEinheitTestFactory.ID);
 		}
+
+		@Test
+		void shouldReturnChildren() {
+			var children = service.getChildren(OrganisationsEinheitTestFactory.ID);
+
+			assertThat(children).containsExactly(organisationsEinheit);
+		}
 	}
 
 	@Nested
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitSettingsTestFactory.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitSettingsTestFactory.java
index ababf88ba11eb1378cc4416c357098c48abd8bc7..c5028fb0e25bb8b6127e623a4e09b75794545d61 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitSettingsTestFactory.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitSettingsTestFactory.java
@@ -15,4 +15,9 @@ public class OrganisationsEinheitSettingsTestFactory {
 				.signatur(SIGNATUR);
 	}
 
+	public static OrganisationsEinheitSettings.OrganisationsEinheitSettingsBuilder createNewBuilder() {
+		return OrganisationsEinheitSettings.builder()
+				.signatur(LoremIpsum.getInstance().getWords(3));
+	}
+
 }
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitTestFactory.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitTestFactory.java
index 2feb3311fb010748e58beed1f48b9a132c24d015..756ec38fc6a01660b352924cebbd24176c4a9939 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitTestFactory.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitTestFactory.java
@@ -34,4 +34,16 @@ public class OrganisationsEinheitTestFactory {
 				.lastSyncTimestamp(LAST_SYNC_UPDATE);
 	}
 
+	public static OrganisationsEinheit.OrganisationsEinheitBuilder createNewBuilder() {
+		return OrganisationsEinheit.builder()
+				.id(UUID.randomUUID().toString())
+				.keycloakId(UUID.randomUUID().toString())
+				.name(LoremIpsum.getInstance().getName())
+				.organisationsEinheitId(UUID.randomUUID().toString())
+				.parentId(UUID.randomUUID().toString())
+				.zufiId(UUID.randomUUID().toString())
+				.syncResult(SyncResult.DELETED)
+				.settings(OrganisationsEinheitSettingsTestFactory.createNewBuilder().build())
+				.lastSyncTimestamp(LAST_SYNC_UPDATE - 10000);
+	}
 }
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncAddedOrganisationsEinheitenITCase.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncAddedOrganisationsEinheitenITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca1b0366500f5ea25e29cef7ebdaee5deff22484
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncAddedOrganisationsEinheitenITCase.java
@@ -0,0 +1,128 @@
+package de.ozgcloud.admin.organisationseinheit;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.groups.Tuple.tuple;
+import static org.mockito.Mockito.*;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.test.context.ContextConfiguration;
+
+import de.ozgcloud.admin.common.KeycloakInitializer;
+import de.ozgcloud.admin.keycloak.Group;
+import de.ozgcloud.admin.keycloak.KeycloakRemoteService;
+import de.ozgcloud.admin.keycloak.ResourceCreationException;
+import de.ozgcloud.common.test.DbInitializer;
+import de.ozgcloud.common.test.ITCase;
+
+@ITCase
+@ContextConfiguration(initializers = { DbInitializer.class, KeycloakInitializer.class })
+class SyncAddedOrganisationsEinheitenITCase {
+
+	@Autowired
+	private SyncService service;
+	@SpyBean
+	private KeycloakRemoteService keycloakRemoteService;
+	@Autowired
+	private MongoOperations operations;
+
+	private final long syncTimestamp = Instant.now().toEpochMilli();
+
+	@BeforeEach
+	void clearDatabase() {
+		operations.dropCollection(OrganisationsEinheit.class);
+	}
+
+	@Test
+	void shouldSynchronizeAddedTopLevelGroup() {
+		var topLevel = topLevel("shouldSynchronizeAddedTopLevelGroup");
+		operations.save(topLevel);
+
+		service.syncAddedOrganisationsEinheiten(syncTimestamp);
+
+		assertThat(keycloakRemoteService.getGroupsWithOrganisationsEinheitId())
+				.extracting(Group::getName, Group::getOrganisationsEinheitId, Group::getSubGroups)
+				.contains(tuple(topLevel.getName(), topLevel.getOrganisationsEinheitId(), List.of()));
+	}
+
+	@Test
+	void shouldSynchronizeAddedTopLevelGroupWithChild() {
+		var topLevel = topLevel("shouldSynchronizeAddedTopLevelGroupWithChild");
+		var childLevel1 = childLevel("shouldSynchronizeAddedTopLevelGroupWithChild", topLevel);
+		operations.save(topLevel);
+		operations.save(childLevel1);
+
+		service.syncAddedOrganisationsEinheiten(syncTimestamp);
+
+		assertThat(findGroupInKeycloak(topLevel.getName())).isPresent().get()
+				.extracting(Group::getSubGroups).asList().extracting("name")
+				.containsExactly(childLevel1.getName());
+	}
+
+	@Test
+	void shouldSynchronizeChildAddedToAlreadySynchronizedParent() {
+		var parent = topLevel("shouldSynchronizeChildAddedToAlreadySynchronizedParent");
+		syncOrganisationsEinheitToKeycloak(parent);
+		var childLevel1 = childLevel("shouldSynchronizeChildAddedToAlreadySynchronizedParent", parent);
+		operations.save(childLevel1);
+
+		service.syncAddedOrganisationsEinheiten(syncTimestamp);
+
+		assertThat(findGroupInKeycloak(parent.getName())).isPresent().get()
+				.extracting(Group::getSubGroups).asList().extracting("name")
+				.containsExactly(childLevel1.getName());
+	}
+
+	@Test
+	void shouldNotAddChildIfParentWasNotSynchronized() {
+		var topLevel = topLevel("shouldNotAddChildIfParentWasNotSynchronized");
+		var childLevel1 = childLevel("shouldNotAddChildIfParentWasNotSynchronized", topLevel);
+		operations.save(topLevel);
+		operations.save(childLevel1);
+		doThrow(new ResourceCreationException("OMG!")).when(keycloakRemoteService)
+				.addGroup(argThat(addGroupData -> addGroupData.getName().equals(topLevel.getName())));
+
+		service.syncAddedOrganisationsEinheiten(syncTimestamp);
+
+		assertThat(findGroupInKeycloak(childLevel1.getName())).isEmpty();
+	}
+
+	private static OrganisationsEinheit topLevel(String nameSuffix) {
+		return OrganisationsEinheitTestFactory.createBuilder()
+				.id(UUID.randomUUID().toString())
+				.parentId(null)
+				.keycloakId(null)
+				.syncResult(null)
+				.name("topLevel (%s)".formatted(nameSuffix))
+				.build();
+	}
+
+	private static OrganisationsEinheit childLevel(String nameSuffix, OrganisationsEinheit parent) {
+		return OrganisationsEinheitTestFactory.createBuilder()
+				.id(UUID.randomUUID().toString())
+				.parentId(parent.getId())
+				.keycloakId(null)
+				.syncResult(null)
+				.name("childLevel1 (%s)".formatted(nameSuffix))
+				.build();
+	}
+
+	private Optional<Group> findGroupInKeycloak(String groupName) {
+		return keycloakRemoteService.getGroupsWithOrganisationsEinheitId()
+				.filter(group -> groupName.equals(group.getName()))
+				.findFirst();
+	}
+
+	private void syncOrganisationsEinheitToKeycloak(OrganisationsEinheit organisationsEinheit) {
+		operations.save(organisationsEinheit);
+		service.syncAddedOrganisationsEinheiten(syncTimestamp);
+	}
+}
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceITCase.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..c681785b71ea74380ac446ca736527d131579284
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceITCase.java
@@ -0,0 +1,630 @@
+package de.ozgcloud.admin.organisationseinheit;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.time.Instant;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.data.mongodb.core.MongoOperations;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.admin.keycloak.GroupTestFactory;
+import de.ozgcloud.admin.keycloak.KeycloakRemoteService;
+import de.ozgcloud.common.test.DataITCase;
+
+@DataITCase
+@EnableAutoConfiguration
+class SyncServiceITCase {
+
+	@Autowired
+	private MongoOperations operations;
+
+	@Autowired
+	private SyncService service;
+
+	@Autowired
+	private OrganisationsEinheitRepository repository;
+
+	@MockBean
+	private KeycloakRemoteService keycloakRemoteService;
+
+	@MockBean
+	private OrganisationsEinheitRemoteService organisationsEinheitRemoteService;
+
+	@BeforeEach
+	void clearDatabase() {
+		operations.dropCollection(OrganisationsEinheit.class);
+	}
+
+	@DisplayName("Organisationseinheit not found in PVOG")
+	@Test
+	void shouldSyncNotFoundInPvog() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().clearSubGroups().build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(List.of());
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var synced = repository.findAll();
+
+		assertThat(synced).
+				hasSize(1)
+				.first()
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.NOT_FOUND_IN_PVOG,
+						null,
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Organisationseinheit found in PVOG but group name is different")
+	@Test
+	void shouldSyncNameMismatch() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().clearSubGroups().build();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var synced = repository.findAll();
+
+		assertThat(synced).
+				hasSize(1)
+				.first()
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						pvogOranigastionsEinheit.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.NAME_MISMATCH,
+						pvogOranigastionsEinheit.getId(),
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Multiple Organisationseinheiten for same group found in PVOG")
+	@Test
+	void shouldSyncOrganisationsEinheitNotUnique() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().clearSubGroups().build();
+		var pvogOranigastionsEinheit1 = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.build();
+		var pvogOranigastionsEinheit2 = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit1, pvogOranigastionsEinheit2));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var synced = repository.findAll();
+
+		assertThat(synced).
+				hasSize(1)
+				.first()
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.ORGANISATIONSEINHEIT_ID_NOT_UNIQUE,
+						null,
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Organisationseinheit found in PVOG and have same data")
+	@Test
+	void shouldSyncOk() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().clearSubGroups().build();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.name(group.getName()).build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var synced = repository.findAll();
+
+		assertThat(synced).
+				hasSize(1)
+				.first()
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.OK,
+						pvogOranigastionsEinheit.getId(),
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("OrganisationseinheitId attribute of group changed")
+	@Test
+	void shouldSyncUpdateAttribute() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().clearSubGroups().build();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.name(group.getName()).build();
+		var newOrganisationsEinheitId = UUID.randomUUID().toString();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(
+				Stream.of(group.toBuilder().organisationsEinheitId(newOrganisationsEinheitId).build()));
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp + 1000);
+
+		var synced = repository.findAll();
+
+		assertThat(synced).
+				hasSize(1)
+				.first()
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						newOrganisationsEinheitId,
+						SyncResult.NOT_FOUND_IN_PVOG,
+						null,
+						null,
+						Collections.emptyList(),
+						syncTimestamp + 1000);
+	}
+
+	@DisplayName("Group deleted in Keycloak")
+	@Test
+	void shouldSyncDeleted() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().clearSubGroups().build();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.name(group.getName()).build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of());
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp + 1000);
+
+		var synced = repository.findAll();
+
+		assertThat(synced).
+				hasSize(1)
+				.first()
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.DELETED,
+						pvogOranigastionsEinheit.getId(),
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Organisationseinheit for parent group and sub group not found in PVOG")
+	@Test
+	void shouldSyncParentNotFoundInPvogSubGroupNotFoundInPvog() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().build();
+		var subGroup = group.getSubGroups().getFirst();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(List.of());
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var parentSynced = repository.findSyncedByKeycloakId(group.getId()).get();
+		var childSynced = repository.findSyncedByKeycloakId(subGroup.getId()).get();
+
+		assertThat(parentSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.NOT_FOUND_IN_PVOG,
+						null,
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+		assertThat(childSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						subGroup.getId(),
+						subGroup.getName(),
+						subGroup.getOrganisationsEinheitId(),
+						SyncResult.NOT_FOUND_IN_PVOG,
+						null,
+						parentSynced.getId(),
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Organisationseinheit for parent group and sub group found in PVOG but have different names")
+	@Test
+	void shouldSyncParentNameMismatchSubGroupNameMismatch() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().build();
+		var subGroup = group.getSubGroups().getFirst();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.build();
+		var pvogChildOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder()
+				.organisationsEinheitId(subGroup.getOrganisationsEinheitId()).name(
+						LoremIpsum.getInstance().getWords(2))
+				.build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.SUB_GROUP_ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogChildOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var parentSynced = repository.findSyncedByKeycloakId(group.getId()).get();
+		var childSynced = repository.findSyncedByKeycloakId(subGroup.getId()).get();
+
+		assertThat(parentSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						pvogOranigastionsEinheit.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.NAME_MISMATCH,
+						pvogOranigastionsEinheit.getId(),
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+		assertThat(childSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						subGroup.getId(),
+						pvogChildOranigastionsEinheit.getName(),
+						subGroup.getOrganisationsEinheitId(),
+						SyncResult.NAME_MISMATCH,
+						pvogChildOranigastionsEinheit.getId(),
+						parentSynced.getId(),
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Multiple Organisationseinheiten for parent group and sub group found in PVOG")
+	@Test
+	void shouldSyncParentAndChildOrganisationsEinheitNotUnique() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().build();
+		var subGroup = group.getSubGroups().getFirst();
+		var pvogOranigastionsEinheit1 = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.build();
+		var pvogOranigastionsEinheit2 = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.build();
+		var pvogChildOranigastionsEinheit1 = OrganisationsEinheitTestFactory.createBuilder()
+				.organisationsEinheitId(subGroup.getOrganisationsEinheitId()).name(
+						LoremIpsum.getInstance().getWords(2))
+				.build();
+		var pvogChildOranigastionsEinheit2 = OrganisationsEinheitTestFactory.createBuilder()
+				.organisationsEinheitId(subGroup.getOrganisationsEinheitId()).name(
+						LoremIpsum.getInstance().getWords(2))
+				.build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit1, pvogOranigastionsEinheit2));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.SUB_GROUP_ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogChildOranigastionsEinheit1, pvogChildOranigastionsEinheit2));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var parentSynced = repository.findSyncedByKeycloakId(group.getId()).get();
+		var childSynced = repository.findSyncedByKeycloakId(subGroup.getId()).get();
+
+		assertThat(parentSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.ORGANISATIONSEINHEIT_ID_NOT_UNIQUE,
+						null,
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+		assertThat(childSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						subGroup.getId(),
+						subGroup.getName(),
+						subGroup.getOrganisationsEinheitId(),
+						SyncResult.ORGANISATIONSEINHEIT_ID_NOT_UNIQUE,
+						null,
+						parentSynced.getId(),
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Organisationseinheit and child Organisationseinheit found in PVOG and have same data")
+	@Test
+	void shouldSyncOkGroupWithSubGroup() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().build();
+		var subGroup = group.getSubGroups().getFirst();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.name(group.getName()).build();
+		var pvogChildOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder()
+				.organisationsEinheitId(subGroup.getOrganisationsEinheitId()).name(
+						subGroup.getName())
+				.build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.SUB_GROUP_ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogChildOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+
+		var parentSynced = repository.findSyncedByKeycloakId(group.getId()).get();
+		var childSynced = repository.findSyncedByKeycloakId(subGroup.getId()).get();
+
+		assertThat(parentSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.OK,
+						pvogOranigastionsEinheit.getId(),
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+		assertThat(childSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						subGroup.getId(),
+						subGroup.getName(),
+						subGroup.getOrganisationsEinheitId(),
+						SyncResult.OK,
+						pvogChildOranigastionsEinheit.getId(),
+						parentSynced.getId(),
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+	@DisplayName("Group with sub group deleted in Keycloak")
+	@Test
+	void shouldSyncGroupAndSubGroupDeleted() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		var group = GroupTestFactory.createBuilder().build();
+		var subGroup = group.getSubGroups().getFirst();
+		var pvogOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder().organisationsEinheitId(group.getOrganisationsEinheitId())
+				.name(group.getName()).build();
+		var pvogChildOranigastionsEinheit = OrganisationsEinheitTestFactory.createBuilder()
+				.organisationsEinheitId(subGroup.getOrganisationsEinheitId()).name(
+						subGroup.getName())
+				.build();
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogOranigastionsEinheit));
+		when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.SUB_GROUP_ORGANISATIONS_EINHEIT_ID)).thenReturn(
+				List.of(pvogChildOranigastionsEinheit));
+
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+		when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of());
+		service.syncOrganisationsEinheitenFromKeycloak(syncTimestamp + 1000);
+
+		var parentSynced = repository.findSyncedByKeycloakId(group.getId()).get();
+		var childSynced = repository.findSyncedByKeycloakId(subGroup.getId()).get();
+
+		assertThat(parentSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						group.getId(),
+						group.getName(),
+						group.getOrganisationsEinheitId(),
+						SyncResult.DELETED,
+						pvogOranigastionsEinheit.getId(),
+						null,
+						Collections.emptyList(),
+						syncTimestamp);
+		assertThat(childSynced)
+				.matches(organisationsEinheit -> Objects.nonNull(organisationsEinheit.getId()))
+				.matches(organisationsEinheit -> Objects.isNull(organisationsEinheit.getSettings().getSignatur()))
+				.extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getName,
+						OrganisationsEinheit::getOrganisationsEinheitId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getZufiId,
+						OrganisationsEinheit::getParentId,
+						OrganisationsEinheit::getChildren,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(
+						subGroup.getId(),
+						subGroup.getName(),
+						subGroup.getOrganisationsEinheitId(),
+						SyncResult.DELETED,
+						pvogChildOranigastionsEinheit.getId(),
+						parentSynced.getId(),
+						Collections.emptyList(),
+						syncTimestamp);
+	}
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceTest.java
index 875324ebf97e9efc9133b313ea8b41eda2a981fc..af78396ac96a80283352eb82a1aedd302b0f64ec 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceTest.java
@@ -21,6 +21,8 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 
+import com.thedeanda.lorem.LoremIpsum;
+
 import de.ozgcloud.admin.keycloak.AddGroupData;
 import de.ozgcloud.admin.keycloak.AddGroupDataTestFactory;
 import de.ozgcloud.admin.keycloak.Group;
@@ -55,7 +57,7 @@ class SyncServiceTest {
 		@BeforeEach
 		void setUp() {
 			when(keycloakRemoteService.getGroupsWithOrganisationsEinheitId()).thenReturn(Stream.of(group));
-			doNothing().when(service).syncGroups(any(), any(), anyLong());
+			doNothing().when(service).syncGroupsWithSubGroups(any(), any(), anyLong());
 		}
 
 		@Test
@@ -69,7 +71,7 @@ class SyncServiceTest {
 		void shouldSyncGroupsFromKeycloak() {
 			callService();
 
-			verify(service).syncGroups(group, null, syncTimestamp);
+			verify(service).syncGroupsWithSubGroups(group, null, syncTimestamp);
 		}
 
 		@Test
@@ -86,7 +88,7 @@ class SyncServiceTest {
 	}
 
 	@Nested
-	class TestSyncGroups {
+	class TestSyncGroupsWithSubGroups {
 
 		private final long syncTimestamp = Instant.now().toEpochMilli();
 		private final Group group = GroupTestFactory.create();
@@ -97,28 +99,28 @@ class SyncServiceTest {
 		@BeforeEach
 		void setUp() {
 			doReturn(syncedOrganisationsEinheitGroup).when(service).syncGroup(group, null, syncTimestamp);
-			doReturn(savedOrganisationsEinheitGroup).when(service).saveSyncedOrganisationsEinheit(any());
+			doReturn(savedOrganisationsEinheitGroup).when(service).saveSyncedOrganisationsEinheit(syncedOrganisationsEinheitGroup);
 		}
 
 		@Test
 		void shouldSyncGroup() {
-			service.syncGroups(group, null, syncTimestamp);
+			service.syncGroupsWithSubGroups(group, null, syncTimestamp);
 
 			verify(service).syncGroup(group, null, syncTimestamp);
 		}
 
 		@Test
-		void shouldSaveSyncedGroup() {
-			service.syncGroups(group, null, syncTimestamp);
+		void shouldSaveSyncedOrganisationsEinheit() {
+			service.syncGroupsWithSubGroups(group, null, syncTimestamp);
 
 			verify(service).saveSyncedOrganisationsEinheit(syncedOrganisationsEinheitGroup);
 		}
 
 		@Test
 		void shouldSyncSubGroupsWithSyncedOrganisationsEinheitAsParent() {
-			service.syncGroups(group, null, syncTimestamp);
+			service.syncGroupsWithSubGroups(group, null, syncTimestamp);
 
-			verify(service).syncGroups(group.getSubGroups().getFirst(), savedOrganisationsEinheitGroup, syncTimestamp);
+			verify(service).syncGroupsWithSubGroups(group.getSubGroups().getFirst(), savedOrganisationsEinheitGroup, syncTimestamp);
 		}
 	}
 
@@ -130,14 +132,18 @@ class SyncServiceTest {
 		private final OrganisationsEinheit parent = OrganisationsEinheitTestFactory.createBuilder().id(UUID.randomUUID().toString()).build();
 		private final OrganisationsEinheit pvogOrganisationsEinheit = OrganisationsEinheitTestFactory.createBuilder().zufiId(null).settings(null)
 				.parentId(null).syncResult(null).build();
+		private final String syncedName = LoremIpsum.getInstance().getWords(3);
+		private final SyncResult syncedSyncResult = SyncResult.OK;
+		private final String syncedZufiId = UUID.randomUUID().toString();
 
 		@Nested
 		class ParentGroup {
 
 			@BeforeEach
 			void setUp() {
-				doReturn(OrganisationsEinheitTestFactory.NAME).when(service).syncName(anyList(), any());
-				doReturn(SyncResult.OK).when(service).evaluateSyncResult(anyList(), any());
+				doReturn(syncedName).when(service).syncName(List.of(pvogOrganisationsEinheit), group);
+				doReturn(syncedSyncResult).when(service).evaluateSyncResult(List.of(pvogOrganisationsEinheit), group);
+				doReturn(syncedZufiId).when(service).syncZufiId(List.of(pvogOrganisationsEinheit));
 				when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID)).thenReturn(
 						List.of(pvogOrganisationsEinheit));
 			}
@@ -151,16 +157,18 @@ class SyncServiceTest {
 
 			@Test
 			void shouldSyncName() {
-				service.syncGroup(group, null, syncTimestamp);
+				var synced = service.syncGroup(group, null, syncTimestamp);
 
 				verify(service).syncName(List.of(pvogOrganisationsEinheit), group);
+				assertThat(synced.getName()).isEqualTo(syncedName);
 			}
 
 			@Test
 			void shouldEvaluateSyncResult() {
-				service.syncGroup(group, null, syncTimestamp);
+				var synced = service.syncGroup(group, null, syncTimestamp);
 
 				verify(service).evaluateSyncResult(List.of(pvogOrganisationsEinheit), group);
+				assertThat(synced.getSyncResult()).isEqualTo(syncedSyncResult);
 			}
 
 			@Test
@@ -170,11 +178,19 @@ class SyncServiceTest {
 				verify(organisationsEinheitRemoteService).getByOrganisationsEinheitId(GroupTestFactory.ORGANISATIONS_EINHEIT_ID);
 			}
 
+			@Test
+			void shouldSetOrganisationsEinheitId() {
+				var synced = service.syncGroup(group, null, syncTimestamp);
+
+				assertThat(synced.getOrganisationsEinheitId()).isEqualTo(group.getOrganisationsEinheitId());
+			}
+
 			@Test
 			void shouldSyncZufiId() {
-				service.syncGroup(group, null, syncTimestamp);
+				var synced = service.syncGroup(group, null, syncTimestamp);
 
 				verify(service).syncZufiId(List.of(pvogOrganisationsEinheit));
+				assertThat(synced.getZufiId()).isEqualTo(syncedZufiId);
 			}
 
 			@Test
@@ -190,8 +206,9 @@ class SyncServiceTest {
 
 			@BeforeEach
 			void setUp() {
-				doReturn(OrganisationsEinheitTestFactory.NAME).when(service).syncName(anyList(), any());
-				doReturn(SyncResult.OK).when(service).evaluateSyncResult(anyList(), any());
+				doReturn(syncedName).when(service).syncName(List.of(pvogOrganisationsEinheit), group.getSubGroups().getFirst());
+				doReturn(syncedSyncResult).when(service).evaluateSyncResult(List.of(pvogOrganisationsEinheit), group.getSubGroups().getFirst());
+				doReturn(syncedZufiId).when(service).syncZufiId(List.of(pvogOrganisationsEinheit));
 				when(organisationsEinheitRemoteService.getByOrganisationsEinheitId(GroupTestFactory.SUB_GROUP_ORGANISATIONS_EINHEIT_ID)).thenReturn(
 						List.of(pvogOrganisationsEinheit));
 			}
@@ -205,23 +222,26 @@ class SyncServiceTest {
 
 			@Test
 			void shouldSyncName() {
-				service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
+				var synced = service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
 
 				verify(service).syncName(List.of(pvogOrganisationsEinheit), group.getSubGroups().getFirst());
+				assertThat(synced.getName()).isEqualTo(syncedName);
 			}
 
 			@Test
 			void shouldEvaluateSyncResult() {
-				service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
+				var synced = service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
 
 				verify(service).evaluateSyncResult(List.of(pvogOrganisationsEinheit), group.getSubGroups().getFirst());
+				assertThat(synced.getSyncResult()).isEqualTo(syncedSyncResult);
 			}
 
 			@Test
 			void shouldGetOrganisationsEinheit() {
-				service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
+				var synced = service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
 
 				verify(organisationsEinheitRemoteService).getByOrganisationsEinheitId(GroupTestFactory.SUB_GROUP_ORGANISATIONS_EINHEIT_ID);
+				assertThat(synced.getOrganisationsEinheitId()).isEqualTo(group.getSubGroups().getFirst().getOrganisationsEinheitId());
 			}
 
 			@Test
@@ -233,9 +253,10 @@ class SyncServiceTest {
 
 			@Test
 			void shouldSyncZufiId() {
-				service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
+				var synced = service.syncGroup(group.getSubGroups().getFirst(), parent, syncTimestamp);
 
 				verify(service).syncZufiId(List.of(pvogOrganisationsEinheit));
+				assertThat(synced.getZufiId()).isEqualTo(syncedZufiId);
 			}
 
 			@Test
@@ -378,7 +399,7 @@ class SyncServiceTest {
 		@Nested
 		class SyncedOrganisationsEinheitExists {
 
-			private final OrganisationsEinheit existingOrganisationsEinheit = OrganisationsEinheitTestFactory.create();
+			private final OrganisationsEinheit existingOrganisationsEinheit = OrganisationsEinheitTestFactory.createNewBuilder().build();
 
 			@Captor
 			private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
@@ -422,8 +443,8 @@ class SyncServiceTest {
 		private final long syncTimestamp = Instant.now().toEpochMilli();
 		private final OrganisationsEinheit withoutSyncResult1 = OrganisationsEinheitTestFactory.createBuilder().id("A").build();
 		private final OrganisationsEinheit withoutSyncResult2 = OrganisationsEinheitTestFactory.createBuilder().id("B").build();
-		private final OrganisationsEinheit[] unsortedOrganisationsEinheiten = new OrganisationsEinheit[]{withoutSyncResult2, withoutSyncResult1};
-		private final OrganisationsEinheit[] sortedOrganisationsEinheiten = new OrganisationsEinheit[]{withoutSyncResult1, withoutSyncResult2};
+		private final OrganisationsEinheit[] unsortedOrganisationsEinheiten = new OrganisationsEinheit[] { withoutSyncResult2, withoutSyncResult1 };
+		private final OrganisationsEinheit[] sortedOrganisationsEinheiten = new OrganisationsEinheit[] { withoutSyncResult1, withoutSyncResult2 };
 
 		@Captor
 		private ArgumentCaptor<Stream<OrganisationsEinheit>> streamArgumentCaptor;
@@ -517,86 +538,110 @@ class SyncServiceTest {
 	class TestSyncAddedOrganisationsEinheit {
 
 		private final long syncTimestamp = Instant.now().toEpochMilli();
-		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
-		private final AddGroupData addGroupData = AddGroupDataTestFactory.create();
-		private final String keycloakId = GroupTestFactory.ID;
+		private final String addedGroupId = UUID.randomUUID().toString();
 		private final String parentKeycloakId = UUID.randomUUID().toString();
-
-		@BeforeEach
-		void setUp() {
-			doReturn(parentKeycloakId).when(service).findParentKeycloakId(organisationsEinheit);
-			when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId)).thenReturn(addGroupData);
-		}
+		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
+		private final OrganisationsEinheit parentWithoutKeycloakId = OrganisationsEinheitTestFactory.createBuilder().keycloakId(null).build();
+		private final OrganisationsEinheit parentWithKeycloakId = OrganisationsEinheitTestFactory.createBuilder().keycloakId(parentKeycloakId)
+				.build();
 
 		@Test
 		void shouldFindParentKeycloakId() {
-			mockAddGroupInKeycloak();
+			doReturn(Optional.of(parentWithoutKeycloakId)).when(service).findParent(organisationsEinheit);
 
 			callService();
 
-			verify(service).findParentKeycloakId(organisationsEinheit);
+			verify(service).findParent(organisationsEinheit);
 		}
 
-		@Test
-		void shouldCreateAddGroupData() {
-			mockAddGroupInKeycloak();
-
-			callService();
-
-			verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit, parentKeycloakId);
-		}
+		@Nested
+		class OnParentHasNoKeycloakId {
 
-		@Test
-		void shouldAddGroupInKeycloak() {
-			mockAddGroupInKeycloak();
+			@BeforeEach
+			void init() {
+				doReturn(Optional.of(parentWithoutKeycloakId)).when(service).findParent(organisationsEinheit);
+			}
 
-			callService();
+			@Test
+			void shouldNotAddAsGroupInKeycloak() {
+				callService();
 
-			verify(service).addGroupInKeycloak(addGroupData);
+				verify(service, never()).addAsGroupInKeycloak(any(), any());
+			}
 		}
 
 		@Nested
-		class OnAddGroupInKeycloakSuccessful {
-
-			@Captor
-			private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
+		class OnOrganisationsEinheitIsTopLevel {
 
 			@BeforeEach
 			void init() {
-				doReturn(Optional.of(keycloakId)).when(service).addGroupInKeycloak(addGroupData);
+				doReturn(Optional.empty()).when(service).findParent(organisationsEinheit);
 			}
 
 			@Test
-			void shouldSaveIfAddGroupSuccessful() {
+			void shouldAddAsGroupInKeycloakWithNullParent() {
+				doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, null);
+
 				callService();
 
-				verify(repository).save(savedOrganisationsEinheitArgumentCaptor.capture());
-				assertThat(savedOrganisationsEinheitArgumentCaptor.getValue()).extracting(
-						OrganisationsEinheit::getKeycloakId,
-						OrganisationsEinheit::getSyncResult,
-						OrganisationsEinheit::getLastSyncTimestamp
-				).containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
+				verify(service).addAsGroupInKeycloak(organisationsEinheit, null);
+			}
+
+			@Test
+			void shouldUpdateAfterSuccessfulGroupCreation() {
+				doReturn(Optional.of(addedGroupId)).when(service).addAsGroupInKeycloak(organisationsEinheit, null);
+				doNothing().when(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
+
+				callService();
+
+				verify(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
+			}
+
+			@Test
+			void shouldNotUpdate() {
+				doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, null);
+
+				callService();
+
+				verify(service, never()).updateAfterSuccessfulGroupCreation(any(), anyLong(), any());
 			}
 		}
 
 		@Nested
-		class OnAddGroupInKeycloakFailed {
+		class OnParentHasKeycloakId {
 
 			@BeforeEach
 			void init() {
-				doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
+				doReturn(Optional.of(parentWithKeycloakId)).when(service).findParent(organisationsEinheit);
 			}
 
 			@Test
-			void shouldNotSaveIfAddGroupFailed() {
+			void shouldAddAsGroupInKeycloakWithNullParent() {
+				doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
+
 				callService();
 
-				verify(repository, never()).save(any());
+				verify(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
 			}
-		}
 
-		private void mockAddGroupInKeycloak() {
-			doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
+			@Test
+			void shouldUpdateAfterSuccessfulGroupCreation() {
+				doReturn(Optional.of(addedGroupId)).when(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
+				doNothing().when(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
+
+				callService();
+
+				verify(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
+			}
+
+			@Test
+			void shouldNotUpdate() {
+				doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
+
+				callService();
+
+				verify(service, never()).updateAfterSuccessfulGroupCreation(any(), anyLong(), any());
+			}
 		}
 
 		private void callService() {
@@ -605,15 +650,15 @@ class SyncServiceTest {
 	}
 
 	@Nested
-	class TestFindParentKeycloakId {
+	class TestFindParent {
 
 		@Nested
 		class OnParentIdIsNull {
 			@Test
-			void shouldReturnNull() {
-				var parentKeycloakId = service.findParentKeycloakId(OrganisationsEinheitTestFactory.createBuilder().parentId(null).build());
+			void shouldReturnEmpty() {
+				var parent = service.findParent(OrganisationsEinheitTestFactory.createBuilder().parentId(null).build());
 
-				assertThat(parentKeycloakId).isNull();
+				assertThat(parent).isEmpty();
 			}
 		}
 
@@ -631,20 +676,87 @@ class SyncServiceTest {
 
 			@Test
 			void shouldFindById() {
-				service.findParentKeycloakId(organisationsEinheit);
+				callService();
 
 				verify(repository).findById(OrganisationsEinheitTestFactory.PARENT_ID);
 			}
 
 			@Test
-			void shouldReturnParentKeycloakId() {
-				var parentKeycloakId = service.findParentKeycloakId(organisationsEinheit);
+			void shouldReturnParent() {
+				var found = callService();
 
-				assertThat(parentKeycloakId).isEqualTo(PARENT_KEYCLOAK_ID);
+				assertThat(found).isPresent().get().isEqualTo(parent);
+			}
+
+			private Optional<OrganisationsEinheit> callService() {
+				return service.findParent(organisationsEinheit);
 			}
 		}
+	}
+
+	@Nested
+	class TestAddAsGroupInKeycloak {
 
+		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
+		private final String parentKeycloakId = UUID.randomUUID().toString();
+		private final AddGroupData addGroupData = AddGroupDataTestFactory.create();
+		private final String addedGroupId = UUID.randomUUID().toString();
 
+		@BeforeEach
+		void init() {
+			when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId)).thenReturn(addGroupData);
+			doReturn(Optional.of(addedGroupId)).when(service).addGroupInKeycloak(addGroupData);
+		}
+
+		@Test
+		void shouldCreateAddGroupData() {
+			callService();
+
+			verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit, parentKeycloakId);
+		}
+
+		@Test
+		void shouldAddGroupInKeycloak() {
+			callService();
+
+			verify(service).addGroupInKeycloak(addGroupData);
+		}
+
+		@Test
+		void shouldReturnAddedGroupId() {
+			var returnedGroupId = callService();
+
+			assertThat(returnedGroupId).get().isEqualTo(addedGroupId);
+		}
+
+		private Optional<String> callService() {
+			return service.addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
+		}
+	}
+
+	@Nested
+	class TestUpdateAfterSuccessfulGroupCreation {
+
+		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.createBuilder()
+				.keycloakId(null)
+				.syncResult(null)
+				.lastSyncTimestamp(null)
+				.build();
+		private final long syncTimestamp = Instant.now().toEpochMilli();
+		private final String keycloakId = UUID.randomUUID().toString();
+
+		@Captor
+		private ArgumentCaptor<OrganisationsEinheit> organisationsEinheitArgumentCaptor;
+
+		@Test
+		void shouldSaveUpdatedOrganisationsEinheit() {
+			service.updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, keycloakId);
+
+			verify(repository).save(organisationsEinheitArgumentCaptor.capture());
+			assertThat(organisationsEinheitArgumentCaptor.getValue())
+					.extracting(OrganisationsEinheit::getKeycloakId, OrganisationsEinheit::getSyncResult, OrganisationsEinheit::getLastSyncTimestamp)
+					.containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
+		}
 	}
 
 	@Nested