diff --git a/backend/src/controllers/gameControllers.ts b/backend/src/controllers/gameControllers.ts
index c5018f9..e7e2d70 100644
--- a/backend/src/controllers/gameControllers.ts
+++ b/backend/src/controllers/gameControllers.ts
@@ -18,6 +18,7 @@ export async function handleGameEvent(req: AuthRequest, res: Response) {
         res.status(404).send({ message: 'Game not found' });
         return;
     }
+    console.log('handling event ', event);
     //todo: When game data is retrieved from database, it is not an instance of GameEngine
     // so we would need to convert it to an instance of GameEngine
     const result = game.dispatchEvent(event);
@@ -46,6 +47,7 @@ export async function handleGameJoin(req: AuthRequest, res: Response) {
     }
     //note: when retrieving game from database, it is not an instance of GameEngine
     // we'd need to add these functions to the mongodb game schema
+    // this should be sent once the joining player receives the game state
     game.dispatchEvent({ type: 'JOIN_GAME', playerId: req.user.id });
     propagateChanges(game);
     req.user.activeGameId = gameCode;
diff --git a/frontend/src/channel.ts b/frontend/src/channel.ts
index c55b9df..9e77a3e 100644
--- a/frontend/src/channel.ts
+++ b/frontend/src/channel.ts
@@ -12,7 +12,7 @@ const GAME_EVENTS = {
     STATE_SYNC: 'STATE_SYNC',
 };
 
-let jwt: string = '';
+let authCreds: { jwt: string; playerId: string } | null = null;
 let polling = false;
 
 let gameEventsDispatcher: (event: types.AppEvent) => void = () => {};
@@ -24,6 +24,9 @@ export function setGameEventsDispatcher(
 }
 let abortController: AbortController | null = null;
 async function poll() {
+    if (!authCreds) {
+        throw new Error('Auth credentials not set');
+    }
     if (abortController) {
         abortController.abort();
     }
@@ -35,7 +38,7 @@ async function poll() {
             method: 'GET',
             headers: {
                 'Content-Type': 'application/json',
-                Authorization: jwt,
+                Authorization: authCreds.jwt,
             },
             signal: abortController.signal,
         }
@@ -73,8 +76,14 @@ function pollLoop() {
         });
 }
 
-export function startPolling(_jwt: string) {
-    jwt = _jwt;
+export function setAuthCreds(jwt: string, playerId: string) {
+    authCreds = { jwt, playerId };
+}
+
+export function startPolling() {
+    if (!authCreds) {
+        throw new Error('Auth credentials not set');
+    }
     polling = true;
     pollLoop();
 }
@@ -85,3 +94,25 @@ export function stopPolling() {
         abortController.abort();
     }
 }
+
+export function triggerEvent(type: types.GameEventType, data?: unknown) {
+    if (!authCreds) {
+        throw new Error('Auth credentials not set');
+    }
+    fetch(`${process.env.REACT_APP_BACKEND_URL}/game/events`, {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json',
+            Authorization: authCreds.jwt,
+        },
+        body: JSON.stringify({
+            event: {
+                type,
+                playerId: authCreds.playerId,
+                data,
+            },
+        }),
+    }).catch((e) => {
+        console.error('Error triggering event:', e);
+    });
+}
diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx
index 40a33ea..009cfb2 100644
--- a/frontend/src/contexts/AuthContext.tsx
+++ b/frontend/src/contexts/AuthContext.tsx
@@ -67,7 +67,8 @@ export function AuthProvider({ children }: { children: ReactElement }) {
                         name: data.user.username,
                     });
                     setJwt(localToken!);
-                    channel.startPolling(localToken!);
+                    channel.setAuthCreds(data.token, data.user.id);
+                    channel.startPolling();
                 }
             } catch (e) {
                 console.info('deleting existing jwt');
@@ -105,7 +106,8 @@ export function AuthProvider({ children }: { children: ReactElement }) {
             });
             setJwt(data.token);
             localStorage.setItem('jwt', data.token);
-            channel.startPolling(data.token);
+            channel.setAuthCreds(data.token, data.user.id);
+            channel.startPolling();
         },
         [setUser, toast]
     );