diff --git a/src/main/java/de/ozgcloud/admin/keycloak/KeycloakApiService.java b/src/main/java/de/ozgcloud/admin/keycloak/KeycloakApiService.java
index 057d0ab9622b949f7214008b131e956d76b70629..09b865543a58b34c7a89233f6f75ee0253bc8d6c 100644
--- a/src/main/java/de/ozgcloud/admin/keycloak/KeycloakApiService.java
+++ b/src/main/java/de/ozgcloud/admin/keycloak/KeycloakApiService.java
@@ -20,11 +20,17 @@ class KeycloakApiService {
 	}
 
 	public String addGroup(GroupRepresentation groupRepresentation) {
-		try (var response = groupsResource.add(groupRepresentation)) {
+		try (var response = addParentOrChildGroup(groupRepresentation)) {
 			return getAddedResourceIdFromResponse(response);
 		}
 	}
 
+	Response addParentOrChildGroup(GroupRepresentation groupRepresentation) {
+		return groupRepresentation.getParentId() == null ?
+				groupsResource.add(groupRepresentation) :
+				groupsResource.group(groupRepresentation.getParentId()).subGroup(groupRepresentation);
+	}
+
 	String getAddedResourceIdFromResponse(Response response) {
 		if (response.getStatus() == Response.Status.CREATED.getStatusCode()) {
 			return extractResourceIdFromLocationHeader(response.getHeaderString("Location"));
diff --git a/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheit.java b/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheit.java
index 0b6bfbbfc86229fa798b1c43671a1af904233526..012a2343ca6c64140adfd28740791b94c1ec8769 100644
--- a/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheit.java
+++ b/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheit.java
@@ -31,7 +31,7 @@ public class OrganisationsEinheit {
 	@JsonIgnore
 	private String zufiId;
 	@JsonIgnore
-	private long lastSyncTimestamp;
+	private Long lastSyncTimestamp;
 	@JsonIgnore
 	private String parentId;
 	@JsonIgnore
diff --git a/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapper.java b/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapper.java
index da1634ec80bf9a5169022184c50bba014dd735a4..193a6f05d8410e8733aad684fc8a4fb6761825f5 100644
--- a/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapper.java
+++ b/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapper.java
@@ -13,5 +13,6 @@ interface OrganisationsEinheitMapper {
 	@Mapping(target = "zufiId", source = "id")
 	OrganisationsEinheit fromGrpc(GrpcOrganisationsEinheit grpcOrganisationsEinheit);
 
-	AddGroupData toAddGroupData(OrganisationsEinheit organisationsEinheit);
+	@Mapping(target = "parentId", source = "parentKeycloakId")
+	AddGroupData toAddGroupData(OrganisationsEinheit organisationsEinheit, String parentKeycloakId);
 }
diff --git a/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncScheduler.java b/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncScheduler.java
index be92837909c12a4cd9c7c93c32decfa05d7e4e0a..116a7e0c61dd25b35b87dff650d47f5fc8566697 100644
--- a/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncScheduler.java
+++ b/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncScheduler.java
@@ -14,9 +14,11 @@ class SyncScheduler {
 
 	private final SyncService syncService;
 
-	@SchedulerLock(name = "SyncScheduler_syncOrganisationsEinheitenFromKeycloak", lockAtLeastFor = "PT5M", lockAtMostFor = "PT23H")
+	@SchedulerLock(name = "SyncScheduler_syncOrganisationsEinheitenWithKeycloak", lockAtLeastFor = "PT5M", lockAtMostFor = "PT23H")
 	@Scheduled(cron = "${ozgcloud.administration.sync.organisationseinheiten.cron}")
-	public void syncOrganisationsEinheitenFromKeycloak() {
-		syncService.syncOrganisationsEinheitenFromKeycloak(Instant.now().toEpochMilli());
+	public void syncOrganisationsEinheitenWithKeycloak() {
+		var syncTimestamp = Instant.now().toEpochMilli();
+		syncService.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
+		syncService.syncAddedOrganisationsEinheiten(syncTimestamp);
 	}
 }
diff --git a/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java b/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java
index 98139f6fa92396ba563328d59275744fadc6a802..80f607a3b81ae1f6aaa283536cebd6f81cee8a6a 100644
--- a/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java
+++ b/src/main/java/de/ozgcloud/admin/organisationseinheit/SyncService.java
@@ -2,6 +2,7 @@ package de.ozgcloud.admin.organisationseinheit;
 
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.springframework.stereotype.Service;
 
@@ -89,11 +90,32 @@ class SyncService {
 	}
 
 	public void syncAddedOrganisationsEinheiten(long syncTimestamp) {
-		repository.findAllWithoutSyncResult().forEach(organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
+		sortInAdditionOrder(repository.findAllWithoutSyncResult()).forEach(organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
+	}
+
+	Stream<OrganisationsEinheit> sortInAdditionOrder(Stream<OrganisationsEinheit> organisationsEinheiten) {
+		return organisationsEinheiten.sorted((org1, org2) -> {
+			if (org1.getParentId() == null && org2.getParentId() == null) {
+				return 0;
+			}
+			if (org1.getParentId() == null) {
+				return -1;
+			}
+			if (org2.getParentId() == null) {
+				return 1;
+			}
+			if (org1.getId().equals(org2.getParentId())) {
+				return -1;
+			}
+			if (org1.getParentId().equals(org2.getId())) {
+				return 1;
+			}
+			return 0;
+		});
 	}
 
 	void syncAddedOrganisationsEinheit(long syncTimestamp, OrganisationsEinheit organisationsEinheit) {
-		var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit);
+		var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit, findParentKeycloakId(organisationsEinheit));
 		var keycloakId = addGroupInKeycloak(addGroupData);
 		if (keycloakId.isPresent()) {
 			var updatedOrganisationsEinheit = organisationsEinheit.toBuilder()
@@ -105,6 +127,13 @@ class SyncService {
 		}
 	}
 
+	String findParentKeycloakId(OrganisationsEinheit organisationsEinheit) {
+		if (organisationsEinheit.getParentId() == null) {
+			return null;
+		}
+		return repository.findById(organisationsEinheit.getParentId()).map(OrganisationsEinheit::getKeycloakId).orElse(null);
+	}
+
 	Optional<String> addGroupInKeycloak(AddGroupData addGroupData) {
 		try {
 			return Optional.of(keycloakRemoteService.addGroup(addGroupData));
diff --git a/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java b/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java
index 67dcc55771e8d52ae9f4d926e9568a22d47795ac..034f962513dc0ffefe78f26ab9d7755281d763a0 100644
--- a/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java
+++ b/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java
@@ -13,6 +13,7 @@ class GroupRepresentationTestFactory {
 	public static final String ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE = "organisationseinheitId";
 
 	public static final String ID = UUID.randomUUID().toString();
+	public static final String PARENT_ID = UUID.randomUUID().toString();
 	public static final String NAME = LoremIpsum.getInstance().getName();
 	public static final String ORGANISATIONS_EINHEIT_ID = UUID.randomUUID().toString();
 	public static final Map<String, List<String>> ATTRIBUTES = Map.of(ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE, List.of(ORGANISATIONS_EINHEIT_ID));
@@ -43,6 +44,7 @@ class GroupRepresentationTestFactory {
 		if (withId) {
 			groupRepresentation.setId(ID);
 		}
+		groupRepresentation.setParentId(PARENT_ID);
 		groupRepresentation.setName(NAME);
 		groupRepresentation.setAttributes(ATTRIBUTES);
 		groupRepresentation.setSubGroups(List.of(createSubGroup(withId)));
@@ -54,6 +56,7 @@ class GroupRepresentationTestFactory {
 		if (withId) {
 			groupRepresentation.setId(SUB_GROUP_ID);
 		}
+		groupRepresentation.setParentId(ID);
 		groupRepresentation.setName(SUB_GROUP_NAME);
 		groupRepresentation.setAttributes(SUB_GROUP_ATTRIBUTES);
 		return groupRepresentation;
diff --git a/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java b/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java
index 848bc65b7ba24f6fd02eb89ea90d6afe441a4141..f4bbd5036da9a34a15704c19209e2d4571eb9705 100644
--- a/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java
+++ b/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java
@@ -8,6 +8,7 @@ import java.util.Optional;
 
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.keycloak.admin.client.resource.GroupsResource;
 import org.keycloak.representations.idm.GroupRepresentation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
@@ -25,6 +26,8 @@ class KeycloakApiServiceITCase {
 	private KeycloakApiService service;
 	@Autowired
 	private KeycloakApiProperties properties;
+	@Autowired
+	private GroupsResource groupsResource;
 
 	@Nested
 	class TestGetAllGroups {
@@ -146,7 +149,7 @@ class KeycloakApiServiceITCase {
 		}
 
 		@Test
-		void shouldNotAddSubgroups() {
+		void shouldNotAddSubgroupsOfAddedGroup() {
 			var groupToAdd = createUniqueGroupRepresentation("shouldNotAddSubgroups");
 
 			var groupId = service.addGroup(groupToAdd);
@@ -155,10 +158,26 @@ class KeycloakApiServiceITCase {
 					.asList().isEmpty();
 		}
 
-		private GroupRepresentation createUniqueGroupRepresentation(String suffix) {
+		@Test
+		void shouldAddSubgroupToParent() {
+			var parentToAdd = createUniqueGroupRepresentation("shouldAddSubgroupToParent-parent");
+			var parentId = service.addGroup(parentToAdd);
+			var childToAdd = createUniqueGroupRepresentation("shouldAddSubgroupToParent-child");
+			childToAdd.setParentId(parentId);
+
+			var childId = service.addGroup(childToAdd);
+
+			var subgroupsInKc = groupsResource.group(parentId).getSubGroups(0, Integer.MAX_VALUE, true);
+			assertThat(subgroupsInKc).hasSize(1).first().extracting(GroupRepresentation::getId, GroupRepresentation::getParentId)
+					.contains(childId, parentId);
+		}
+
+		private GroupRepresentation createUniqueGroupRepresentation(String nameSuffix) {
 			// LoremIpsum does not guarantee unique results when called repeatedly
-			var groupName = "%s (%s)".formatted(LoremIpsum.getInstance().getName(), suffix);
-			return GroupRepresentationTestFactory.createWithoutId(groupName);
+			var groupName = "%s (%s)".formatted(LoremIpsum.getInstance().getName(), nameSuffix);
+			var group = GroupRepresentationTestFactory.createWithoutId(groupName);
+			group.setParentId(null);
+			return group;
 		}
 
 		private Optional<GroupRepresentation> findGroupInKeycloak(String groupId) {
diff --git a/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceTest.java b/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceTest.java
index ffded7cebae2a78c00c622ba341eb840eec4f760..f04a47581dc3c2d7c67a79edb6f4ec3f1c69572b 100644
--- a/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceTest.java
+++ b/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceTest.java
@@ -6,6 +6,7 @@ import static org.mockito.Mockito.*;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.keycloak.admin.client.resource.GroupResource;
 import org.keycloak.admin.client.resource.GroupsResource;
 import org.keycloak.representations.idm.GroupRepresentation;
 import org.mockito.InjectMocks;
@@ -34,15 +35,15 @@ class KeycloakApiServiceTest {
 
 		@BeforeEach
 		void init() {
-			when(groupsResource.add(groupRepresentation)).thenReturn(response);
+			doReturn(response).when(service).addParentOrChildGroup(groupRepresentation);
 			doReturn(RESOURCE_ID).when(service).getAddedResourceIdFromResponse(response);
 		}
 
 		@Test
-		void shouldCallGroupsResource() {
+		void shouldAddParentOrChildGroup() {
 			callService();
 
-			verify(groupsResource).add(groupRepresentation);
+			verify(service).addParentOrChildGroup(groupRepresentation);
 		}
 
 		@Test
@@ -64,6 +65,69 @@ class KeycloakApiServiceTest {
 		}
 	}
 
+	@Nested
+	class TestAddParentOrChildGroup {
+
+		private GroupRepresentation groupRepresentation;
+
+		@Nested
+		class OnParentGroup {
+
+			@BeforeEach
+			void init() {
+				groupRepresentation = GroupRepresentationTestFactory.create();
+				groupRepresentation.setParentId(null);
+				when(groupsResource.add(groupRepresentation)).thenReturn(response);
+			}
+
+			@Test
+			void shouldCallGroupsResource() {
+				callService();
+
+				verify(groupsResource).add(groupRepresentation);
+			}
+
+			@Test
+			void shouldReturnResponse() {
+				var serviceResponse = callService();
+
+				assertThat(serviceResponse).isEqualTo(response);
+			}
+		}
+
+		@Nested
+		class OnChildGroup {
+
+			@Mock
+			private GroupResource groupResource;
+
+			@BeforeEach
+			void init() {
+				groupRepresentation = GroupRepresentationTestFactory.create();
+				when(groupsResource.group(GroupRepresentationTestFactory.PARENT_ID)).thenReturn(groupResource);
+				when(groupResource.subGroup(groupRepresentation)).thenReturn(response);
+			}
+
+			@Test
+			void shouldCallGroupResource() {
+				callService();
+
+				verify(groupResource).subGroup(groupRepresentation);
+			}
+
+			@Test
+			void shouldReturnResponse() {
+				var serviceResponse = callService();
+
+				assertThat(serviceResponse).isEqualTo(response);
+			}
+		}
+
+		private Response callService() {
+			return service.addParentOrChildGroup(groupRepresentation);
+		}
+	}
+
 	@Nested
 	class TestGetAddedResourceIdFromResponse {
 
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapperTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitMapperTest.java
index 10ee3a2de7fd8c740093d84f0444b90cf7b9d19a..3298e01121a50ad9858bec40e0828472e894e4a2 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.UUID;
 
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -44,16 +45,18 @@ class OrganisationsEinheitMapperTest {
 	@Nested
 	class TestToAddGroupData {
 
+		public static final String PARENT_KEYCLOAK_ID = UUID.randomUUID().toString();
+
 		@Test
 		void shouldMap() {
-			var mapped = mapper.toAddGroupData(OrganisationsEinheitTestFactory.create());
+			var mapped = mapper.toAddGroupData(OrganisationsEinheitTestFactory.create(), PARENT_KEYCLOAK_ID);
 
 			assertThat(mapped).extracting(
 					AddGroupData::getParentId,
 					AddGroupData::getName,
 					AddGroupData::getOrganisationsEinheitId
 			).containsExactly(
-					OrganisationsEinheitTestFactory.PARENT_ID,
+					PARENT_KEYCLOAK_ID,
 					OrganisationsEinheitTestFactory.NAME,
 					OrganisationsEinheitTestFactory.ORGANISATIONS_EINHEIT_ID
 			);
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncSchedulerTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncSchedulerTest.java
index a37a4ef8e34d65490814140497c972e90b57d0d3..c78510c4c8c77dabfe5bf774382775c6959af0fa 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncSchedulerTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncSchedulerTest.java
@@ -5,7 +5,7 @@ import static org.mockito.Mockito.*;
 
 import java.time.Instant;
 
-import org.assertj.core.data.Offset;
+import org.assertj.core.data.*;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
@@ -22,18 +22,34 @@ class SyncSchedulerTest {
 	private SyncService syncService;
 
 	@Nested
-	class TestSyncOrganisationsEinheitenFromKeycloak {
+	class TestSyncOrganisationsEinheitenWithKeycloak {
 
 		@Captor
 		private ArgumentCaptor<Long> syncTimestampArgumentCaptor;
 
 		@Test
-		void shouldCallService() {
-			scheduler.syncOrganisationsEinheitenFromKeycloak();
+		void shouldSyncOrganisationsEinheitenFromKeycloak() {
+			callService();
 
 			verify(syncService).syncOrganisationsEinheitenFromKeycloak(syncTimestampArgumentCaptor.capture());
+			assertThatSyncTimestampIsCloseToNow();
+		}
+
+		@Test
+		void shouldSyncAddedOrganisationsEinheiten() {
+			callService();
+
+			verify(syncService).syncAddedOrganisationsEinheiten(syncTimestampArgumentCaptor.capture());
+			assertThatSyncTimestampIsCloseToNow();
+		}
+
+		private void assertThatSyncTimestampIsCloseToNow() {
 			assertThat(syncTimestampArgumentCaptor.getValue()).isCloseTo(Instant.now().toEpochMilli(), Offset.offset(5000L));
 		}
+
+		private void callService() {
+			scheduler.syncOrganisationsEinheitenWithKeycloak();
+		}
 	}
 
 }
\ 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 401216f163eb0aadda47be61874496c5ccd57ba8..875324ebf97e9efc9133b313ea8b41eda2a981fc 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceTest.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/SyncServiceTest.java
@@ -5,6 +5,7 @@ import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 import java.time.Instant;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -416,15 +417,21 @@ class SyncServiceTest {
 	}
 
 	@Nested
-	class TestsyncAddedOrganisationsEinheiten {
+	class TestSyncAddedOrganisationsEinheiten {
 
 		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};
+
+		@Captor
+		private ArgumentCaptor<Stream<OrganisationsEinheit>> streamArgumentCaptor;
 
 		@BeforeEach
 		void setUp() {
-			when(repository.findAllWithoutSyncResult()).thenReturn(Stream.of(withoutSyncResult1, withoutSyncResult2));
+			when(repository.findAllWithoutSyncResult()).thenReturn(Stream.of(unsortedOrganisationsEinheiten));
+			doReturn(Stream.of(sortedOrganisationsEinheiten)).when(service).sortInAdditionOrder(any());
 			doNothing().when(service).syncAddedOrganisationsEinheit(anyLong(), any());
 		}
 
@@ -435,6 +442,14 @@ class SyncServiceTest {
 			verify(repository).findAllWithoutSyncResult();
 		}
 
+		@Test
+		void shouldSortInAdditionOrder() {
+			callService();
+
+			verify(service).sortInAdditionOrder(streamArgumentCaptor.capture());
+			assertThat(streamArgumentCaptor.getValue()).containsExactly(unsortedOrganisationsEinheiten);
+		}
+
 		@Test
 		void shouldSynchronizeFirstOrganisationsEinheit() {
 			callService();
@@ -449,11 +464,55 @@ class SyncServiceTest {
 			verify(service).syncAddedOrganisationsEinheit(syncTimestamp, withoutSyncResult2);
 		}
 
+		@Test
+		void shouldSynchronizeInOrder() {
+			var inOrder = inOrder(service);
+
+			callService();
+
+			Arrays.stream(sortedOrganisationsEinheiten).forEach(organisationsEinheit ->
+					inOrder.verify(service).syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
+		}
+
 		private void callService() {
 			service.syncAddedOrganisationsEinheiten(syncTimestamp);
 		}
 	}
 
+	@Nested
+	class TestSortInAdditionOrder {
+
+		@Test
+		void shouldTopLevelOrgComeFirst() {
+			var orgWithParent = OrganisationsEinheitTestFactory.create();
+			var orgWithoutParent = OrganisationsEinheitTestFactory.createBuilder().parentId(null).build();
+
+			var sorted = service.sortInAdditionOrder(Stream.of(orgWithParent, orgWithoutParent));
+
+			assertThat(sorted).containsExactly(orgWithoutParent, orgWithParent);
+		}
+
+		@Test
+		void shouldParentComeBeforeChild() {
+			var parent = OrganisationsEinheitTestFactory.create();
+			var child = OrganisationsEinheitTestFactory.createBuilder().parentId(parent.getId()).build();
+
+			var sorted = service.sortInAdditionOrder(Stream.of(child, parent));
+
+			assertThat(sorted).containsExactly(parent, child);
+		}
+
+		@Test
+		void shouldPreserveOrderForTopLevelGroups() {
+			var orgWithoutParent1 = OrganisationsEinheitTestFactory.createBuilder().parentId(null).build();
+			var orgWithoutParent2 = OrganisationsEinheitTestFactory.createBuilder().parentId(null).build();
+
+			var sorted = service.sortInAdditionOrder(Stream.of(orgWithoutParent1, orgWithoutParent2));
+
+			assertThat(sorted).containsExactly(orgWithoutParent1, orgWithoutParent2);
+		}
+	}
+
 	@Nested
 	class TestSyncAddedOrganisationsEinheit {
 
@@ -461,61 +520,82 @@ class SyncServiceTest {
 		private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
 		private final AddGroupData addGroupData = AddGroupDataTestFactory.create();
 		private final String keycloakId = GroupTestFactory.ID;
-
-		@Captor
-		private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
+		private final String parentKeycloakId = UUID.randomUUID().toString();
 
 		@BeforeEach
 		void setUp() {
-			when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit)).thenReturn(addGroupData);
+			doReturn(parentKeycloakId).when(service).findParentKeycloakId(organisationsEinheit);
+			when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId)).thenReturn(addGroupData);
 		}
 
 		@Test
-		void shouldCreateAddGroupData() {
-			givenAddGroupInKeycloakSuccessful();
+		void shouldFindParentKeycloakId() {
+			mockAddGroupInKeycloak();
 
 			callService();
 
-			verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit);
+			verify(service).findParentKeycloakId(organisationsEinheit);
 		}
 
 		@Test
-		void shouldAddGroupInKeycloak() {
-			givenAddGroupInKeycloakSuccessful();
+		void shouldCreateAddGroupData() {
+			mockAddGroupInKeycloak();
 
 			callService();
 
-			verify(service).addGroupInKeycloak(addGroupData);
+			verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit, parentKeycloakId);
 		}
 
 		@Test
-		void shouldSaveIfAddGroupSuccessful() {
-			givenAddGroupInKeycloakSuccessful();
+		void shouldAddGroupInKeycloak() {
+			mockAddGroupInKeycloak();
 
 			callService();
 
-			verify(repository).save(savedOrganisationsEinheitArgumentCaptor.capture());
-			assertThat(savedOrganisationsEinheitArgumentCaptor.getValue()).extracting(
-					OrganisationsEinheit::getKeycloakId,
-					OrganisationsEinheit::getSyncResult,
-					OrganisationsEinheit::getLastSyncTimestamp
-			).containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
+			verify(service).addGroupInKeycloak(addGroupData);
 		}
 
-		@Test
-		void shouldNotSaveIfAddGroupFailed() {
-			givenAddGroupInKeycloakFailed();
+		@Nested
+		class OnAddGroupInKeycloakSuccessful {
 
-			callService();
+			@Captor
+			private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
+
+			@BeforeEach
+			void init() {
+				doReturn(Optional.of(keycloakId)).when(service).addGroupInKeycloak(addGroupData);
+			}
+
+			@Test
+			void shouldSaveIfAddGroupSuccessful() {
+				callService();
 
-			verifyNoInteractions(repository);
+				verify(repository).save(savedOrganisationsEinheitArgumentCaptor.capture());
+				assertThat(savedOrganisationsEinheitArgumentCaptor.getValue()).extracting(
+						OrganisationsEinheit::getKeycloakId,
+						OrganisationsEinheit::getSyncResult,
+						OrganisationsEinheit::getLastSyncTimestamp
+				).containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
+			}
 		}
 
-		private void givenAddGroupInKeycloakSuccessful() {
-			doReturn(Optional.of(keycloakId)).when(service).addGroupInKeycloak(addGroupData);
+		@Nested
+		class OnAddGroupInKeycloakFailed {
+
+			@BeforeEach
+			void init() {
+				doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
+			}
+
+			@Test
+			void shouldNotSaveIfAddGroupFailed() {
+				callService();
+
+				verify(repository, never()).save(any());
+			}
 		}
 
-		private void givenAddGroupInKeycloakFailed() {
+		private void mockAddGroupInKeycloak() {
 			doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
 		}
 
@@ -524,6 +604,49 @@ class SyncServiceTest {
 		}
 	}
 
+	@Nested
+	class TestFindParentKeycloakId {
+
+		@Nested
+		class OnParentIdIsNull {
+			@Test
+			void shouldReturnNull() {
+				var parentKeycloakId = service.findParentKeycloakId(OrganisationsEinheitTestFactory.createBuilder().parentId(null).build());
+
+				assertThat(parentKeycloakId).isNull();
+			}
+		}
+
+		@Nested
+		class OnParentIdIsNotNull {
+
+			private final String PARENT_KEYCLOAK_ID = UUID.randomUUID().toString();
+			private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
+			private final OrganisationsEinheit parent = OrganisationsEinheitTestFactory.createBuilder().keycloakId(PARENT_KEYCLOAK_ID).build();
+
+			@BeforeEach
+			void init() {
+				when(repository.findById(OrganisationsEinheitTestFactory.PARENT_ID)).thenReturn(Optional.of(parent));
+			}
+
+			@Test
+			void shouldFindById() {
+				service.findParentKeycloakId(organisationsEinheit);
+
+				verify(repository).findById(OrganisationsEinheitTestFactory.PARENT_ID);
+			}
+
+			@Test
+			void shouldReturnParentKeycloakId() {
+				var parentKeycloakId = service.findParentKeycloakId(organisationsEinheit);
+
+				assertThat(parentKeycloakId).isEqualTo(PARENT_KEYCLOAK_ID);
+			}
+		}
+
+
+	}
+
 	@Nested
 	class TestAddGroupInKeycloak {