diff --git a/packages/server/src/HTTPError.js b/packages/server/src/HTTPError.js
new file mode 100644
index 0000000..8317c7b
--- /dev/null
+++ b/packages/server/src/HTTPError.js
@@ -0,0 +1,27 @@
+/**
+ * Represents an http error.
+ */
+export class HTTPError extends Error
+{
+    /**
+     * The http status code.
+     *
+     * @type {number}
+     */
+    status;
+
+    /**
+     * Initializes a new instance of the {@link HTTPError `HTTPError`} class.
+     *
+     * @param {number} status
+     * The http status code.
+     *
+     * @param {string} message
+     * The error message.
+     */
+    constructor(status, message)
+    {
+        super(message);
+        this.status = status;
+    }
+}
diff --git a/packages/server/src/main.js b/packages/server/src/main.js
index caaa151..8a767e4 100644
--- a/packages/server/src/main.js
+++ b/packages/server/src/main.js
@@ -1,18 +1,49 @@
 import { join } from "path";
 import { fileURLToPath } from "url";
 import express from "express";
+import { HTTPError } from "./HTTPError.js";
 
 const dirname = fileURLToPath(new URL(".", import.meta.url));
 const app = express();
 
+const apiKeys = [
+    "c4game"
+];
+
 app.use(express.static(join(dirname, "..", "..", "game", "lib", "static")));
+app.use("/api", express.json());
+
+app.use(
+    "/api",
+    (request, response, next) =>
+    {
+        const keyParam = "token";
+
+        if (keyParam in request.query)
+        {
+            let key = request.query[keyParam];
+
+            if (typeof key === "string" && apiKeys.includes(key))
+            {
+                next();
+            }
+            else
+            {
+                next(new HTTPError(401, "The specified API token is invalid"));
+            }
+        }
+        else
+        {
+            next(new HTTPError(401, "An API token is required"));
+        }
+    });
 
 app.use(
     [
         (error, request, response, next) =>
         {
             response.send(`${error}`);
-            response.status(error?.status ?? 500);
+            response.status(error instanceof HTTPError ? error.status : 500);
         }
     ]);