diff --git a/src/Core/AdminConsole/Repositories/OrganizationIntegrationConfigurationRepository.cs b/src/Core/AdminConsole/Repositories/OrganizationIntegrationConfigurationRepository.cs
index af33b123c7..03e3ae2bf4 100644
--- a/src/Core/AdminConsole/Repositories/OrganizationIntegrationConfigurationRepository.cs
+++ b/src/Core/AdminConsole/Repositories/OrganizationIntegrationConfigurationRepository.cs
@@ -46,7 +46,7 @@ public class OrganizationIntegrationConfigurationRepository(GlobalSettings globa
                     {
                         Url = _webhookUrl,
                     },
-                    Template = "{ \"newObject\": true }"
+                    Template = "{ \"Date\": \"#Date#\", \"Type\": \"#Type#\", \"UserId\": \"#UserId#\" }"
                 } as IntegrationConfiguration<T>;
             default:
                 return null;
diff --git a/src/Core/AdminConsole/Services/Implementations/WebhookEventHandler.cs b/src/Core/AdminConsole/Services/Implementations/WebhookEventHandler.cs
index 4ad3713107..95e668e5be 100644
--- a/src/Core/AdminConsole/Services/Implementations/WebhookEventHandler.cs
+++ b/src/Core/AdminConsole/Services/Implementations/WebhookEventHandler.cs
@@ -1,4 +1,4 @@
-using System.Net.Http.Json;
+using System.Text;
 using Bit.Core.Enums;
 using Bit.Core.Models.Data;
 using Bit.Core.Models.Data.Integrations;
