diff --git a/.gitignore b/.gitignore
index 6a8fd526ec8c6c600fd616bca2a7893d2dee5d3e..a8d2e8e3d8b61967e872f5daed2c0fb7e5483d29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@ target/
 .attach**
 .factorypath
 .vscode*
+.nx
\ No newline at end of file
diff --git a/alfa-client/.nvmrc b/alfa-client/.nvmrc
index 87ec8842b158d213e0477ba0129281a484b9d47d..48b14e6b2b56f3819ca134cef59bc09580f44fd6 100644
--- a/alfa-client/.nvmrc
+++ b/alfa-client/.nvmrc
@@ -1 +1 @@
-18.18.2
+20.14.0
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java
index 67cb7eb4c7f5432aa2433a65b784c788f4b9869c..76d8324789bfcec50208634004b8082eef732414 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java
@@ -1,7 +1,10 @@
 package de.ozgcloud.alfa.bescheid;
 
+import static de.ozgcloud.alfa.common.ValidationMessageCodes.*;
+
 import java.util.List;
 
+import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -53,7 +56,9 @@ public class Bescheid implements CommandBody {
 
 	@LinkedResource(controllerClass = BinaryFileController.class)
 	private List<FileId> attachments;
+	@NotEmpty(message = FIELD_IS_EMPTY, groups = BescheidNachrichtValidation.class)
 	private String nachrichtText;
+	@NotEmpty(message = FIELD_IS_EMPTY, groups = BescheidNachrichtValidation.class)
 	private String nachrichtSubject;
 	private SendBy sendBy;
 	private BescheidStatus status;
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java
index f8d3c4a12eb145cdc898cf59d783f01e8c0d935c..cef975602a1435f59cb4ecbf54f36a44bda7953e 100644
--- a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java
@@ -61,6 +61,9 @@ public class BescheidModelAssembler implements RepresentationModelAssembler<Besc
 		var attachmentsLink = linkTo(methodOn(BescheidController.class).getAttachments(bescheid.getId(), bescheid.getVorgangId()));
 		var createCommandLink = buildCreateCommandLink(bescheid);
 		var vorgangWithEingang = vorgangController.getVorgang(bescheid.getVorgangId());
+		var bescheidenUndSendenLink = linkTo(
+				methodOn(BescheidSendenCommandController.class).createCommand(vorgangWithEingang.getId(), bescheid.getId(), bescheid.getVersion(),
+						null));
 
 		return ModelBuilder.fromEntity(bescheid)
 				.addLink(selfLink.withSelfRel())
@@ -75,7 +78,7 @@ public class BescheidModelAssembler implements RepresentationModelAssembler<Besc
 				.addLink(createCommandLink.withRel(REL_CREATE_DOCUMENT))
 				.addLink(createCommandLink.withRel(REL_CREATE_DOCUMENT_FROM_FILE))
 				.ifMatch(() -> canSendMessageToAntragsteller(vorgangWithEingang))
-				.addLink(createCommandLink.withRel(REL_BESCHEIDEN_UND_SENDEN))
+				.addLink(bescheidenUndSendenLink.withRel(REL_BESCHEIDEN_UND_SENDEN))
 				.addLink(createCommandLink.withRel(REL_BESCHEIDEN))
 				.buildModel();
 	}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidNachrichtValidation.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidNachrichtValidation.java
