diff --git a/Documentation/epicardium/sensor-streams.rst b/Documentation/epicardium/sensor-streams.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a111402d74a13430bc21aeb16ab768ad2602d750
--- /dev/null
+++ b/Documentation/epicardium/sensor-streams.rst
@@ -0,0 +1,29 @@
+Sensor Streams
+==============
+Sensor drivers can make their data available to core 1 in a stream-like format.
+This allows batch-reading many samples and shoud reduce pressure on the
+Epicardium API this way.  Sensor streams are read on core 1 using
+:c:func:`epic_stream_read`.
+
+This page intends to document how to add this stream interface to a sensor driver.
+It also serves as a reference of existing streams.  For that, take a look at the
+definitions in the :c:type:`stream_descriptor` enum.
+
+Adding a new Stream
+-------------------
+The list of possible sensor streams must be known at compile time.  Each stream
+gets a unique ID in the :c:type:`stream_descriptor` enum.  Please do not assign
+IDs manually but instead let the enum assign sequencial IDs.  :c:macro:`SD_MAX`
+must always be the highest stream ID.  Additionally, please document what this
+stream is for using a doc-comment so it shows up on this page.
+
+When a sensor driver enables data collection, it should also register its
+respective stream.  This is done using a :c:type:`stream_info` object.  Pass
+this object to :c:func:`stream_register` to make your stream available.  Your
+driver must guarantee the :c:member:`stream_info.queue` handle to be valid until
+deregistration using :c:func:`stream_deregister`.
+
+Definitions
+-----------
+
+.. c:autodoc:: epicardium/modules/stream.h
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 1cbba07da9e948adfe3a5bb67fce17b0698f26ce..d9a7339a5fcb8f241fad2a66395d91ed318123f9 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -35,6 +35,7 @@ Last but not least, if you want to start hacking the lower-level firmware, the
    debugger
    pycardium-guide
    memorymap
+   epicardium/sensor-streams
 
 .. toctree::
    :maxdepth: 1
@@ -43,5 +44,3 @@ Last but not least, if you want to start hacking the lower-level firmware, the
    epicardium/overview
    epicardium/api
    epicardium-guide
-
-
diff --git a/epicardium/modules/stream.h b/epicardium/modules/stream.h
index d5dd30794d2367320c2f9ef8e2112769b0add203..5cf0dcc068ceac251c1609ba768c8fbbabe76bcf 100644
--- a/epicardium/modules/stream.h
+++ b/epicardium/modules/stream.h
@@ -10,18 +10,37 @@
 /**
  * **Stream Descriptors**:
  *
- *    All supported streams have to have a unique ID in this list.  ``SD_MAX``
- *    must be greater than or equal to the highest defined ID.  Please keep IDs
- *    in sequential order.
+ *    All supported streams have to have a unique ID in this list.  :c:macro:`SD_MAX`
+ *    must be greater than or equal to the highest defined ID.  Please keep IDs in
+ *    sequential order.
  */
 enum stream_descriptor {
 	/** Highest descriptor must always be ``SD_MAX``. */
 	SD_MAX,
 };
 
+/**
+ * Stream Information Object.
+ *
+ * This struct contains the information necessary for :c:func:`epic_stream_read`
+ * to read from a sensor's stream.  This consists of:
+ */
 struct stream_info {
+	/**
+	 * A FreeRTOS queue handle.
+	 *
+	 * Management of this queue is the sensor drivers responsibility.
+	 */
 	QueueHandle_t queue;
+	/** The size of one data packet (= queue element). */
 	size_t item_size;
+	/**
+	 * An optional function to call before performing the read.
+	 *
+	 * ``poll_stream()`` is intended for sensors who passively collect data.
+	 * A sensor driver might for example retrieve the latest samples in this
+	 * function instead of actively polling in a task loop.
+	 */
 	int (*poll_stream)();
 };