diff --git a/common/src/main/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelle.java b/common/src/main/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelle.java
index 4de3040e543b837699024b45c710d1b7abb8d7e0..19d6b1b39921e5dcc3224b42066aecff493b28d7 100644
--- a/common/src/main/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelle.java
+++ b/common/src/main/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelle.java
@@ -35,4 +35,10 @@ public class ZustaendigeStelle {
 	private String organisationseinheitenId;
 	private String bezeichnung;
 	private String email;
+	private String gemeindeSchluessel;
+	private String amtlicherRegionalSchluessel;
+	private String hausanschriftStrasse;
+	private String hausanschriftPlz;
+	private String hausanschriftOrt;
+	private String telefon;
 }
diff --git a/common/src/test/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelleTestFactory.java b/common/src/test/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelleTestFactory.java
index 2ffa27d9f2daba7531f0f06438e7f5624d56f467..fe990b8f81c42db2a65a480524b7a64d0e5a70a4 100644
--- a/common/src/test/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelleTestFactory.java
+++ b/common/src/test/java/de/ozgcloud/eingang/common/formdata/ZustaendigeStelleTestFactory.java
@@ -27,6 +27,12 @@ public class ZustaendigeStelleTestFactory {
 
 	public static final String ORGANISATIONSEINHEIT_ID = "08150815";
 	public static final String EMAIL = "hase@loewenkaefig.de";
+	public static final String GEMEINDE_SCHLUESSEL = "1234567";
+	public static final String AMTLICHER_REGIONAL_SCHLUESSEL = "regional-schluessel";
+	public static final String HAUSANSCHRIFT_STRASSE = "Musterstraße";
+	public static final String HAUSANSCHRIFT_PLZ = "12345";
+	public static final String HAUSANSCHRIFT_ORT = "Musterort";
+	public static final String TELEFON = "0123456789";
 
 	public static ZustaendigeStelle create() {
 		return createBuilder().build();
@@ -35,6 +41,12 @@ public class ZustaendigeStelleTestFactory {
 	public static ZustaendigeStelle.ZustaendigeStelleBuilder createBuilder() {
 		return ZustaendigeStelle.builder() //
 				.organisationseinheitenId(ORGANISATIONSEINHEIT_ID)
-				.email(EMAIL);
+				.email(EMAIL)
+				.gemeindeSchluessel(GEMEINDE_SCHLUESSEL)
+				.amtlicherRegionalSchluessel(AMTLICHER_REGIONAL_SCHLUESSEL)
+				.hausanschriftStrasse(HAUSANSCHRIFT_STRASSE)
+				.hausanschriftPlz(HAUSANSCHRIFT_PLZ)
+				.hausanschriftOrt(HAUSANSCHRIFT_ORT)
+				.telefon(TELEFON);
 	}
 }
diff --git a/intelliform-adapter/src/main/java/de/ozgcloud/eingang/SemantikAdapterConfiguration.java b/intelliform-adapter/src/main/java/de/ozgcloud/eingang/SemantikAdapterConfiguration.java
index dd6ada82e85d34ecb6befee9dd5c506f95172fe4..7c70b8144a3b5da22da7b1962216c9ada61dceba 100644
--- a/intelliform-adapter/src/main/java/de/ozgcloud/eingang/SemantikAdapterConfiguration.java
+++ b/intelliform-adapter/src/main/java/de/ozgcloud/eingang/SemantikAdapterConfiguration.java
@@ -36,4 +36,5 @@ public class SemantikAdapterConfiguration {
 	public EngineBasedSemantikAdapter engineBasedSemantikAdapter() {
 		return new AfmEngineBasedAdapter();
 	}
+
 }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8a57b5b9cf5655cde9efe8c07b35d00de73b6e70..21e99a3e97973b851457a49f353883b237824aa5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,7 @@
 	<properties>
 		<mapstruct.version>1.4.2.Final</mapstruct.version>
 
-		<pluto.version>1.16.0</pluto.version>
+		<pluto.version>1.17.0-SNAPSHOT</pluto.version>
 
 		<jsoup.version>1.14.3</jsoup.version>
 		<xmlschema.version>2.3.0</xmlschema.version>
diff --git a/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java b/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java
index 089c7fb8b31f0f1fc60a7ebef1c7524e0c3d70d0..b06d3c5675c9a85455b3da02b9cb52958c5113f2 100644
--- a/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java
+++ b/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java
@@ -42,6 +42,7 @@ import de.itvsh.ozg.pluto.vorgang.GrpcZustaendigeStelle;
 import de.ozgcloud.eingang.common.formdata.Antragsteller;
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
 
 @Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, //
 		unmappedSourcePolicy = ReportingPolicy.WARN, //
@@ -77,7 +78,7 @@ public interface GrpcEingangMapper {
 	@Mapping(target = "unknownFields", ignore = true)
 	@Mapping(target = "allFields", ignore = true)
 
-	GrpcZustaendigeStelle toZustaendigeStelle(de.ozgcloud.eingang.common.formdata.ZustaendigeStelle zustaendigeStelle);
+	GrpcZustaendigeStelle toZustaendigeStelle(ZustaendigeStelle zustaendigeStelle);
 
 	GrpcAntragsteller toAntragsteller(Antragsteller antragsteller);
 
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java
index e8ff80f8d833cd1af8d2ab867b4b3ea990fe7c5b..1e057c6e81f5c937a429d8050c2c8996742026c9 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
@@ -43,8 +44,18 @@ class AfmZustaendigeStelleMapper implements AfmEngineBasedMapper {
 	public static final String ORGANISATIONSEINHEITEN_ID = "OrganisationseinheitenID";
 	public static final String TAG_BEZEICHNUNG = "OrganisationseinheitenBEZEICHNUNG";
 
+	@Autowired
+	private ZustaendigeStelleMetadataMapper zustaendigeStelleMetadataMapper;
+
 	@Override
 	public FormData parseFormData(FormData formData) {
+		if (zustaendigeStelleMetadataMapper.isResponsible(formData)) {
+			return zustaendigeStelleMetadataMapper.parseZustaendigeStelleData(formData);
+		}
+		return parseZustaendigeStelleData(formData);
+	}
+
+	FormData parseZustaendigeStelleData(FormData formData) {
 		var zustaendigeStelleMap = getZustaendigeStelle(formData);
 		var organisationseinheitenID = getOrganisationseinheitenId(formData);
 		var builder = ZustaendigeStelle.builder();
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/XmlMapperSupplier.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/XmlMapperSupplier.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a4b166b5140b283b4e9fa1f8a433991d51c53ae
--- /dev/null
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/XmlMapperSupplier.java
@@ -0,0 +1,21 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+
+@Component
+public class XmlMapperSupplier {
+
+	private final XmlMapper xmlMapper;
+
+	public XmlMapperSupplier() {
+		xmlMapper = new XmlMapper();
+		xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	}
+
+	public XmlMapper getMapper() {
+		return xmlMapper;
+	}
+}
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleData.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleData.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f085ab99a1b6c7005799b5e91e0618541e4a2af
--- /dev/null
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleData.java
@@ -0,0 +1,43 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import java.util.List;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.Singular;
+
+@JacksonXmlRootElement(localName = "data")
+@Builder
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class ZustaendigeStelleData {
+
+	@JacksonXmlProperty(localName = "field")
+	@JacksonXmlElementWrapper(useWrapping = false)
+	@Singular
+	private List<Field> fields;
+
+	@Getter
+	@Setter
+	@NoArgsConstructor
+	@AllArgsConstructor
+	@Builder
+	public static class Field {
+
+		@JacksonXmlProperty(isAttribute = true)
+		private String name;
+
+		@JacksonXmlText
+		private String value;
+
+	}
+}
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..505d274ea5627e3634cf349943b301d70de2857b
--- /dev/null
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java
@@ -0,0 +1,86 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import static java.util.Objects.*;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import de.itvsh.kop.common.errorhandling.TechnicalException;
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+@Component
+public class ZustaendigeStelleMetadataMapper {
+
+	static final String BEHOERDE_METADATA_FILE_NAME = "behoerde_metadata.xml";
+
+	private static final Predicate<IncomingFile> IS_BEHOERDE_METADATA = inFile -> StringUtils.endsWith(inFile.getName(), BEHOERDE_METADATA_FILE_NAME);
+
+	static final String KEY_BEHOERDE_ANZEIGE_NAME = "behoerde_anzeige_name";
+	static final String KEY_BEHOERDE_CALLER_ID = "behoerde_caller_id";
+	static final String KEY_GEMEINDE_SCHLUESSEL_BP = "gemeinde_schluessel_bp";
+	static final String KEY_BEHOERDE_EMAIL = "behoerde_email";
+	static final String KEY_AMTLICHER_REGIONALSCHLUESSEL = "amtlicher_regionalschluessel";
+	static final String KEY_BEHOERDE_HAUSANSCHRIFT_STRASSE = "behoerde_hausanschrift_strasse";
+	static final String KEY_BEHOERDE_HAUSANSCHRIFT_ORT = "behoerde_hausanschrift_ort";
+	static final String KEY_BEHOERDE_HAUSANSCHRIFT_PLZ = "behoerde_hausanschrift_plz";
+	static final String KEY_BEHOERDE_TELEFON = "behoerde_telefon";
+
+	@Autowired
+	private XmlMapperSupplier xmlMapperSupplier;
+
+	public FormData parseZustaendigeStelleData(FormData formData) {
+		return formData.getRepresentations().stream().filter(IS_BEHOERDE_METADATA).findAny()
+				.map(this::readZustaendigeStelleMetadata)
+				.map(this::mapZustaendigeStelle)
+				.map(zustaendigeStelle -> formData.toBuilder().zustaendigeStelle(zustaendigeStelle).build())
+				.orElse(formData);
+	}
+
+	Map<String, String> readZustaendigeStelleMetadata(IncomingFile metadata) {
+		return readXmlContent(metadata).map(ZustaendigeStelleData::getFields).map(this::collectToMap).orElse(Collections.emptyMap());
+	}
+
+	Optional<ZustaendigeStelleData> readXmlContent(IncomingFile metadata) {
+		try {
+			return Optional.of(xmlMapperSupplier.getMapper().readValue(metadata.getContentStream(), ZustaendigeStelleData.class));
+		} catch (IOException | TechnicalException e) {
+			LOG.error("Error parsing {}", BEHOERDE_METADATA_FILE_NAME, e);
+		}
+		return Optional.empty();
+	}
+
+	Map<String, String> collectToMap(List<ZustaendigeStelleData.Field> fields) {
+		return fields.stream().filter(field -> nonNull(field.getValue()))
+				.collect(Collectors.toMap(ZustaendigeStelleData.Field::getName, ZustaendigeStelleData.Field::getValue));
+	}
+
+	ZustaendigeStelle mapZustaendigeStelle(Map<String, String> zustaendigeStelleMetadata) {
+		return ZustaendigeStelle.builder()
+				.bezeichnung(zustaendigeStelleMetadata.get(KEY_BEHOERDE_ANZEIGE_NAME))
+				.organisationseinheitenId(zustaendigeStelleMetadata.get(KEY_BEHOERDE_CALLER_ID))
+				.gemeindeSchluessel(zustaendigeStelleMetadata.get(KEY_GEMEINDE_SCHLUESSEL_BP))
+				.email(zustaendigeStelleMetadata.get(KEY_BEHOERDE_EMAIL))
+				.amtlicherRegionalSchluessel(zustaendigeStelleMetadata.get(KEY_AMTLICHER_REGIONALSCHLUESSEL))
+				.hausanschriftStrasse(zustaendigeStelleMetadata.get(KEY_BEHOERDE_HAUSANSCHRIFT_STRASSE))
+				.hausanschriftOrt(zustaendigeStelleMetadata.get(KEY_BEHOERDE_HAUSANSCHRIFT_ORT))
+				.hausanschriftPlz(zustaendigeStelleMetadata.get(KEY_BEHOERDE_HAUSANSCHRIFT_PLZ))
+				.telefon(zustaendigeStelleMetadata.get(KEY_BEHOERDE_TELEFON)).build();
+	}
+
+	public boolean isResponsible(FormData formData) {
+		return formData.getRepresentations().stream().anyMatch(IS_BEHOERDE_METADATA);
+	}
+}
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java
index c8ee29bd8101967aa0c44135d3faf80dccc80608..4f83cb409499a33c332c3b8226012cf210949ae8 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java
@@ -32,12 +32,11 @@ import java.util.Map;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
+import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
-import de.ozgcloud.eingang.semantik.enginebased.afm.AfmEngineBasedMapper;
-import de.ozgcloud.eingang.semantik.enginebased.afm.AfmZustaendigeStelleMapper;
 
 class AfmZustaendigeStelleMapperTest {
 
@@ -45,6 +44,9 @@ class AfmZustaendigeStelleMapperTest {
 	@Spy
 	private AfmZustaendigeStelleMapper mapper;
 
+	@Mock
+	private ZustaendigeStelleMetadataMapper zustaendigeStelleMetadataMapper;
+
 	@Nested
 	class TestParseFormData {
 
@@ -67,14 +69,14 @@ class AfmZustaendigeStelleMapperTest {
 			void shouldReturnFormDataOnNonExistingZustaendigeStelleAndOrganisationseinheitenId() {
 				var emptyFormData = FormData.builder().formData(new HashMap<String, Object>()).build();
 
-				var parsedFormData = parseFormData(emptyFormData);
+				var parsedFormData = parseZustaendigeStelleData(emptyFormData);
 
 				assertThat(parsedFormData).isEqualTo(emptyFormData);
 			}
 
 			@Test
 			void shouldMapOrganisationseinheitenId() {
-				var parsedFormData = parseFormData(formData);
+				var parsedFormData = parseZustaendigeStelleData(formData);
 
 				assertThat(parsedFormData.getZustaendigeStelle().getOrganisationseinheitenId())
 						.isEqualTo(AfmZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID);
@@ -82,17 +84,39 @@ class AfmZustaendigeStelleMapperTest {
 
 			@Test
 			void shouldMapBezeichnung() {
-				var parsedFormData = parseFormData(formData);
+				var parsedFormData = parseZustaendigeStelleData(formData);
 
 				assertThat(parsedFormData.getZustaendigeStelle().getBezeichnung()).isEqualTo(BEZEICHNUNG);
 			}
 
 			@Test
 			void shouldMapEmail() {
-				var parsedFormData = parseFormData(formData);
+				var parsedFormData = parseZustaendigeStelleData(formData);
 
 				assertThat(parsedFormData.getZustaendigeStelle().getEmail()).isEqualTo(AfmZustaendigeStelleTestFactory.EMAIL);
 			}
+
+			@Test
+			void shouldCallparseZustaendigeStelleData() {
+				parseFormData(formData);
+
+				verify(mapper).parseZustaendigeStelleData(formData);
+			}
+
+			@Test
+			void shouldCallParseBayernMetadata() {
+				when(zustaendigeStelleMetadataMapper.isResponsible(any())).thenReturn(true);
+				var expectedFormData = FormDataTestFactory.create();
+				when(zustaendigeStelleMetadataMapper.parseZustaendigeStelleData(any())).thenReturn(expectedFormData);
+
+				var resultFormData = parseFormData(formData);
+
+				assertThat(resultFormData).isEqualTo(expectedFormData);
+			}
+
+			private FormData parseZustaendigeStelleData(FormData formData) {
+				return mapper.parseZustaendigeStelleData(formData);
+			}
 		}
 
 		@Nested
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleDataTestFactory.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleDataTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7d82d624f06de55c99069480ce537b66edab2a3
--- /dev/null
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleDataTestFactory.java
@@ -0,0 +1,62 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import static de.ozgcloud.eingang.semantik.enginebased.afm.ZustaendigeStelleMetadataMapper.*;
+
+import java.util.List;
+import java.util.Map;
+
+import de.ozgcloud.eingang.semantik.enginebased.afm.ZustaendigeStelleData.ZustaendigeStelleDataBuilder;
+
+public class ZustaendigeStelleDataTestFactory {
+	public static final String BEHOERDE_ANZEIGE_NAME = "Landratsamt XYZ (Testbehörde für BDA)";
+	public static final String BEHOERDE_CALLER_ID = "87331322433";
+	public static final String GEMEINDE_SCHLUESSEL_BP = "09189155";
+	public static final String BEHOERDE_EMAIL = "poststelle@testbehoerde.bayern";
+	public static final String AMTLICHER_REGIONALSCHLUESSEL = "091890000000";
+	public static final String BEHOERDE_HAUSANSCHRIFT_STRASSE = "Teststraße 1";
+	public static final String BEHOERDE_HAUSANSCHRIFT_ORT = "Musterstadt";
+	public static final String BEHOERDE_HAUSANSCHRIFT_PLZ = "12345";
+	public static final String BEHOERDE_TELEFON = "+49 123 45-0";
+
+	public static final Map<String, String> BEHOERDE_METADATA = Map.of(
+			KEY_BEHOERDE_ANZEIGE_NAME, BEHOERDE_ANZEIGE_NAME,
+			KEY_BEHOERDE_CALLER_ID, BEHOERDE_CALLER_ID,
+			KEY_GEMEINDE_SCHLUESSEL_BP, GEMEINDE_SCHLUESSEL_BP,
+			KEY_BEHOERDE_EMAIL, BEHOERDE_EMAIL,
+			KEY_AMTLICHER_REGIONALSCHLUESSEL, AMTLICHER_REGIONALSCHLUESSEL,
+			KEY_BEHOERDE_HAUSANSCHRIFT_STRASSE, BEHOERDE_HAUSANSCHRIFT_STRASSE,
+			KEY_BEHOERDE_HAUSANSCHRIFT_ORT, BEHOERDE_HAUSANSCHRIFT_ORT,
+			KEY_BEHOERDE_HAUSANSCHRIFT_PLZ, BEHOERDE_HAUSANSCHRIFT_PLZ,
+			KEY_BEHOERDE_TELEFON, BEHOERDE_TELEFON
+	);
+
+	public static final List<ZustaendigeStelleData.Field> ZUSTAENDIGE_STELLE_DATA_FIELDS = List.of(
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_ANZEIGE_NAME)
+					.value(ZustaendigeStelleDataTestFactory.BEHOERDE_ANZEIGE_NAME).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_CALLER_ID)
+					.value(ZustaendigeStelleDataTestFactory.BEHOERDE_CALLER_ID).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_GEMEINDE_SCHLUESSEL_BP)
+					.value(ZustaendigeStelleDataTestFactory.GEMEINDE_SCHLUESSEL_BP).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_EMAIL).value(ZustaendigeStelleDataTestFactory.BEHOERDE_EMAIL)
+					.build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_AMTLICHER_REGIONALSCHLUESSEL)
+					.value(ZustaendigeStelleDataTestFactory.AMTLICHER_REGIONALSCHLUESSEL).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_HAUSANSCHRIFT_STRASSE)
+					.value(ZustaendigeStelleDataTestFactory.BEHOERDE_HAUSANSCHRIFT_STRASSE).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_HAUSANSCHRIFT_ORT)
+					.value(ZustaendigeStelleDataTestFactory.BEHOERDE_HAUSANSCHRIFT_ORT).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_HAUSANSCHRIFT_PLZ)
+					.value(ZustaendigeStelleDataTestFactory.BEHOERDE_HAUSANSCHRIFT_PLZ).build(),
+			ZustaendigeStelleMetadataFieldTestFactory.createBuilder().name(KEY_BEHOERDE_TELEFON).value(ZustaendigeStelleDataTestFactory.BEHOERDE_TELEFON)
+					.build()
+	);
+
+	public static ZustaendigeStelleData create() {
+		return createBuilder().build();
+	}
+
+	public static ZustaendigeStelleDataBuilder createBuilder() {
+		return ZustaendigeStelleData.builder()
+				.fields(ZUSTAENDIGE_STELLE_DATA_FIELDS);
+	}
+}
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataFieldTestFactory.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataFieldTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..2508c76dde41ccc174ed79a3a97c23b08a883a50
--- /dev/null
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataFieldTestFactory.java
@@ -0,0 +1,20 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import de.ozgcloud.eingang.semantik.enginebased.afm.ZustaendigeStelleData.Field;
+import de.ozgcloud.eingang.semantik.enginebased.afm.ZustaendigeStelleData.Field.FieldBuilder;
+
+public class ZustaendigeStelleMetadataFieldTestFactory {
+
+	public static final String FIELD_NAME = "name";
+	public static final String FIELD_VALUE = "value";
+
+	public static Field create() {
+		return createBuilder().build();
+	}
+
+	public static FieldBuilder createBuilder() {
+		return Field.builder()
+				.name(FIELD_NAME)
+				.value(FIELD_VALUE);
+	}
+}
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperITCase.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1ff2336639729b40f08a08a6b663e8841a6d931
--- /dev/null
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperITCase.java
@@ -0,0 +1,50 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import static de.ozgcloud.eingang.semantik.enginebased.afm.ZustaendigeStelleMetadataMapper.*;
+import static org.assertj.core.api.Assertions.*;
+
+import java.io.File;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import de.itvsh.kop.common.test.ITCase;
+import de.itvsh.kop.common.test.TestUtils;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
+import lombok.SneakyThrows;
+
+@ITCase
+class ZustaendigeStelleMetadataMapperITCase {
+
+	@Autowired
+	private ZustaendigeStelleMetadataMapper mapper;
+
+	private IncomingFile behoerdeMetadataXml;
+
+	@SneakyThrows
+	@BeforeEach
+	void setUp() {
+		behoerdeMetadataXml = IncomingFileTestFactory.createBuilder()
+				.name(ZustaendigeStelleMetadataMapper.BEHOERDE_METADATA_FILE_NAME)
+				.file(new File(TestUtils.class.getClassLoader().getResource(BEHOERDE_METADATA_FILE_NAME).toURI())).build();
+
+	}
+
+	@Test
+	void shouldReadXmlNodes() {
+		var metadata = mapper.readXmlContent(behoerdeMetadataXml);
+
+		assertThat(metadata).get().extracting("fields").asList().usingRecursiveFieldByFieldElementComparator()
+				.containsAll(ZustaendigeStelleDataTestFactory.ZUSTAENDIGE_STELLE_DATA_FIELDS);
+	}
+
+	@SneakyThrows
+	@Test
+	void shouldCatchException() {
+		var zustaendigeStelleData = mapper.readXmlContent(IncomingFileTestFactory.createBuilder().file(new File("broken-file")).build());
+
+		assertThat(zustaendigeStelleData).isEmpty();
+	}
+}
\ No newline at end of file
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5da34d86397802416e222b17f31722392944791d
--- /dev/null
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java
@@ -0,0 +1,173 @@
+package de.ozgcloud.eingang.semantik.enginebased.afm;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelleTestFactory;
+import lombok.SneakyThrows;
+
+class ZustaendigeStelleMetadataMapperTest {
+
+	@Spy
+	@InjectMocks
+	private ZustaendigeStelleMetadataMapper mapper;
+
+	@Mock
+	private XmlMapper xmlMapper;
+
+	@Nested
+	class TestParseBehoerdeMetadata {
+
+		private IncomingFile behoerdeMetadataFile;
+
+		private FormData formData;
+
+		@BeforeEach
+		void setUp() {
+			behoerdeMetadataFile = IncomingFileTestFactory.createBuilder().name(ZustaendigeStelleMetadataMapper.BEHOERDE_METADATA_FILE_NAME)
+					.build();
+			formData = FormDataTestFactory.createBuilder()
+					.zustaendigeStelle(null)
+					.representation(behoerdeMetadataFile).build();
+		}
+
+		@SneakyThrows
+		@Test
+		void shouldCallReadBehoerdeMetadata() {
+			doReturn(ZustaendigeStelleDataTestFactory.BEHOERDE_METADATA).when(mapper).readZustaendigeStelleMetadata(behoerdeMetadataFile);
+
+			mapper.parseZustaendigeStelleData(formData);
+
+			verify(mapper).readZustaendigeStelleMetadata(behoerdeMetadataFile);
+		}
+
+		@Test
+		void shouldCallMapZustaendigeStelle() {
+			var behoerdeMetadata = Map.of("key", "value");
+			doReturn(behoerdeMetadata).when(mapper).readZustaendigeStelleMetadata(behoerdeMetadataFile);
+
+			mapper.parseZustaendigeStelleData(formData);
+
+			verify(mapper).mapZustaendigeStelle(behoerdeMetadata);
+		}
+
+		@Test
+		void shouldSetParsedZustaendigeStelle() {
+			doReturn(Map.of("key", "value")).when(mapper).readZustaendigeStelleMetadata(any());
+			var zustaendigeStelle = ZustaendigeStelleTestFactory.create();
+			doReturn(zustaendigeStelle).when(mapper).mapZustaendigeStelle(any());
+
+			var result = mapper.parseZustaendigeStelleData(formData);
+
+			assertThat(result.getZustaendigeStelle()).isEqualTo(zustaendigeStelle);
+		}
+	}
+
+	@Nested
+	class TestReadBehoerdeMetadata {
+
+
+		private File brokenFile;
+
+
+	}
+
+	@Nested
+	class TestMapZuestaendigeStelle {
+
+		@Test
+		void shouldSetBezeichnung() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getBezeichnung()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_ANZEIGE_NAME);
+		}
+
+		@Test
+		void shouldSetOrganisationEinheitId() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getOrganisationseinheitenId()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_CALLER_ID);
+		}
+
+		@Test
+		void shouldSetGemeindeSchluessel() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getGemeindeSchluessel()).isEqualTo(ZustaendigeStelleDataTestFactory.GEMEINDE_SCHLUESSEL_BP);
+		}
+
+		@Test
+		void shouldSetEmail() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getEmail()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_EMAIL);
+		}
+
+		@Test
+		void shouldSetAmtlicherRegionalSchluessel() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getAmtlicherRegionalSchluessel()).isEqualTo(ZustaendigeStelleDataTestFactory.AMTLICHER_REGIONALSCHLUESSEL);
+		}
+
+		@Test
+		void shouldSetHausanschriftStrasse() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getHausanschriftStrasse()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_HAUSANSCHRIFT_STRASSE);
+		}
+
+		@Test
+		void shouldSetHausanschriftOrt() {
+			var zusatendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zusatendigeStelle.getHausanschriftOrt()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_HAUSANSCHRIFT_ORT);
+		}
+
+		@Test
+		void shouldSetHausanschriftPlz() {
+			var zustaendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zustaendigeStelle.getHausanschriftPlz()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_HAUSANSCHRIFT_PLZ);
+		}
+
+		@Test
+		void shouldSetTelefon() {
+			var zusatendigeStelle = mapZustaendigeStelle();
+
+			assertThat(zusatendigeStelle.getTelefon()).isEqualTo(ZustaendigeStelleDataTestFactory.BEHOERDE_TELEFON);
+		}
+
+		private ZustaendigeStelle mapZustaendigeStelle() {
+			return mapper.mapZustaendigeStelle(ZustaendigeStelleDataTestFactory.BEHOERDE_METADATA);
+		}
+	}
+
+	@Test
+	void shouldApproveResponsibility() {
+		var formData = FormDataTestFactory.createBuilder()
+				.representation(IncomingFileTestFactory.createBuilder().name(ZustaendigeStelleMetadataMapper.BEHOERDE_METADATA_FILE_NAME)
+						.build()).build();
+
+		var isResponsible = mapper.isResponsible(formData);
+
+		assertThat(isResponsible).isTrue();
+	}
+}
\ No newline at end of file
diff --git a/semantik-adapter/src/test/resources/behoerde_metadata.xml b/semantik-adapter/src/test/resources/behoerde_metadata.xml
new file mode 100644
index 0000000000000000000000000000000000000000..66b1f000dd1af9e077657cab9f67bf0d3710b32f
--- /dev/null
+++ b/semantik-adapter/src/test/resources/behoerde_metadata.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="http://xmlns.cit.de/assistants/store" name="myForm" class="de.cit.assistants.DataBean">
+    <field type="string" readonly="true" name="behoerde_anzeige_name">Landratsamt XYZ (Testbehörde für BDA)</field>
+    <field type="string" readonly="true" name="behoerde_caller_id">87331322433</field>
+    <field type="string" readonly="true" name="behoerde_pki_email"></field>
+    <field type="string" readonly="true" name="behoerde_link">
+        https://redesign.bayernportal.bayern.de/dokumente/behoerde/87331322433</field>
+    <field type="string" readonly="true" name="behoerde_sicherer_kontakt_link"></field>
+    <field type="string" readonly="true" name="behoerde_postkorb_eakte"></field>
+    <field type="string" readonly="true" name="behoerde_organisationseinheit_eakte"></field>
+    <field type="string" readonly="true" name="gemeinde_schluessel_bp">09189155</field>
+    <field type="string" readonly="true" name="amtlicher_regionalschluessel">091890000000</field>
+    <field type="string" readonly="true" name="behoerde_email">poststelle@testbehoerde.bayern</field>
+    <field type="string" readonly="true" name="behoerde_telefon">+49 123 45-0</field>
+    <field type="string" readonly="true" name="behoerde_telefax">+49 12 45-7</field>
+    <field type="string" readonly="true" name="behoerde_hausanschrift_strasse">Teststraße 1</field>
+    <field type="string" readonly="true" name="behoerde_hausanschrift_plz">12345</field>
+    <field type="string" readonly="true" name="behoerde_hausanschrift_ort">Musterstadt</field>
+    <field type="string" readonly="true" name="behoerde_safeId"></field>
+    <field type="string" readonly="true" name="dvdv_praefix">bab</field>
+    <field type="string" readonly="true" name="dvdv_kennung">09189</field>
+</data>
\ No newline at end of file