diff --git a/actix/Cargo.lock b/actix/Cargo.lock
index fb9da0a..8fe58e6 100644
--- a/actix/Cargo.lock
+++ b/actix/Cargo.lock
@@ -485,6 +485,8 @@ dependencies = [
  "rand",
  "regex",
  "rusqlite",
+ "serde",
+ "serde_json",
 ]
 
 [[package]]
diff --git a/actix/Cargo.toml b/actix/Cargo.toml
index 440ee82..763fb79 100644
--- a/actix/Cargo.toml
+++ b/actix/Cargo.toml
@@ -32,3 +32,5 @@ rand = "0.8.5"
 actix-session = { version = "0.9.0", features = ["cookie-session"] }
 env_logger = "0.11.1"
 nanoid = "0.4.0"
+serde_json = "1.0.115"
+serde = { version = "1.0.197", features = [ "derive" ] }
diff --git a/actix/src/database.rs b/actix/src/database.rs
index 53e32e6..0dc66a1 100644
--- a/actix/src/database.rs
+++ b/actix/src/database.rs
@@ -1,4 +1,12 @@
 use rusqlite::Connection;
+use serde::Serialize;
+
+#[derive(Serialize)]
+pub struct DbRow {
+    shortlink: String,
+    longlink: String,
+    hits: i64,
+}
 
 pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
     let mut statement = db
@@ -10,17 +18,19 @@ pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
         .ok()
 }
 
-pub fn getall(db: &Connection) -> Vec<String> {
+pub fn getall(db: &Connection) -> Vec<DbRow> {
     let mut statement = db.prepare_cached("SELECT * FROM urls").unwrap();
 
     let mut data = statement.query([]).unwrap();
 
-    let mut links: Vec<String> = Vec::new();
+    let mut links: Vec<DbRow> = Vec::new();
     while let Some(row) = data.next().unwrap() {
-        let short_url: String = row.get("short_url").unwrap();
-        let long_url: String = row.get("long_url").unwrap();
-        let hits: i64 = row.get("hits").unwrap();
-        links.push(format!("{short_url},{long_url},{hits}"));
+        let row_struct = DbRow {
+            shortlink: row.get("short_url").unwrap(),
+            longlink: row.get("long_url").unwrap(),
+            hits: row.get("hits").unwrap(),
+        };
+        links.push(row_struct);
     }
 
     links
diff --git a/actix/src/utils.rs b/actix/src/utils.rs
index 1575596..68bad35 100644
--- a/actix/src/utils.rs
+++ b/actix/src/utils.rs
@@ -5,6 +5,13 @@ use nanoid::nanoid;
 use rand::seq::SliceRandom;
 use regex::Regex;
 use rusqlite::Connection;
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Url {
+    shortlink: String,
+    longlink: String,
+}
 
 pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
     if validate_link(&shortlink) {
@@ -21,12 +28,11 @@ fn validate_link(link: &str) -> bool {
 
 pub fn getall(db: &Connection) -> String {
     let links = database::getall(db);
-    links.join("\n")
+    serde_json::to_string(&links).unwrap()
 }
 
 pub fn add_link(req: String, db: &Connection) -> (bool, String) {
-    let chunks: Vec<&str> = req.split(';').collect();
-    let longlink = String::from(chunks[0]);
+    let mut chunks: Url = serde_json::from_str(&req).unwrap();
 
     let style = env::var("slug_style").unwrap_or(String::from("Pair"));
     let len_str = env::var("slug_length").unwrap_or(String::from("8"));
@@ -35,20 +41,16 @@ pub fn add_link(req: String, db: &Connection) -> (bool, String) {
         len = 4;
     }
 
-    let mut shortlink;
-    if chunks.len() > 1 {
-        shortlink = chunks[1].to_string().to_lowercase();
-        if shortlink.is_empty() {
-            shortlink = gen_link(style, len);
-        }
-    } else {
-        shortlink = gen_link(style, len);
+    if chunks.shortlink.is_empty() {
+        chunks.shortlink = gen_link(style, len);
     }
 
-    if validate_link(shortlink.as_str()) && get_longurl(shortlink.clone(), db).is_none() {
+    if validate_link(chunks.shortlink.as_str())
+        && get_longurl(chunks.shortlink.clone(), db).is_none()
+    {
         (
-            database::add_link(shortlink.clone(), longlink, db),
-            shortlink,
+            database::add_link(chunks.shortlink.clone(), chunks.longlink, db),
+            chunks.shortlink,
         )
     } else {
         (false, String::from("shortUrl not valid or already in use"))
diff --git a/resources/static/script.js b/resources/static/script.js
index b7d19ca..c9d6194 100644
--- a/resources/static/script.js
+++ b/resources/static/script.js
@@ -31,16 +31,7 @@ const refreshData = async () => {
         document.getElementById("login-dialog").showModal();
         document.getElementById("password").focus();
     } else {
-        data = reply
-            .split("\n")
-            .filter(line => line !== "")
-            .map(line => line.split(","))
-            .map(arr => ({
-                short: arr[0],
-                long: arr[1],
-                hits: arr[2]
-            }));
-
+        data = JSON.parse(reply)
         displayData(data);
     }
 };
@@ -87,18 +78,18 @@ const showAlert = async (text, col) => {
 
 const TR = (row, site) => {
     const tr = document.createElement("tr");
-    const longTD = TD(A_LONG(row.long), "Long URL");
+    const longTD = TD(A_LONG(row["longlink"]), "Long URL");
     var shortTD = null;
     if (window.isSecureContext) {
-        shortTD = TD(A_SHORT(row.short, site), "Short URL");
+        shortTD = TD(A_SHORT(row["shortlink"], site), "Short URL");
     }
     else {
-        shortTD = TD(A_SHORT_INSECURE(row.short, site), "Short URL");
+        shortTD = TD(A_SHORT_INSECURE(row["shortlink"], site), "Short URL");
     }
-    hitsTD = TD(row.hits);
+    hitsTD = TD(row["hits"]);
     hitsTD.setAttribute("label", "Hits");
     hitsTD.setAttribute("name", "hitsColumn");
-    const btn = deleteButton(row.short);
+    const btn = deleteButton(row["shortlink"]);
 
     tr.appendChild(shortTD);
     tr.appendChild(longTD);
@@ -168,14 +159,19 @@ const TD = (s, u) => {
 
 const submitForm = () => {
     const form = document.forms.namedItem("new-url-form");
-    const longUrl = form.elements["longUrl"];
-    const shortUrl = form.elements["shortUrl"];
+    const data ={
+        "longlink": form.elements["longUrl"].value,
+        "shortlink": form.elements["shortUrl"].value,
+    };
 
     const url = prepSubdir("/api/new");
 
     fetch(url, {
         method: "POST",
-        body: `${longUrl.value};${shortUrl.value}`
+        headers: {
+            "Content-Type": "application/json",
+        },
+        body: JSON.stringify(data),
     })
         .then(res => {
             if (!res.ok) {