diff --git a/demo/addons/gdpd/gdpd.gdextension.uid b/demo/addons/gdpd/gdpd.gdextension.uid
new file mode 100644
index 0000000000000000000000000000000000000000..45e065e3835b1d5445ffa6fc0c84b2c7c6ed8389
--- /dev/null
+++ b/demo/addons/gdpd/gdpd.gdextension.uid
@@ -0,0 +1 @@
+uid://dcjcppemo68jx
diff --git a/demo/project.godot b/demo/project.godot
index f1d685070a54afedab01fe3d1321f9546232ebac..3c340b90e3d43ae2746a6b783ea7288655c0b12a 100644
--- a/demo/project.godot
+++ b/demo/project.godot
@@ -12,7 +12,7 @@ config_version=5
 
 config/name="GdPd"
 run/main_scene="res://Main.tscn"
-config/features=PackedStringArray("4.3")
+config/features=PackedStringArray("4.4")
 run/low_processor_mode=true
 config/icon="res://icon.png"
 
diff --git a/src/gdpd.cpp b/src/gdpd.cpp
index 6c69a1ecc43ab3aafa682e94f1c7de24bf937564..f57cc9db56ffc2a771ab0335c8838ad5f443fab9 100644
--- a/src/gdpd.cpp
+++ b/src/gdpd.cpp
@@ -76,6 +76,8 @@ void GdPd::_bind_methods() {
                          &GdPd::get_application_name);
 
     ClassDB::bind_method(D_METHOD("send"), &GdPd::send);
+    ClassDB::bind_method(D_METHOD("begin_bundle"), &GdPd::begin_bundle);
+    ClassDB::bind_method(D_METHOD("send_bundle"), &GdPd::send_bundle);
 
 
     ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", 
@@ -336,6 +338,21 @@ void GdPd::stop() {
 	print("Stopped");
 }
 
+void GdPd::begin_bundle() {
+    if(mode==OSC) {
+        m_oscBundleStarted=true;
+        m_oscBundle = lo_bundle_new(LO_TT_IMMEDIATE);
+    }
+}
+
+void GdPd::send_bundle() {
+    if(mode==OSC && m_oscBundleStarted) {
+        lo_send_bundle(m_destination, m_oscBundle);
+        lo_bundle_free_recursive(m_oscBundle);
+        m_oscBundleStarted=false;
+    }
+}
+
 void GdPd::send(String address, Array arguments) {
     if(!m_init) {
         return;
@@ -362,7 +379,12 @@ void GdPd::send(String address, Array arguments) {
         
         std::string addrStr(address.utf8().get_data());
         addrStr = std::string("/gdpd/")+m_applicationNameStr+"/"+addrStr;
-        lo_send_message(m_destination, addrStr.c_str(), msg);
+        if(m_oscBundleStarted) {
+            lo_bundle_add_message(m_oscBundle, addrStr.c_str(), msg);
+        }
+        else {
+            lo_send_message(m_destination, addrStr.c_str(), msg);
+        }
     }
     else {
         libpd_start_message(arguments.size()+2);
diff --git a/src/gdpd.h b/src/gdpd.h
index 4d89ea5cbceac36182147836beb1ddc0e152fdf3..05087926a211153c0604f3e459ab5a7b3e476554 100644
--- a/src/gdpd.h
+++ b/src/gdpd.h
@@ -111,6 +111,8 @@ private:
     lo_address m_destination;
     int m_senderPort;
     int m_receiverPort;
+    bool m_oscBundleStarted;
+    lo_bundle m_oscBundle;
 
 public:
 
@@ -156,6 +158,9 @@ public:
 
     void send(String destination, Array arguments);
 
+    void begin_bundle();
+    void send_bundle();
+
 	virtual void print(const std::string& message) override;
 
 	//libpd hooks