diff --git a/config/setup/tables/users.ts b/config/setup/tables/users.ts
index 82b132c..00f62c1 100644
--- a/config/setup/tables/users.ts
+++ b/config/setup/tables/users.ts
@@ -1,6 +1,6 @@
 import { CassandraService } from "@lib/cassandra";
 
-export async function createTable() {
+async function createTable() {
 	await CassandraService.getClient().execute(`
 		CREATE TABLE IF NOT EXISTS users (
 			id TEXT PRIMARY KEY,
@@ -15,3 +15,5 @@ export async function createTable() {
 		);
 	`);
 }
+
+export { createTable };
diff --git a/src/lib/http.ts b/src/lib/http.ts
new file mode 100644
index 0000000..3ba934b
--- /dev/null
+++ b/src/lib/http.ts
@@ -0,0 +1,60 @@
+const statusMessages: Record<number, string> = {
+	200: "OK",
+	201: "Created",
+	204: "No Content",
+	400: "Bad Request",
+	401: "Unauthorized",
+	403: "Forbidden",
+	404: "Not Found",
+	500: "Internal Server Error",
+};
+
+export async function returnGenericJsonResponse(
+	statusCode: number,
+	options: GenericJsonResponseOptions = {},
+): Promise<Response> {
+	const { headers, message, error, ...extra } = options;
+
+	if (statusCode === 204) {
+		return new Response(null, {
+			status: statusCode,
+			headers: {
+				"Content-Type": "application/json",
+				...headers,
+			},
+		});
+	}
+
+	const statusMessage = statusMessages[statusCode] || "Unknown Status";
+	const jsonResponse: Record<string, unknown> = {};
+
+	if (statusCode >= 200 && statusCode < 300) {
+		jsonResponse.status = statusMessage;
+		if (message) jsonResponse.message = message;
+	} else {
+		jsonResponse.error = error || statusMessage;
+		if (message) jsonResponse.message = message;
+	}
+
+	const orderedResponse: Record<string, unknown> = {};
+
+	if ("status" in jsonResponse) {
+		orderedResponse.status = jsonResponse.status;
+	}
+	if ("error" in jsonResponse) {
+		orderedResponse.error = jsonResponse.error;
+	}
+	if ("message" in jsonResponse) {
+		orderedResponse.message = jsonResponse.message;
+	}
+
+	Object.assign(orderedResponse, extra);
+
+	return Response.json(orderedResponse, {
+		status: statusCode,
+		headers: {
+			"Content-Type": "application/json",
+			...headers,
+		},
+	});
+}
diff --git a/src/routes/user/register.ts b/src/routes/user/register.ts
new file mode 100644
index 0000000..29a9ddf
--- /dev/null
+++ b/src/routes/user/register.ts
@@ -0,0 +1,34 @@
+import { returnGenericJsonResponse } from "@/lib/http";
+
+const routeDef: RouteDef = {
+	method: "POST",
+	accepts: "application/json",
+	returns: "application/json",
+	needsBody: "json",
+};
+
+async function handler(
+	request: ExtendedRequest,
+	requestBody: unknown,
+): Promise<Response> {
+	const { username, password, email } = requestBody as {
+		username: string;
+		password: string;
+		email: string;
+	};
+
+	if (!username || !password || !email) {
+		return returnGenericJsonResponse(400, {
+			message: "Missing required fields: username, password, email",
+		});
+	}
+
+	return returnGenericJsonResponse(200, {
+		message: "User registered successfully",
+		username: username,
+		password,
+		email,
+	});
+}
+
+export { handler, routeDef };
diff --git a/types/http.d.ts b/types/http.d.ts
new file mode 100644
index 0000000..303fea2
--- /dev/null
+++ b/types/http.d.ts
@@ -0,0 +1,6 @@
+interface GenericJsonResponseOptions {
+	headers?: Record<string, string>;
+	message?: string;
+	error?: string;
+	[key: string]: unknown;
+}