diff --git a/example/announce.c b/example/announce.c
index 9220242..737eff5 100644
--- a/example/announce.c
+++ b/example/announce.c
@@ -23,8 +23,10 @@ int main(void) {
     sp_char_grid_set(grid, 3, 1, 'l');
     sp_char_grid_set(grid, 4, 1, 'd');
 
-    TypedCommand *command = sp_command_char_grid(0, 0, grid);
-    sp_udp_send_command(connection, command);
+    Packet *packet = sp_char_grid_into_packet(grid, 0, 0);
+    if (packet == NULL)
+        return 1;
+    sp_udp_send_packet(connection, packet);
 
     sp_udp_free(connection);
     return 0;
diff --git a/example/brightness_tester.c b/example/brightness_tester.c
index 93e64ce..d06d30d 100644
--- a/example/brightness_tester.c
+++ b/example/brightness_tester.c
@@ -8,11 +8,12 @@ int main(void) {
 
     Bitmap *all_on = sp_bitmap_new_max_sized();
     sp_bitmap_fill(all_on, true);
-    TypedCommand *cmd = sp_command_bitmap(0, 0, all_on, COMPRESSION_CODE_UNCOMPRESSED);
-    if (cmd == NULL)
+
+    Packet *packet = sp_bitmap_into_packet(all_on, 0, 0, COMPRESSION_CODE_UNCOMPRESSED);
+    if (packet == NULL)
         return -1;
 
-    sp_udp_send_command(connection, cmd);
+    sp_udp_send_packet(connection, packet);
 
     BrightnessGrid *grid = sp_brightness_grid_new(TILE_WIDTH, TILE_HEIGHT);
 
@@ -21,8 +22,8 @@ int main(void) {
         slice.start[index] = (uint8_t) (index % ((size_t) Brightness_MAX));
     }
 
-    TypedCommand *command = sp_command_brightness_grid(0, 0, grid);
-    sp_udp_send_command(connection, command);
+    packet = sp_brightness_grid_into_packet(grid, 0, 0);
+    sp_udp_send_packet(connection, packet);
 
     sp_udp_free(connection);
     return 0;
diff --git a/example/random_stuff.c b/example/random_stuff.c
index 80c3847..ca5a14d 100644
--- a/example/random_stuff.c
+++ b/example/random_stuff.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include "servicepoint.h"
 
 int main(void) {
@@ -11,14 +12,12 @@ int main(void) {
 
     sp_bitmap_fill(pixels, true);
 
-    TypedCommand *command = sp_command_bitmap(0, 0, pixels, COMPRESSION_CODE_UNCOMPRESSED);
-    if (command == NULL)
+    Packet *packet = sp_bitmap_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED);
+    if (packet == NULL)
         return 1;
 
-    Packet *packet = sp_packet_from_command(command);
-
     Header *header = sp_packet_get_header(packet);
-    //printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
+    printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
 
     sp_udp_send_packet(connection, packet);
 
diff --git a/include/servicepoint.h b/include/servicepoint.h
index 1ece5e6..77d2e36 100644
--- a/include/servicepoint.h
+++ b/include/servicepoint.h
@@ -455,6 +455,18 @@ size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap);
  */
 SPBitVec */*notnull*/ sp_bitmap_into_bitvec(Bitmap */*notnull*/ bitmap);
 
+/**
+ * Creates a [BitmapCommand] and immediately turns that into a [Packet].
+ *
+ * The provided [Bitmap] gets consumed.
+ *
+ * Returns NULL in case of an error.
+ */
+Packet *sp_bitmap_into_packet(Bitmap */*notnull*/ bitmap,
+                              size_t x,
+                              size_t y,
+                              CompressionCode compression);
+
 /**
  * Loads a [Bitmap] with the specified dimensions from the provided data.
  *
@@ -580,6 +592,18 @@ void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec);
  */
 bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index);
 
+/**
+ * Creates a [BitVecCommand] and immediately turns that into a [Packet].
+ *
+ * The provided [SPBitVec] gets consumed.
+ *
+ * Returns NULL in case of an error.
+ */
+Packet *sp_bitvec_into_packet(SPBitVec */*notnull*/ bitvec,
+                              size_t offset,
+                              BinaryOperation operation,
+                              CompressionCode compression);
+
 /**
  * Returns true if length is 0.
  *
@@ -695,6 +719,13 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid,
  */
 size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid);
 
