diff --git a/rust_crud_api/src/db/init.rs b/rust_crud_api/src/db/init.rs
index 031b6d9f1b9440402cc932524596b2d3e519f453..d6c4ae201836cf601efd6cc593a66f3f660755e6 100644
--- a/rust_crud_api/src/db/init.rs
+++ b/rust_crud_api/src/db/init.rs
@@ -23,25 +23,39 @@ pub fn init_db(db_url: &str) -> PyResult<()> {
             profilepicture VARCHAR,
             firstlogin BOOLEAN NOT NULL DEFAULT TRUE
         );
+
         CREATE TABLE IF NOT EXISTS groups (
             id SERIAL PRIMARY KEY,
             name VARCHAR NOT NULL,
             member_count INTEGER NOT NULL DEFAULT 0
         );
+
         CREATE TABLE IF NOT EXISTS group_members (
             group_id INTEGER REFERENCES groups(id),
             user_id INTEGER REFERENCES users(id),
             PRIMARY KEY (group_id, user_id)
         );
+
         CREATE TABLE IF NOT EXISTS posts (
-        id SERIAL PRIMARY KEY,
-        user_id INTEGER REFERENCES users(id),
-        group_id INTEGER REFERENCES groups(id),
-        content TEXT NOT NULL,
-        created_at TIMESTAMPTZ NOT NULL DEFAULT now()
+            id SERIAL PRIMARY KEY,
+            user_id INTEGER REFERENCES users(id),
+            group_id INTEGER REFERENCES groups(id),
+            content TEXT NOT NULL,
+            created_at TIMESTAMPTZ NOT NULL DEFAULT now()
+        );
+
+        CREATE TABLE IF NOT EXISTS events (
+            id SERIAL PRIMARY KEY,
+            title TEXT NOT NULL,
+            description TEXT,
+            location TEXT NOT NULL,
+            date DATE NOT NULL,
+            time TIME NOT NULL,
+            created_by INTEGER REFERENCES users(id),
+            group_id INTEGER REFERENCES groups(id),
+            created_at TIMESTAMPTZ NOT NULL DEFAULT now()
         );
         "
     ).map_err(pg_err)?;
     Ok(())
-}
-
+}
\ No newline at end of file
diff --git a/rust_crud_api/src/models/event.rs b/rust_crud_api/src/models/event.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d7ab003147cbe52a84f33f8e96ad0b4bd4ee525f
--- /dev/null
+++ b/rust_crud_api/src/models/event.rs
@@ -0,0 +1,25 @@
+use pyo3::prelude::*;
+use serde::{Serialize, Deserialize};
+
+#[pyclass]
+#[derive(Serialize, Deserialize, Debug)]
+pub struct Event {
+    #[pyo3(get, set)]
+    pub id: i32,
+    #[pyo3(get, set)]
+    pub title: String,
+    #[pyo3(get, set)]
+    pub description: Option<String>,
+    #[pyo3(get, set)]
+    pub location: String,
+    #[pyo3(get, set)]
+    pub date: String, // or NaiveDate
+    #[pyo3(get, set)]
+    pub time: String, // or NaiveTime
+    #[pyo3(get, set)]
+    pub created_by: i32,
+    #[pyo3(get, set)]
+    pub group_id: Option<i32>,
+    #[pyo3(get, set)]
+    pub created_at: String,
+}
\ No newline at end of file
diff --git a/rust_crud_api/src/models/events.rs b/rust_crud_api/src/models/events.rs
new file mode 100644
index 0000000000000000000000000000000000000000..809c61c3e1714a1c67cbd9ad85fa9638d466e099
--- /dev/null
+++ b/rust_crud_api/src/models/events.rs
@@ -0,0 +1,39 @@
+use crate::models::Event;
+use pyo3::prelude::*;
+use pyo3::exceptions::PyRuntimeError;
+use postgres::{Client, NoTls};
+use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
+
+fn pg_err(e: postgres::Error) -> PyErr {
+    PyRuntimeError::new_err(e.to_string())
+}
+
+/// Create a new event
+#[pyfunction]
+pub fn create_event(
+    db_url: &str,
+    title: &str,
+    description: Option<&str>,
+    location: &str,
+    date: &str,         // expected format: "YYYY-MM-DD"
+    time: &str,         // expected format: "HH:MM:SS"
+    created_by: i32,
+    group_id: Option<i32>
+) -> PyResult<()> {
+    let mut client = Client::connect(db_url, NoTls).map_err(pg_err)?;
+
+    let date_parsed = NaiveDate::parse_from_str(date, "%Y-%m-%d")
+        .map_err(|e| PyRuntimeError::new_err(format!("Invalid date: {}", e)))?;
+    let time_parsed = NaiveTime::parse_from_str(time, "%H:%M:%S")
+        .map_err(|e| PyRuntimeError::new_err(format!("Invalid time: {}", e)))?;
+
+    client.execute(
+        "
+        INSERT INTO events (title, description, location, date, time, created_by, group_id)
+        VALUES ($1, $2, $3, $4, $5, $6, $7)
+        ",
+        &[&title, &description, &location, &date_parsed, &time_parsed, &created_by, &group_id]
+    ).map_err(pg_err)?;
+
+    Ok(())
+}
\ No newline at end of file