diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/ISubscribable.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/ISubscribable.cs
index 9787bf2d..8e86a671 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/ISubscribable.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/ISubscribable.cs
@@ -51,3 +51,29 @@ public sealed record DataChangeEventArgs(
ISubscriptionHandle SubscriptionHandle,
string FullReference,
DataValueSnapshot Snapshot);
+
+/// One changed attribute within a .
+/// Driver-side full reference of the changed attribute.
+/// New value + quality + timestamps.
+public sealed record DataChangeItem(string FullReference, DataValueSnapshot Snapshot);
+
+/// Event payload for — every attribute
+/// that changed within ONE production burst (a poll cycle, an inbound message, a stream chunk).
+/// The handle returned by the original call.
+/// The changed attributes, one entry per changed tag. Never empty.
+public sealed record DataChangeBatchEventArgs(
+ ISubscriptionHandle SubscriptionHandle,
+ IReadOnlyList Items);
+
+///
+/// Optional driver capability: data changes delivered one event per production burst instead of
+/// one event per tag. A driver implementing this raises once per
+/// burst AND continues raising the per-tag for each item
+/// (legacy consumers: Galaxy cold reads, driver CLIs). A consumer subscribes to EXACTLY ONE of the
+/// two events — subscribing both double-delivers. DriverInstanceActor prefers the batch event.
+///
+public interface IBatchSubscribable : ISubscribable
+{
+ /// Batched data-change notification — one raise per production burst.
+ event EventHandler? OnDataChangeBatch;
+}
diff --git a/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Tests/DataChangeBatchContractTests.cs b/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Tests/DataChangeBatchContractTests.cs
new file mode 100644
index 00000000..738600c8
--- /dev/null
+++ b/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Tests/DataChangeBatchContractTests.cs
@@ -0,0 +1,27 @@
+using Shouldly;
+using Xunit;
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Core.Tests;
+
+/// Contract tests for the batched data-change payload types.
+[Trait("Category", "Unit")]
+public sealed class DataChangeBatchContractTests
+{
+ private sealed record FakeHandle(string DiagnosticId) : ISubscriptionHandle;
+
+ /// Verifies the batch payload carries the subscription handle and its per-tag items.
+ [Fact]
+ public void Batch_args_carry_handle_and_items()
+ {
+ var handle = new FakeHandle("h1");
+ var snap = new DataValueSnapshot(42, 0u, DateTime.UtcNow, DateTime.UtcNow);
+
+ var args = new DataChangeBatchEventArgs(handle, new[] { new DataChangeItem("plc/tag1", snap) });
+
+ args.SubscriptionHandle.ShouldBe(handle);
+ args.Items.Count.ShouldBe(1);
+ args.Items[0].FullReference.ShouldBe("plc/tag1");
+ args.Items[0].Snapshot.ShouldBe(snap);
+ }
+}