@@ -27,7 +27,11 @@ public class WebhookEventHandler(
             eventMessage.Type);
         if (configuration is not null)
         {
-            var content = JsonContent.Create(configuration.Template);
+            var content = new StringContent(
+                TemplateProcessor.ReplaceTokens(configuration.Template, eventMessage),
+                Encoding.UTF8,
+                "application/json"
+            );
             var response = await _httpClient.PostAsync(
                 configuration.Configuration.Url,
                 content);
diff --git a/src/Core/AdminConsole/Utilities/TemplateProcessor.cs b/src/Core/AdminConsole/Utilities/TemplateProcessor.cs
new file mode 100644
index 0000000000..e7613a3f20
--- /dev/null
+++ b/src/Core/AdminConsole/Utilities/TemplateProcessor.cs
@@ -0,0 +1,20 @@
+using System.Text.RegularExpressions;
+
+public static class TemplateProcessor
+{
+    private static readonly Regex TokenRegex = new(@"#(\w+)#", RegexOptions.Compiled);
+
+    public static string ReplaceTokens(string template, object values)
+    {
+        if (string.IsNullOrEmpty(template) || values == null)
+            return template;
+
+        var type = values.GetType();
+        return TokenRegex.Replace(template, match =>
+        {
+            var propertyName = match.Groups[1].Value;
+            var property = type.GetProperty(propertyName);
+            return property?.GetValue(values)?.ToString() ?? match.Value;
+        });
+    }
+}
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index a271b41784..8a8de3d77d 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -74,7 +74,6 @@
   </ItemGroup>
   
   <ItemGroup>
-    <Folder Include="AdminConsole\Utilities\" />
     <Folder Include="Resources\" />
     <Folder Include="Properties\" />
   </ItemGroup>
diff --git a/test/Core.Test/AdminConsole/Services/WebhookEventHandlerTests.cs b/test/Core.Test/AdminConsole/Services/WebhookEventHandlerTests.cs
index 6c7d7178c1..0dc4a9495a 100644
--- a/test/Core.Test/AdminConsole/Services/WebhookEventHandlerTests.cs
+++ b/test/Core.Test/AdminConsole/Services/WebhookEventHandlerTests.cs
@@ -1,6 +1,9 @@
 using System.Net;
 using System.Net.Http.Json;
+using Bit.Core.Enums;
 using Bit.Core.Models.Data;
+using Bit.Core.Models.Data.Integrations;
+using Bit.Core.Repositories;
 using Bit.Core.Services;
 using Bit.Test.Common.AutoFixture;
 using Bit.Test.Common.AutoFixture.Attributes;
@@ -8,7 +11,6 @@ using Bit.Test.Common.Helpers;
 using Bit.Test.Common.MockedHttpClient;
 using NSubstitute;
 using Xunit;
-using GlobalSettings = Bit.Core.Settings.GlobalSettings;
 
 namespace Bit.Core.Test.Services;
 
@@ -16,7 +18,7 @@ namespace Bit.Core.Test.Services;
 public class WebhookEventHandlerTests
 {
     private readonly MockedHttpMessageHandler _handler;
-    private HttpClient _httpClient;
+    private readonly HttpClient _httpClient;
 
     private const string _webhookUrl = "http://localhost/test/event";
 
@@ -29,16 +31,26 @@ public class WebhookEventHandlerTests
         _httpClient = _handler.ToHttpClient();
     }
 
-    public SutProvider<WebhookEventHandler> GetSutProvider()
+    private SutProvider<WebhookEventHandler> GetSutProvider()
     {
         var clientFactory = Substitute.For<IHttpClientFactory>();
         clientFactory.CreateClient(WebhookEventHandler.HttpClientName).Returns(_httpClient);
 
-        var globalSettings = new GlobalSettings();
-        globalSettings.EventLogging.WebhookUrl = _webhookUrl;
+        var repository = Substitute.For<IOrganizationIntegrationConfigurationRepository>();
+        repository.GetConfigurationAsync<WebhookConfiguration>(
+            Arg.Any<Guid>(),
+            IntegrationType.Webhook,
+            Arg.Any<EventType>()
+        ).Returns(
+            new IntegrationConfiguration<WebhookConfiguration>
+            {
+                Configuration = new WebhookConfiguration { ApiKey = "", Url = _webhookUrl },
+                Template = "{ \"Date\": \"#Date#\", \"Type\": \"#Type#\", \"UserId\": \"#UserId#\" }"
+            }
+        );
 
         return new SutProvider<WebhookEventHandler>()
-            .SetDependency(globalSettings)
+            .SetDependency(repository)
             .SetDependency(clientFactory)
             .Create();
     }
@@ -50,21 +62,22 @@ public class WebhookEventHandlerTests
 
         await sutProvider.Sut.HandleEventAsync(eventMessage);
         sutProvider.GetDependency<IHttpClientFactory>().Received(1).CreateClient(
-            Arg.Is(AssertHelper.AssertPropertyEqual<string>(WebhookEventHandler.HttpClientName))
+            Arg.Is(AssertHelper.AssertPropertyEqual(WebhookEventHandler.HttpClientName))
         );
 
         Assert.Single(_handler.CapturedRequests);
         var request = _handler.CapturedRequests[0];
         Assert.NotNull(request);
-        var returned = await request.Content.ReadFromJsonAsync<EventMessage>();
+        var returned = await request.Content.ReadFromJsonAsync<MockEvent>();
+        var expected = MockEvent.From(eventMessage);
 
         Assert.Equal(HttpMethod.Post, request.Method);
         Assert.Equal(_webhookUrl, request.RequestUri.ToString());
-        AssertHelper.AssertPropertyEqual(eventMessage, returned, new[] { "IdempotencyId" });
+        AssertHelper.AssertPropertyEqual(expected, returned);
     }
 
     [Theory, BitAutoData]
-    public async Task HandleEventManyAsync_PostsEventsToUrl(IEnumerable<EventMessage> eventMessages)
+    public async Task HandleEventManyAsync_PostsEventsToUrl(List<EventMessage> eventMessages)
     {
         var sutProvider = GetSutProvider();
 
@@ -73,13 +86,29 @@ public class WebhookEventHandlerTests
             Arg.Is(AssertHelper.AssertPropertyEqual<string>(WebhookEventHandler.HttpClientName))
         );
 
-        Assert.Single(_handler.CapturedRequests);
         var request = _handler.CapturedRequests[0];
         Assert.NotNull(request);
-        var returned = request.Content.ReadFromJsonAsAsyncEnumerable<EventMessage>();
+        var returned = await request.Content.ReadFromJsonAsync<MockEvent>();
+        var expected = MockEvent.From(eventMessages.First());
 
         Assert.Equal(HttpMethod.Post, request.Method);
         Assert.Equal(_webhookUrl, request.RequestUri.ToString());
-        AssertHelper.AssertPropertyEqual(eventMessages, returned, new[] { "IdempotencyId" });
+        AssertHelper.AssertPropertyEqual(expected, returned);
+    }
+}
+
+public class MockEvent(string date, string type, string userId)
+{
+    public string Date { get; set; } = date;
+    public string Type { get; set; } = type;
+    public string UserId { get; set; } = userId;
+
+    public static MockEvent From(EventMessage eventMessage)
+    {
+        return new MockEvent(
+            eventMessage.Date.ToString(),
+            eventMessage.Type.ToString(),
+            eventMessage.UserId.ToString()
+        );
     }
 }
