diff --git a/src/routes/channel.rs b/src/routes/channel.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7472909cd4ac75ce0631a71cb50d275b1fc85dd7
--- /dev/null
+++ b/src/routes/channel.rs
@@ -0,0 +1,5 @@
+pub enum ChannelType {
+	DM = 0,
+	GROUP_DM = 1,
+	GUILD_CHANNEL = 2,
+}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index a32647e17ed200fc91e1e87d5ea40f25ed727f79..a7ea2ab884bcfdece162c9c18136563bd7050cf4 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -1,7 +1,8 @@
 use rocket::Rocket;
 
-mod account;
-mod user;
+pub mod account;
+pub mod user;
+pub mod channel;
 
 pub fn mount(rocket: Rocket) -> Rocket {
 	rocket
diff --git a/src/routes/user.rs b/src/routes/user.rs
index 74cd5bc86ed81bab1dec2b22960bafc500de28cf..3ca0284c6c272f65faf15f2a5df1cf42b2d0fe31 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -1,10 +1,12 @@
 use crate::auth::User;
 use crate::database;
+use crate::routes::channel;
 
 use rocket_contrib::json::{ Json, JsonValue };
 use serde::{ Serialize, Deserialize };
 use mongodb::options::FindOptions;
 use bson::{ bson, doc };
+use ulid::Ulid;
 
 /// retrieve your user information
 #[get("/@me")]
@@ -60,13 +62,85 @@ pub fn lookup(_user: User, query: Json<Query>) -> JsonValue {
 /// retrieve all of your DMs
 #[get("/@me/dms")]
 pub fn dms(user: User) -> JsonValue {
-	json!([])
+	let col = database::get_collection("channels");
+
+	let results = col.find(
+		doc! {
+			"$or": [
+				{
+					"type": channel::ChannelType::DM as i32
+				},
+				{
+					"type": channel::ChannelType::GROUP_DM as i32
+				}
+			],
+			"recipients": user.0.to_string()
+		},
+		None
+	).expect("Failed channel lookup");
+
+	let mut channels = Vec::new();
+	for res in results {
+		let doc = res.expect("Failed to unwrap document");
+
+		let mut recipients = Vec::new();
+		for user in doc.get_array("recipients").expect("DB[recipients]") {
+			recipients.push(
+				user.as_str()
+					.expect("Should be a string.")
+			);
+		}
+
+		let active =
+			match doc.get_bool("active") {
+				Ok(x) => x,
+				Err(_) => true
+			};
+		
+		channels.push(
+			json!({
+				"id": doc.get_str("_id").expect("DB[id]"),
+				"type": doc.get_i32("type").expect("DB[type]"),
+				"recipients": recipients,
+				"active": active
+			})
+		);
+	}
+
+	json!(channels)
 }
 
 /// open a DM with a user
 #[get("/<target>/dm")]
 pub fn dm(user: User, target: User) -> JsonValue {
-	json!([])
+	let col = database::get_collection("channels");
+
+	match col.find_one(
+		doc! { "type": channel::ChannelType::DM as i32, "recipients": [ user.0.to_string(), target.0.to_string() ] },
+		None
+	).expect("Failed channel lookup") {
+		Some(channel) =>
+			json!({
+				"id": channel.get_str("_id").expect("DB[id]")
+			}),
+		None => {
+			let id = Ulid::new();
+
+			col.insert_one(
+				doc! {
+					"_id": id.to_string(),
+					"type": channel::ChannelType::DM as i32,
+					"recipients": [ user.0.to_string(), target.0.to_string() ],
+					"active": false
+				},
+				None
+			).expect("Failed insert query.");
+
+			json!({
+				"id": id.to_string()
+			})
+		}
+	}
 }
 
 enum Relationship {