diff --git a/cbindgen.toml b/cbindgen.toml
index 29c19a8..48ef574 100644
--- a/cbindgen.toml
+++ b/cbindgen.toml
@@ -39,3 +39,6 @@ exclude = []
 
 [enum]
 rename_variants = "QualifiedScreamingSnakeCase"
+
+[ptr]
+non_null_attribute = "/*notnull*/"
diff --git a/include/servicepoint.h b/include/servicepoint.h
index 63c1179..4e7843f 100644
--- a/include/servicepoint.h
+++ b/include/servicepoint.h
@@ -239,7 +239,7 @@ typedef struct {
     /**
      * The start address of the memory
      */
-    uint8_t *start;
+    uint8_t */*notnull*/ start;
     /**
      * The amount of memory in bytes
      */
@@ -351,7 +351,7 @@ extern "C" {
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_bitmap_free`.
  */
-Bitmap *sp_bitmap_clone(const Bitmap *bitmap);
+Bitmap */*notnull*/ sp_bitmap_clone(const Bitmap *bitmap);
 
 /**
  * Sets the state of all pixels in the [SPBitmap].
@@ -506,7 +506,7 @@ Bitmap *sp_bitmap_new(size_t width,
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling [sp_bitmap_free].
  */
-Bitmap *sp_bitmap_new_screen_sized(void);
+Bitmap */*notnull*/ sp_bitmap_new_screen_sized(void);
 
 /**
  * Sets the value of the specified position in the [SPBitmap].
@@ -587,7 +587,7 @@ size_t sp_bitmap_width(const Bitmap *bitmap);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_bitvec_free`.
  */
-SPBitVec *sp_bitvec_clone(const SPBitVec *bit_vec);
+SPBitVec */*notnull*/ sp_bitvec_clone(const SPBitVec *bit_vec);
 
 /**
  * Sets the value of all bits in the [SPBitVec].
@@ -709,8 +709,8 @@ size_t sp_bitvec_len(const SPBitVec *bit_vec);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_bitvec_free`.
  */
-SPBitVec *sp_bitvec_load(const uint8_t *data,
-                         size_t data_length);
+SPBitVec */*notnull*/ sp_bitvec_load(const uint8_t *data,
+                                     size_t data_length);
 
 /**
  * Creates a new [SPBitVec] instance.
@@ -732,7 +732,7 @@ SPBitVec *sp_bitvec_load(const uint8_t *data,
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_bitvec_free`.
  */
-SPBitVec *sp_bitvec_new(size_t size);
+SPBitVec */*notnull*/ sp_bitvec_new(size_t size);
 
 /**
  * Sets the value of a bit in the [SPBitVec].
@@ -800,7 +800,7 @@ SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec *bit_vec);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_brightness_grid_free`.
  */
-BrightnessGrid *sp_brightness_grid_clone(const BrightnessGrid *brightness_grid);
+BrightnessGrid */*notnull*/ sp_brightness_grid_clone(const BrightnessGrid *brightness_grid);
 
 /**
  * Sets the value of all cells in the [SPBrightnessGrid].
@@ -930,8 +930,8 @@ BrightnessGrid *sp_brightness_grid_load(size_t width,
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_brightness_grid_free`.
  */
-BrightnessGrid *sp_brightness_grid_new(size_t width,
-                                       size_t height);
+BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width,
+                                                   size_t height);
 
 /**
  * Sets the value of the specified position in the [SPBrightnessGrid].
@@ -1024,7 +1024,7 @@ size_t sp_brightness_grid_width(const BrightnessGrid *brightness_grid);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_char_grid_free`.
  */
-CharGrid *sp_char_grid_clone(const CharGrid *char_grid);
+CharGrid */*notnull*/ sp_char_grid_clone(const CharGrid *char_grid);
 
 /**
  * Sets the value of all cells in the [SPCharGrid].
@@ -1127,10 +1127,10 @@ size_t sp_char_grid_height(const CharGrid *char_grid);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_char_grid_free`.
  */
-CharGrid *sp_char_grid_load(size_t width,
-                            size_t height,
-                            const uint8_t *data,
-                            size_t data_length);
+CharGrid */*notnull*/ sp_char_grid_load(size_t width,
+                                        size_t height,
+                                        const uint8_t *data,
+                                        size_t data_length);
 
 /**
  * Creates a new [SPCharGrid] with the specified dimensions.
@@ -1144,8 +1144,8 @@ CharGrid *sp_char_grid_load(size_t width,
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_char_grid_free`.
  */
-CharGrid *sp_char_grid_new(size_t width,
-                           size_t height);
+CharGrid */*notnull*/ sp_char_grid_new(size_t width,
+                                       size_t height);
 
 /**
  * Sets the value of the specified position in the [SPCharGrid].
@@ -1360,7 +1360,7 @@ Command *sp_command_bitmap_linear_xor(size_t offset,
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_brightness(uint8_t brightness);
+Command */*notnull*/ sp_command_brightness(uint8_t brightness);
 
 /**
  * Set the brightness of individual tiles in a rectangular area of the display.
@@ -1382,9 +1382,9 @@ Command *sp_command_brightness(uint8_t brightness);
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_char_brightness(size_t x,
-                                    size_t y,
-                                    BrightnessGrid *grid);
+Command */*notnull*/ sp_command_char_brightness(size_t x,
+                                                size_t y,
+                                                BrightnessGrid *grid);
 
 /**
  * Set all pixels to the off state.
@@ -1406,7 +1406,7 @@ Command *sp_command_char_brightness(size_t x,
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_clear(void);
+Command */*notnull*/ sp_command_clear(void);
 
 /**
  * Clones a [SPCommand] instance.
@@ -1426,7 +1426,7 @@ Command *sp_command_clear(void);
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_clone(const Command *command);
+Command */*notnull*/ sp_command_clone(const Command *command);
 
 /**
  * Show codepage 437 encoded text on the screen.
@@ -1448,9 +1448,9 @@ Command *sp_command_clone(const Command *command);
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_cp437_data(size_t x,
-                               size_t y,
-                               Cp437Grid *grid);
+Command */*notnull*/ sp_command_cp437_data(size_t x,
+                                           size_t y,
+                                           Cp437Grid *grid);
 
 /**
  * A yet-to-be-tested command.
@@ -1464,7 +1464,7 @@ Command *sp_command_cp437_data(size_t x,
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_fade_out(void);
+Command */*notnull*/ sp_command_fade_out(void);
 
 /**
  * Deallocates a [SPCommand].
@@ -1504,7 +1504,7 @@ void sp_command_free(Command *command);
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_hard_reset(void);
+Command */*notnull*/ sp_command_hard_reset(void);
 
 /**
  * A low-level display command.
@@ -1563,9 +1563,9 @@ Command *sp_command_try_from_packet(Packet *packet);
  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_command_free`.
  */
-Command *sp_command_utf8_data(size_t x,
-                              size_t y,
-                              CharGrid *grid);
+Command */*notnull*/ sp_command_utf8_data(size_t x,
+                                          size_t y,
+                                          CharGrid *grid);
 
 /**
  * Closes and deallocates a [SPConnection].
@@ -1664,7 +1664,7 @@ bool sp_connection_send_packet(const UdpConnection *connection, Packet *packet);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_cp437_grid_free`.
  */
-Cp437Grid *sp_cp437_grid_clone(const Cp437Grid *cp437_grid);
+Cp437Grid */*notnull*/ sp_cp437_grid_clone(const Cp437Grid *cp437_grid);
 
 /**
  * Sets the value of all cells in the [SPCp437Grid].
@@ -1783,8 +1783,8 @@ Cp437Grid *sp_cp437_grid_load(size_t width,
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_cp437_grid_free`.
  */
-Cp437Grid *sp_cp437_grid_new(size_t width,
-                             size_t height);
+Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width,
+                                         size_t height);
 
 /**
  * Sets the value of the specified position in the [SPCp437Grid].
@@ -1872,7 +1872,7 @@ size_t sp_cp437_grid_width(const Cp437Grid *cp437_grid);
  * - the returned instance is freed in some way, either by using a consuming function or
  *   by explicitly calling `sp_packet_free`.
  */
-Packet *sp_packet_clone(const Packet *packet);
+Packet */*notnull*/ sp_packet_clone(const Packet *packet);
 
 /**
  * Deallocates a [SPPacket].
@@ -1937,9 +1937,9 @@ Packet *sp_packet_from_command(Command *command);
  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
  *   by explicitly calling [sp_packet_free].
  */
-Packet *sp_packet_from_parts(Header header,
-                             const uint8_t *payload,
-                             size_t payload_len);
+Packet */*notnull*/ sp_packet_from_parts(Header header,
+                                         const uint8_t *payload,
+                                         size_t payload_len);
 
 Header *sp_packet_get_header(Packet *packet);