diff --git a/test/Core.Test/AdminConsole/Utilities/TemplateProcessorTests.cs b/test/Core.Test/AdminConsole/Utilities/TemplateProcessorTests.cs
new file mode 100644
index 0000000000..46b2658cdb
--- /dev/null
+++ b/test/Core.Test/AdminConsole/Utilities/TemplateProcessorTests.cs
@@ -0,0 +1,91 @@
+using Bit.Core.Models.Data;
+using Bit.Test.Common.AutoFixture.Attributes;
+using Xunit;
+
+namespace Bit.Core.Test.Utilities;
+
+public class TemplateProcessorTests
+{
+    [Theory, BitAutoData]
+    public void ReplaceTokens_ReplacesSingleToken(EventMessage eventMessage)
+    {
+        var template = "Event #Type# occurred.";
+        var expected = $"Event {eventMessage.Type} occurred.";
+        var result = TemplateProcessor.ReplaceTokens(template, eventMessage);
+
+        Assert.Equal(expected, result);
+    }
+
+    [Theory, BitAutoData]
+    public void ReplaceTokens_ReplacesMultipleTokens(EventMessage eventMessage)
+    {
+        var template = "Event #Type#, User (id: #UserId#).";
+        var expected = $"Event {eventMessage.Type}, User (id: {eventMessage.UserId}).";
+        var result = TemplateProcessor.ReplaceTokens(template, eventMessage);
+
+        Assert.Equal(expected, result);
+    }
+
+    [Theory, BitAutoData]
+    public void ReplaceTokens_LeavesUnknownTokensUnchanged(EventMessage eventMessage)
+    {
+        var template = "Event #Type#, User (id: #UserId#), Details: #UnknownKey#.";
+        var expected = $"Event {eventMessage.Type}, User (id: {eventMessage.UserId}), Details: #UnknownKey#.";
+        var result = TemplateProcessor.ReplaceTokens(template, eventMessage);
+
+        Assert.Equal(expected, result);
+    }
+
+    [Theory, BitAutoData]
+    public void ReplaceTokens_WithNullProperty_LeavesTokenUnchanged(EventMessage eventMessage)
+    {
+        eventMessage.UserId = null; // Ensure UserId is null for this test
+
+        var template = "Event #Type#, User (id: #UserId#).";
+        var expected = $"Event {eventMessage.Type}, User (id: #UserId#).";
+        var result = TemplateProcessor.ReplaceTokens(template, eventMessage);
+
+        Assert.Equal(expected, result);
+    }
+
+    [Theory, BitAutoData]
+    public void ReplaceTokens_IgnoresCaseSensitiveTokens(EventMessage eventMessage)
+    {
+        var template = "Event #type#, User (id: #UserId#)."; // Lowercase "type"
+        var expected = $"Event #type#, User (id: {eventMessage.UserId})."; // Token remains unchanged
+        var result = TemplateProcessor.ReplaceTokens(template, eventMessage);
+
+        Assert.Equal(expected, result);
+    }
+
+    [Theory, BitAutoData]
+    public void ReplaceTokens_ReturnsOriginalString_IfNoTokensPresent(EventMessage eventMessage)
+    {
+        var template = "System is running normally.";
+        var expected = "System is running normally.";
+        var result = TemplateProcessor.ReplaceTokens(template, eventMessage);
+
+        Assert.Equal(expected, result);
+    }
+
+    [Theory, BitAutoData]
+    public void ReplaceTokens_ReturnsOriginalString_IfTemplateIsNullOrEmpty(EventMessage eventMessage)
+    {
+        var emptyTemplate = "";
+        var expectedEmpty = "";
+
+        Assert.Equal(expectedEmpty, TemplateProcessor.ReplaceTokens(emptyTemplate, eventMessage));
+        Assert.Null(TemplateProcessor.ReplaceTokens(null, eventMessage));
+    }
+
+    [Fact]
+    public void ReplaceTokens_ReturnsOriginalString_IfDataObjectIsNull()
+    {
+        var template = "Event #Type#, User (id: #UserId#).";
+        var expected = "Event #Type#, User (id: #UserId#).";
+
+        var result = TemplateProcessor.ReplaceTokens(template, null);
+
+        Assert.Equal(expected, result);
+    }
+}