diff --git a/Cargo.lock b/Cargo.lock
index b9b1ca791a0bfda6275dac44942453b841a1615f..bc76ea837668853b58cedc55cf3c067b67c03761 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1068,6 +1068,8 @@ checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
 [[package]]
 name = "hive_pubsub"
 version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ac4635b1e9faf304ccb33c2f0edbc615030e40d249183281fc788ef20ef5c76"
 dependencies = [
  "futures",
  "many-to-many",
@@ -2473,7 +2475,7 @@ dependencies = [
 
 [[package]]
 name = "revolt"
-version = "0.4.0-alpha.2"
+version = "0.4.0-alpha.3"
 dependencies = [
  "async-std",
  "async-tungstenite",
diff --git a/Cargo.toml b/Cargo.toml
index 2bd5f1076a17f07ac72178d01b25c5fe8f55ce76..cc28e92e4a98f7e5785075a6e06cfec2b9b3298b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "revolt"
-version = "0.4.0-alpha.2"
+version = "0.4.0-alpha.3"
 authors = ["Paul Makles <paulmakles@gmail.com>"]
 edition = "2018"
 
diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs
index dc7032261b43b7da9ba93319d03127732e5fa71a..81d87c747a5fe7e4ad1cfc16143fd3bfe23b3d13 100644
--- a/src/database/entities/user.rs
+++ b/src/database/entities/user.rs
@@ -25,6 +25,20 @@ pub struct Relationship {
     pub status: RelationshipStatus,
 }
 
+/*
+pub enum Badge {
+    Developer = 1
+}
+*/
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(tag = "type")]
+pub enum UserStatus {
+    Text {
+        text: String
+    }
+}
+
 #[derive(Serialize, Deserialize, Debug)]
 pub struct User {
     #[serde(rename = "_id")]
@@ -33,6 +47,13 @@ pub struct User {
     #[serde(skip_serializing_if = "Option::is_none")]
     pub relations: Option<Vec<Relationship>>,
 
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub badges: Option<i32>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub status: Option<Vec<UserStatus>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub profile: Option<String>,
+
     // ? This should never be pushed to the collection.
     #[serde(skip_serializing_if = "Option::is_none")]
     pub relationship: Option<RelationshipStatus>,
@@ -65,6 +86,7 @@ impl User {
             self.online = Some(is_online(&self.id));
         }
 
+        self.profile = None;
         self
     }
 
@@ -73,7 +95,7 @@ impl User {
         if username == "revolt" && username == "admin" {
             return Ok(true)
         }
-    
+
         if get_collection("users")
             .find_one(
                 doc! {
diff --git a/src/notifications/payload.rs b/src/notifications/payload.rs
index 5a8d612da2db1a2138280e311376ad99f6c290c2..73cf7895603da4363f5d2a9e4990588cbcbcc982 100644
--- a/src/notifications/payload.rs
+++ b/src/notifications/payload.rs
@@ -77,7 +77,7 @@ pub async fn generate_ready(mut user: User) -> Result<ClientboundNotification> {
                     }
                 },
                 FindOptions::builder()
-                    .projection(doc! { "_id": 1, "username": 1 })
+                    .projection(doc! { "_id": 1, "username": 1, "badges": 1, "status": 1 })
                     .build(),
             )
             .await
diff --git a/src/routes/channels/message_send.rs b/src/routes/channels/message_send.rs
index 6803ca5f08bb8f0beaaddbc32f90df3a8709b1d1..626fba918dc95b3d5604c04b57c73b25b54974dd 100644
--- a/src/routes/channels/message_send.rs
+++ b/src/routes/channels/message_send.rs
@@ -32,11 +32,11 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<JsonVal
     }
 
     let target = target.fetch_channel().await?;
-
     let perm = permissions::PermissionCalculator::new(&user)
         .with_channel(&target)
         .for_channel()
         .await?;
+
     if !perm.get_send_message() {
         Err(Error::MissingPermission)?
     }
diff --git a/src/routes/root.rs b/src/routes/root.rs
index b8cc6c950e5488b0db99dda215bd338f1be79118..18c9c53e2fcefa98e3a202284ba8a3f228e3a068 100644
--- a/src/routes/root.rs
+++ b/src/routes/root.rs
@@ -9,7 +9,7 @@ use rocket_contrib::json::JsonValue;
 #[get("/")]
 pub async fn root() -> JsonValue {
     json!({
-        "revolt": "0.4.0-alpha.2",
+        "revolt": "0.4.0-alpha.3",
         "features": {
             "registration": !*DISABLE_REGISTRATION,
             "captcha": {
diff --git a/src/routes/users/fetch_profile.rs b/src/routes/users/fetch_profile.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7e2b6b91dec04681a7904d91d1a05be61a9a3a2f
--- /dev/null
+++ b/src/routes/users/fetch_profile.rs
@@ -0,0 +1,24 @@
+use crate::database::*;
+use crate::util::result::{Error, Result};
+
+use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
+
+#[get("/<target>/profile")]
+pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
+    let target = target.fetch_user().await?;
+    let perm = permissions::PermissionCalculator::new(&user)
+        .with_user(&target)
+        .for_user_given()
+        .await?;
+    
+    if !perm.get_view_profile() {
+        Err(Error::MissingPermission)?
+    }
+
+    if target.profile.is_some() {
+        Ok(json!({ "profile": target.profile }))
+    } else {
+        Ok(json!({}))
+    }
+}
diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs
index 163978fdb0deba56f0cfa2fb552405501f88a61b..6945bcbe5e207602fc93be13770c757eb08f5977 100644
--- a/src/routes/users/mod.rs
+++ b/src/routes/users/mod.rs
@@ -3,6 +3,7 @@ use rocket::Route;
 mod add_friend;
 mod block_user;
 mod fetch_dms;
+mod fetch_profile;
 mod fetch_relationship;
 mod fetch_relationships;
 mod fetch_user;
@@ -19,6 +20,7 @@ pub fn routes() -> Vec<Route> {
         fetch_user::req,
         get_default_avatar::req,
         get_avatar::req,
+        fetch_profile::req,
         // Direct Messaging
         fetch_dms::req,
         open_dm::req,