+/**
+ * Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
+ *
+ * The provided [BrightnessGrid] gets consumed.
+ *
+ * Returns NULL in case of an error.
+ */
 Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid,
                                        size_t x,
                                        size_t y);
@@ -818,6 +849,17 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y);
  */
 size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid);
 
+/**
+ * Creates a [CharGridCommand] and immediately turns that into a [Packet].
+ *
+ * The provided [CharGrid] gets consumed.
+ *
+ * Returns NULL in case of an error.
+ */
+Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid,
+                                 size_t x,
+                                 size_t y);
+
 /**
  * Loads a [CharGrid] with the specified dimensions from the provided data.
  *
@@ -1045,6 +1087,17 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid,
  */
 size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid);
 
+/**
+ * Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
+ *
+ * The provided [Cp437Grid] gets consumed.
+ *
+ * Returns NULL in case of an error.
+ */
+Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid,
+                                  size_t x,
+                                  size_t y);
+
 /**
  * Loads a [Cp437Grid] with the specified dimensions from the provided data.
  */
@@ -1156,7 +1209,13 @@ void sp_packet_set_payload(Packet */*notnull*/ packet, ByteSlice data);
  */
 Packet *sp_packet_try_load(ByteSlice data);
 
-bool sp_u16_to_command_code(uint16_t code, CommandCode *result);
+/**
+ * Converts u16 into [CommandCode].
+ *
+ * If the provided value is not valid, false is returned and result is not changed.
+ */
+bool sp_u16_to_command_code(uint16_t code,
+                            CommandCode *result);
 
 /**
  * Closes and deallocates a [UdpConnection].
diff --git a/src/bitmap.rs b/src/bitmap.rs
index 71753a5..358be48 100644
--- a/src/bitmap.rs
+++ b/src/bitmap.rs
@@ -1,6 +1,6 @@
 use crate::byte_slice::ByteSlice;
 use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, SPBitVec};
-use servicepoint::{Bitmap, DataRef, Grid};
+use servicepoint::{Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet};
 use std::ptr::NonNull;
 
 /// Creates a new [Bitmap] with the specified dimensions.
@@ -199,3 +199,26 @@ pub unsafe extern "C" fn sp_bitmap_into_bitvec(
     let bitmap = unsafe { heap_remove(bitmap) };
     heap_move_nonnull(SPBitVec(bitmap.into()))
 }
+
+/// Creates a [BitmapCommand] and immediately turns that into a [Packet].
+///
+/// The provided [Bitmap] gets consumed.
+///
+/// Returns NULL in case of an error.
+#[no_mangle]
+pub unsafe extern "C" fn sp_bitmap_into_packet(
+    bitmap: NonNull<Bitmap>,
+    x: usize,
+    y: usize,
+    compression: CompressionCode
+) -> *mut Packet {
+    let bitmap = unsafe { heap_remove(bitmap) };
+    match Packet::try_from(BitmapCommand {
+        bitmap,
+        origin: Origin::new(x, y),
+        compression,
+    }) {
+        Ok(packet) => heap_move(packet),
+        Err(_) => std::ptr::null_mut(),
+    }
+}
diff --git a/src/bitvec.rs b/src/bitvec.rs
index e5ce720..22f7545 100644
--- a/src/bitvec.rs
+++ b/src/bitvec.rs
@@ -1,5 +1,5 @@
-use crate::{heap_drop, heap_move_nonnull, ByteSlice};
-use servicepoint::BitVecU8Msb0;
+use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
+use servicepoint::{BinaryOperation, BitVecCommand, BitVecU8Msb0, CompressionCode, Packet};
 use std::ptr::NonNull;
 
 /// A vector of bits
@@ -146,3 +146,27 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref(
 ) -> ByteSlice {
     unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) }
 }
+
+/// Creates a [BitVecCommand] and immediately turns that into a [Packet].
+///
+/// The provided [SPBitVec] gets consumed.
+///
+/// Returns NULL in case of an error.
+#[no_mangle]
+pub unsafe extern "C" fn sp_bitvec_into_packet(
+    bitvec: NonNull<SPBitVec>,
+    offset: usize,
+    operation: BinaryOperation,
+    compression: CompressionCode
+) -> *mut Packet {
+    let bitvec = unsafe { heap_remove(bitvec) }.0;
+    match Packet::try_from(BitVecCommand {
+        bitvec,
+        offset,
+        operation,
+        compression,
+    }) {
+        Ok(packet) => heap_move(packet),
+        Err(_) => std::ptr::null_mut(),
+    }
+}
diff --git a/src/brightness_grid.rs b/src/brightness_grid.rs
index f85602a..1099be0 100644
--- a/src/brightness_grid.rs
+++ b/src/brightness_grid.rs
@@ -175,6 +175,11 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
     }
 }
 
+/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
+///
+/// The provided [BrightnessGrid] gets consumed.
+///
+/// Returns NULL in case of an error.
 #[no_mangle]
 pub unsafe extern "C" fn sp_brightness_grid_into_packet(
     grid: NonNull<BrightnessGrid>,
diff --git a/src/char_grid.rs b/src/char_grid.rs
index cdcc4b5..bfb2585 100644
--- a/src/char_grid.rs
+++ b/src/char_grid.rs
@@ -1,5 +1,5 @@
-use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice};
-use servicepoint::{CharGrid, Grid};
+use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
+use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet};
 use std::ptr::NonNull;
 
 /// Creates a new [CharGrid] with the specified dimensions.
@@ -132,3 +132,24 @@ pub unsafe extern "C" fn sp_char_grid_height(
 ) -> usize {
     unsafe { char_grid.as_ref().height() }
 }
+
+/// Creates a [CharGridCommand] and immediately turns that into a [Packet].
+///
+/// The provided [CharGrid] gets consumed.
+///
+/// Returns NULL in case of an error.
+#[no_mangle]
+pub unsafe extern "C" fn sp_char_grid_into_packet(
+    grid: NonNull<CharGrid>,
+    x: usize,
+    y: usize,
+) -> *mut Packet {
+    let grid = unsafe { heap_remove(grid) };
+    match Packet::try_from(CharGridCommand {
+        grid,
+        origin: Origin::new(x, y),
+    }) {
+        Ok(packet) => heap_move(packet),
+        Err(_) => std::ptr::null_mut(),
+    }
+}
diff --git a/src/cp437_grid.rs b/src/cp437_grid.rs
index e22a0ed..01aeb1e 100644
--- a/src/cp437_grid.rs
+++ b/src/cp437_grid.rs
@@ -1,5 +1,5 @@
-use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice};
-use servicepoint::{Cp437Grid, DataRef, Grid};
+use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
+use servicepoint::{Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet};
 use std::ptr::NonNull;
 
 /// Creates a new [Cp437Grid] with the specified dimensions.
@@ -132,3 +132,24 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref(
 ) -> ByteSlice {
     unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) }
 }
+
+/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
+///
+/// The provided [Cp437Grid] gets consumed.
+///
+/// Returns NULL in case of an error.
+#[no_mangle]
+pub unsafe extern "C" fn sp_cp437_grid_into_packet(
+    grid: NonNull<Cp437Grid>,
+    x: usize,
+    y: usize,
+) -> *mut Packet {
+    let grid = unsafe { heap_remove(grid) };
+    match Packet::try_from(Cp437GridCommand {
+        grid,
+        origin: Origin::new(x, y),
+    }) {
+        Ok(packet) => heap_move(packet),
+        Err(_) => std::ptr::null_mut(),
+    }
+}
diff --git a/src/packet.rs b/src/packet.rs
index a891ee3..d8b1579 100644
--- a/src/packet.rs
+++ b/src/packet.rs
@@ -108,6 +108,9 @@ pub unsafe extern "C" fn sp_packet_free(packet: NonNull<Packet>) {
     unsafe { heap_drop(packet) }
 }
 
+/// Converts u16 into [CommandCode].
+///
+/// If the provided value is not valid, false is returned and result is not changed.
 #[no_mangle]
 pub unsafe extern "C" fn sp_u16_to_command_code(
     code: u16,