new file mode 100644
index 0000000000000000000000000000000000000000..13e50b003feb81845b571a78148235252d852457
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidNachrichtValidation.java
@@ -0,0 +1,4 @@
+package de.ozgcloud.alfa.bescheid;
+
+interface BescheidNachrichtValidation {
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandController.java
new file mode 100644
index 0000000000000000000000000000000000000000..443ade445b6ec5e3cb8867db1144cc245aaeadfd
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandController.java
@@ -0,0 +1,47 @@
+package de.ozgcloud.alfa.bescheid;
+
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
+
+import org.springframework.hateoas.EntityModel;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.ozgcloud.alfa.common.command.Command;
+import de.ozgcloud.alfa.common.command.CommandController;
+import de.ozgcloud.alfa.common.command.CommandService;
+import de.ozgcloud.alfa.common.command.CreateCommand;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import lombok.RequiredArgsConstructor;
+
+@RestController
+@RequestMapping(BescheidSendenCommandController.PATH)
+@RequiredArgsConstructor
+class BescheidSendenCommandController {
+
+	static final String PATH = "/api/vorgangs/{vorgangId}/bescheids/relations/{relationId}/{relationVersion}/commands"; // NOSONAR
+
+	private final BescheidService bescheidService;
+	private final CommandService commandService;
+	private final BescheidSendenCommandValidator bescheidSendenCommandValidator;
+
+	@PostMapping
+	public ResponseEntity<EntityModel<Command>> createCommand(@PathVariable String vorgangId, @PathVariable String relationId,
+			@PathVariable long relationVersion, @RequestBody CreateCommand command) {
+		command = command.toBuilder().vorgangId(vorgangId).relationId(relationId).build();
+
+		validate(vorgangId, command);
+
+		var created = commandService.createCommand(command, relationVersion);
+		return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build();
+	}
+
+	void validate(String vorgangId, CreateCommand command) {
+		var bescheid = bescheidService.getBescheidDraft(vorgangId)
+				.orElseThrow(() -> new TechnicalException("Bescheid not found for vorgang id: " + vorgangId));
+		bescheidSendenCommandValidator.validate(command.toBuilder().body(bescheid).build());
+	}
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandValidator.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..f304a0428a6a923900e5ba657d16cc8faea20d6f
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandValidator.java
@@ -0,0 +1,17 @@
+package de.ozgcloud.alfa.bescheid;
+
+import jakarta.validation.Valid;
+
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+
+import de.ozgcloud.alfa.common.command.CreateCommand;
+
+@Validated(BescheidNachrichtValidation.class)
+@Component
+class BescheidSendenCommandValidator {
+
+	public void validate(@Valid CreateCommand command) {
+		// noop
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java
index 4372f02417565a329e9fe8b3b25bc5b7556e2611..c78910e7421f2d5bceca56088ff5214efc90f064 100644
--- a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java
@@ -177,7 +177,7 @@ class BescheidModelAssemblerTest {
 
 			assertThat(model.getLink(REL_BESCHEIDEN_UND_SENDEN))
 					.isPresent().get()
-					.extracting(Link::getHref).isEqualTo(createCommandLink());
+					.extracting(Link::getHref).isEqualTo(bescheidenUndSendenLink());
 		}
 
 		@Test
@@ -225,6 +225,11 @@ class BescheidModelAssemblerTest {
 					.expand(VorgangHeaderTestFactory.ID, BescheidTestFactory.ID, BescheidTestFactory.VERSION).toString();
 		}
 
+		private String bescheidenUndSendenLink() {
+			return new UriTemplate(BescheidSendenCommandController.PATH)
+					.expand(VorgangHeaderTestFactory.ID, BescheidTestFactory.ID, BescheidTestFactory.VERSION).toString();
+		}
+
 		private EntityModel<Bescheid> callToModel() {
 			return callToModel(bescheid);
 		}
@@ -240,6 +245,8 @@ class BescheidModelAssemblerTest {
 
 		@Test
 		void shouldCallToModel() {
+			when(vorgangController.getVorgang(VorgangHeaderTestFactory.ID)).thenReturn(VorgangWithEingangTestFactory.create());
+
 			callMethod();
 
 			verify(assembler).toCollectionModel(List.of(bescheid));
@@ -257,6 +264,8 @@ class BescheidModelAssemblerTest {
 
 		@Test
 		void shouldHaveSelfLink() {
+			when(vorgangController.getVorgang(VorgangHeaderTestFactory.ID)).thenReturn(VorgangWithEingangTestFactory.create());
+
 			var collectionModel = callMethod();
 
 			assertThat(collectionModel.getLinks())
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6ee7a8966c541ecece42781f2f9a2b58aa371fd
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidSendenCommandControllerTest.java
@@ -0,0 +1,180 @@
+package de.ozgcloud.alfa.bescheid;
+
+import static de.ozgcloud.alfa.common.command.CommandController.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import java.util.Optional;
+
+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.Mock;
+import org.mockito.Spy;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import de.ozgcloud.alfa.common.command.Command;
+import de.ozgcloud.alfa.common.command.CommandOrder;
+import de.ozgcloud.alfa.common.command.CommandService;
+import de.ozgcloud.alfa.common.command.CommandTestFactory;
+import de.ozgcloud.alfa.common.command.CreateCommand;
+import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.common.test.TestUtils;
+
+class BescheidSendenCommandControllerTest {
+
+	@Spy
+	@InjectMocks
+	private BescheidSendenCommandController controller;
+
+	@Mock
+	private BescheidService bescheidService;
+	@Mock
+	private CommandService commandService;
+
+	@Mock
+	private BescheidSendenCommandValidator bescheidSendenCommandValidator;
+
+	private MockMvc mockMvc;
+
+	@BeforeEach
+	void setUp() {
+		mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
+	}
+
+	@Nested
+	class TestCreateCommand {
+
+		private final Command command = CommandTestFactory.create();
+
+		@Captor
+		private ArgumentCaptor<CreateCommand> createCommandArgumentCaptor;
+
+		@BeforeEach
+		void setUp() {
+			doNothing().when(controller).validate(eq(VorgangHeaderTestFactory.ID), any(CreateCommand.class));
+			when(commandService.createCommand(any(CreateCommand.class), eq(BescheidTestFactory.VERSION))).thenReturn(command);
+		}
+
+		@Test
+		void shouldValidate() throws Exception {
+			doRequest();
+
+			verify(controller).validate(eq(VorgangHeaderTestFactory.ID), any(CreateCommand.class));
+		}
+
+		@Test
+		void shouldSetVorgangIdOnCreateCommand() throws Exception {
+			doRequest();
+
+			verify(controller).validate(eq(VorgangHeaderTestFactory.ID), createCommandArgumentCaptor.capture());
+			assertThat(createCommandArgumentCaptor.getValue().getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID);
+		}
+
+		@Test
+		void shouldSetRelationIdOnCreateCommand() throws Exception {
+			doRequest();
+
+			verify(controller).validate(eq(VorgangHeaderTestFactory.ID), createCommandArgumentCaptor.capture());
+			assertThat(createCommandArgumentCaptor.getValue().getRelationId()).isEqualTo(BescheidTestFactory.ID);
+		}
+
+		@Test
+		void shouldCallCommandService() throws Exception {
+			doRequest();
+
+			verify(commandService).createCommand(any(CreateCommand.class), eq(BescheidTestFactory.VERSION));
+		}
+
+		@Test
+		void shouldReturnCreated() throws Exception {
+			doRequest().andExpect(status().isCreated());
+		}
+
+		@Test
+		void shouldReturnCommand() throws Exception {
+			doRequest()
+					.andExpect(header().stringValues("location", "http://localhost" + COMMANDS_PATH + "/" + CommandTestFactory.ID));
+		}
+
+		private ResultActions doRequest() throws Exception {
+			return mockMvc.perform(
+					post(BescheidSendenCommandController.PATH,
+							VorgangHeaderTestFactory.ID,
+							BescheidTestFactory.ID,
+							BescheidTestFactory.VERSION)
+							.content(createContent())
+							.contentType(MediaType.APPLICATION_JSON));
+		}
+
+		private String createContent() {
+			return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithBody.json.tmpl",
+					CommandOrder.SEND_BESCHEID.name(),
+					null);
+		}
+
+	}
+
+	@Nested
+	class TestValidate {
+
+		private final CreateCommand createCommand = CommandTestFactory.createCreateCommand();
+		private final Bescheid bescheid = BescheidTestFactory.create();
+
+		@Captor
+		private ArgumentCaptor<CreateCommand> commandArgumentCaptor;
+
+		@Nested
+		class WhenBescheidExists {
+
+			@BeforeEach
+			void setUp() {
+				when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.of(bescheid));
+				doNothing().when(bescheidSendenCommandValidator).validate(any(CreateCommand.class));
+			}
+
+			@Test
+			void shouldGetBescheidDraft() {
+				controller.validate(VorgangHeaderTestFactory.ID, createCommand);
+
+				verify(bescheidService).getBescheidDraft(VorgangHeaderTestFactory.ID);
+			}
+
+			@Test
+			void shouldValidate() {
+				controller.validate(VorgangHeaderTestFactory.ID, createCommand);
+
+				verify(bescheidSendenCommandValidator).validate(any(CreateCommand.class));
+			}
+
+			@Test
+			void shouldAddBescheidToCommand() {
+				controller.validate(VorgangHeaderTestFactory.ID, createCommand);
+
+				verify(bescheidSendenCommandValidator).validate(commandArgumentCaptor.capture());
+				assertThat(commandArgumentCaptor.getValue()).usingRecursiveComparison().isEqualTo(createCommand.toBuilder().body(bescheid).build());
+			}
+		}
+
+		@Nested
+		class WhenBescheidNotExists {
+
+			@Test
+			void shouldThrowTechnicalException() {
+				when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.empty());
+
+				assertThatThrownBy(() -> controller.validate(VorgangHeaderTestFactory.ID, createCommand)).isInstanceOf(TechnicalException.class);
+			}
+		}
+	}
+
+}
\ No newline at end of file