diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h
index 7932c176..0dedcdca 100644
--- a/include/clap/ext/draft/undo.h
+++ b/include/clap/ext/draft/undo.h
@@ -1,8 +1,11 @@
 #pragma once
 
 #include "../../plugin.h"
+#include "../../stream.h"
 
-static CLAP_CONSTEXPR const char CLAP_EXT_UNDO[] = "clap.undo/3";
+static CLAP_CONSTEXPR const char CLAP_EXT_UNDO[] = "clap.undo/4";
+static CLAP_CONSTEXPR const char CLAP_EXT_UNDO_CONTEXT[] = "clap.undo_context/4";
+static CLAP_CONSTEXPR const char CLAP_EXT_UNDO_DELTA[] = "clap.undo_delta/4";
 
 #ifdef __cplusplus
 extern "C" {
@@ -15,7 +18,7 @@ extern "C" {
 ///
 /// Calling host->undo() or host->redo() is equivalent to clicking undo/redo within the host's GUI.
 ///
-/// If the plugin implements this interface then its undo and redo should be entirely delegated to
+/// If the plugin uses this interface then its undo and redo should be entirely delegated to
 /// the host; clicking in the plugin's UI undo or redo is equivalent to clicking undo or redo in the
 /// host's UI.
 ///
@@ -40,6 +43,12 @@ extern "C" {
 /// history. This simplifies the host implementation, leading to less bugs, a more robust design
 /// and maybe an easier experience for the user because there's a single undo context versus one
 /// for the host and one for each plugin instance.
+///
+/// This extension tries to make it as easy as possible for the plugin to hook into the host undo
+/// and make it efficient when possible by using deltas. The plugin interfaces are all optional, and
+/// the plugin can for a minimal implementation, just use the host interface and call
+/// host->change_made() without providing a delta. This is enough for the host to know that it can
+/// capture a plugin state for the undo step.
 
 typedef struct clap_undo_delta_properties {
    // If false, then all clap_undo_delta_properties's attributes become irrelevant.
@@ -54,7 +63,9 @@ typedef struct clap_undo_delta_properties {
    uint32_t format_version;
 } clap_undo_delta_properties_t;
 
-typedef struct clap_plugin_undo {
+// Use CLAP_EXT_UNDO_DELTA
+// This is an optional interface, using deltas is an optimization versus making state snapshot.
+typedef struct clap_plugin_undo_delta {
    // Asks the plugin the delta properties.
    // [main-thread]
    void(CLAP_ABI *get_delta_properties)(const clap_plugin_t          *plugin,
@@ -83,21 +94,26 @@ typedef struct clap_plugin_undo {
                         clap_id              format_version,
                         const void          *delta,
                         size_t               delta_size);
+} clap_plugin_undo_delta_t;
 
+// Use CLAP_EXT_UNDO_CONTEXT
+// This is an optional interface, that the plugin can implement in order to know about
+// the current undo context.
+typedef struct clap_plugin_undo_context {
    // Indicate if it is currently possible to perform a redo or undo operation.
    // if can_* is false then it invalidates the corresponding name.
    // [main-thread]
-   void (CLAP_ABI *set_can_undo)(const clap_plugin_t *plugin, bool can_undo);
-   void (CLAP_ABI *set_can_redo)(const clap_plugin_t *plugin, bool can_redo);
+   void(CLAP_ABI *set_can_undo)(const clap_plugin_t *plugin, bool can_undo);
+   void(CLAP_ABI *set_can_redo)(const clap_plugin_t *plugin, bool can_redo);
 
    // Sets the name of the next undo or redo step.
-   // name: null terminated string if an redo/undo step exists, null otherwise.
+   // name: null terminated string.
    // [main-thread]
-   void (CLAP_ABI *set_undo_name)(const clap_plugin_t *plugin, const char *name);
-   void (CLAP_ABI *set_redo_name)(const clap_plugin_t *plugin, const char *name);
-
-} clap_plugin_undo_t;
+   void(CLAP_ABI *set_undo_name)(const clap_plugin_t *plugin, const char *name);
+   void(CLAP_ABI *set_redo_name)(const clap_plugin_t *plugin, const char *name);
+} clap_plugin_undo_context_t;
 
+// Use CLAP_EXT_UNDO
 typedef struct clap_host_undo {
    // Begins a long running change.
    // The plugin must not call this twice: there must be either a call to cancel_change() or
@@ -124,12 +140,23 @@ typedef struct clap_host_undo {
    // plugin can indicate a format version id and the validity lifetime for the binary blobs.
    // The host can use these to verify the compatibility before applying the delta.
    // If the plugin is unable to use a delta, a notification should be provided to the user and
-   // the crash recovery should perform a best effort job, at least restoring the latest saved state.
+   // the crash recovery should perform a best effort job, at least restoring the latest saved
+   // state.
    //
    // Special case: for objects with shared and synchronized state, changes shouldn't be reported
    // as the host already knows about it.
    // For example, plugin parameter changes shouldn't produce a call to change_made().
    //
+   // Note: if the plugin asked for this interface, then host_state->mark_dirty() will not create an
+   // implicit undo step.
+   //
+   // Note: if the plugin did load a preset or did something that leads to a large delta,
+   // it may consider not producing a delta (pass null) and let the host make a state snapshot
+   // instead.
+   //
+   // Note: if a plugin is producing a lot of changes within a small amount of time, the host
+   // may merge them into a single undo step.
+   //
    // [main-thread]
    void(CLAP_ABI *change_made)(const clap_host_t *host,
                                const char        *name,
@@ -154,6 +181,8 @@ typedef struct clap_host_undo {
    //
    // is_subscribed: set to true to receive context info
    //
+   // It is mandatory for the plugin to implement CLAP_EXT_UNDO_CONTEXT when using this method.
+   //
    // [main-thread]
    void(CLAP_ABI *set_wants_context_updates)(const clap_host_t *host, bool is_subscribed);
 } clap_host_undo_t;