diff --git a/core/screens/chat/ChatRoomView.tsx b/core/screens/chat/ChatRoomView.tsx
index 4390363aa861734d72133c7d79096ee3a4d0fb44..d75f75284686e465e6cb15900523782d9729b1d1 100644
--- a/core/screens/chat/ChatRoomView.tsx
+++ b/core/screens/chat/ChatRoomView.tsx
@@ -40,6 +40,8 @@ import HoliKeyboardSafeAreaView from '@holi/ui/components/organisms/HoliKeyboard
 import { dimensions } from '@holi/ui/styles/globalVars'
 import { createStyleSheet } from 'holi-bricks/utils'
 import { useStyles } from 'holi-bricks/hooks'
+import { TrackingEvent } from '@holi/core/tracking'
+import useTracking from '@holi/core/tracking/hooks/useTracking'
 
 const WAIT_FOR_CHATROOM_DELAY = 5000
 
@@ -54,6 +56,7 @@ const ChatRoomView = () => {
   const { navigateBack, replaceRoute } = useRouting()
   const chatInitialized = useChatInitialized()
   const { styles } = useStyles(stylesheet)
+  const { track } = useTracking()
 
   const [roomId = ''] = useParam('roomId')
   const [room, messages] = useRoomById(roomId)
@@ -175,6 +178,30 @@ const ChatRoomView = () => {
   // reset header when screen is focused
   useShowHeaderOnScreenFocus()
 
+  const sendTrackingEvent = () => {
+    if (!loggedInUser || !room) return
+
+    if (isSpaceRoom) {
+      track(
+        TrackingEvent.Chat.MessageSent({
+          roomId: room.id,
+          type: 'space_message',
+          content: 'text',
+          spaceId: room.content.holiSpaceId,
+          spaceName: room.content.spaceName,
+        })
+      )
+    } else {
+      track(
+        TrackingEvent.Chat.MessageSent({
+          roomId: room.id,
+          type: 'direct_message',
+          content: 'text',
+        })
+      )
+    }
+  }
+
   // TODO: provide skeleton instead of HoliLoader
   if (!chatInitialized || !room || loadingUsers) return <HoliLoader testID={'chat-room-loader'} />
 
@@ -222,6 +249,7 @@ const ChatRoomView = () => {
                     isVisible={!room.hasInvitation}
                     userName={chatPartnerHoliUser?.fullName}
                     roomId={roomId}
+                    onMessageSent={sendTrackingEvent}
                   />
                 </HoliContainer>
               </View>
diff --git a/core/tracking/events.ts b/core/tracking/events.ts
index f2e478a88a4947e96243c96c943010f44db8365f..a8b3742e45f49fcc28ac450632502408cad5c838 100644
--- a/core/tracking/events.ts
+++ b/core/tracking/events.ts
@@ -1,6 +1,6 @@
 /* eslint-disable @typescript-eslint/no-namespace */
 import type { SignupModalPressedTrigger } from '@holi/core/tracking/types'
-import { Channel } from '@holi/core/screens/notifications/hooks/useNotificationPreferences'
+import type { Channel } from '@holi/core/screens/notifications/hooks/useNotificationPreferences'
 
 type RecommendationType = 'space' | 'donation' | 'volunteering_opportunity' | 'goodnews' | 'space_task'
 
@@ -368,6 +368,33 @@ export namespace TrackingEvent {
     ...versionOne,
   })
 
+  export namespace Chat {
+    interface ChatMessageMetadataBase {
+      roomId: string
+      content: 'text' | 'file' | 'image'
+    }
+
+    interface ChatUserMessageMetadata extends ChatMessageMetadataBase {
+      type: 'direct_message'
+    }
+
+    interface ChatSpaceMessageMetadata extends ChatMessageMetadataBase {
+      type: 'space_message'
+      spaceId: string
+      spaceName: string
+    }
+
+    type ChatMessageMetadata = ChatUserMessageMetadata | ChatSpaceMessageMetadata
+
+    export const MessageSent = (metadata: ChatMessageMetadata): TrackingEvent => ({
+      name: 'chatMessageSent',
+      properties: {
+        ...metadata,
+      },
+      ...versionOne,
+    })
+  }
+
   export const NotYetAvailableFeaturePressed = (feature: string): TrackingEvent => ({
     name: 'notYetAvailableFeaturePressed',
     properties: { feature },
diff --git a/packages/chat/src/components/ChatTextInput.tsx b/packages/chat/src/components/ChatTextInput.tsx
index 75d8ab59742442f6dc3802c548baf34055008408..d0afc308abf9ccef2ede4e5215d82e64108f1710 100644
--- a/packages/chat/src/components/ChatTextInput.tsx
+++ b/packages/chat/src/components/ChatTextInput.tsx
@@ -29,9 +29,10 @@ interface Props {
   roomId: string
   isVisible: boolean
   userName?: string
+  onMessageSent?: (content: string) => void
 }
 
-export const ChatTextInput = ({ roomId, isVisible, userName = '' }: Props) => {
+export const ChatTextInput = ({ roomId, isVisible, userName = '', onMessageSent }: Props) => {
   const { t } = useTranslation()
   const { theme } = useTheme()
   const { displayError } = useErrorHandling()
@@ -49,6 +50,7 @@ export const ChatTextInput = ({ roomId, isVisible, userName = '' }: Props) => {
     try {
       setInputValue('')
       await sendMessage({ roomId, text })
+      onMessageSent?.(text)
     } catch (err) {
       setInputValue(text)
       displayError(err, 'Could not send chat message', {