diff --git a/Cargo.lock b/Cargo.lock
index 6a386cddf66b522b28028b4a71fecf46cb2d3d84..d63d1466b1c40561fe4173322ed14d0213b09823 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -949,6 +949,7 @@ dependencies = [
  "rusqlite",
  "serde",
  "serde_json",
+ "serde_path_to_error",
  "sha2",
  "structopt",
  "tokio",
@@ -1292,6 +1293,15 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "serde_path_to_error"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f6109f0506e20f7e0f910e51a0079acf41da8e0694e6442527c4ddf5a2b158"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde_urlencoded"
 version = "0.7.0"
diff --git a/Cargo.toml b/Cargo.toml
index c26b2d35e97263af1c5bcef0dc947390c1413582..61b0ba43b97ad937cff7c868af92d65247eb22ca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,6 +28,7 @@ regex = "1.5.4"
 rusqlite = { version = "0.25.3", features = ["sqlcipher"] }
 serde = { version = "1.0.126", features = ["derive"] }
 serde_json = "1.0.64"
+serde_path_to_error = "0.1.4"
 sha2 = "0.9.5"
 structopt = { version = "0.3.22", features = ["color", "suggestions"] }
 tokio = { version = "1.9.0", features = ["full"] }
diff --git a/src/error.rs b/src/error.rs
index 07dcee51d90b66060db7c5a35d25ad3c66efa179..7dac4a7716fffa81bf39859ec270d2c30ca42a25 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -65,6 +65,16 @@ impl From<serde_json::Error> for Error {
     }
 }
 
+impl From<serde_path_to_error::Error<serde_json::Error>> for Error {
+    fn from(err: serde_path_to_error::Error<serde_json::Error>) -> Error {
+        let msg = format!("JSON deserialization error {}", err);
+        Error {
+            code: StatusCode::BAD_REQUEST,
+            msg,
+        }
+    }
+}
+
 impl<T> From<std::sync::PoisonError<T>> for Error {
     fn from(err: std::sync::PoisonError<T>) -> Error {
         let msg = format!(
diff --git a/src/warp_api.rs b/src/warp_api.rs
index f5025001a68221fb2164ccf1ad714f39d8449b5a..2f6b3b7c8bf2ffdd32901a35e41bdf213bbf7635 100644
--- a/src/warp_api.rs
+++ b/src/warp_api.rs
@@ -1,11 +1,3 @@
-use crate::api_model::Bulk;
-use crate::api_model::CreateEdge;
-use crate::api_model::CreateItem;
-use crate::api_model::GetEdges;
-use crate::api_model::GetFile;
-use crate::api_model::PayloadWrapper;
-use crate::api_model::Search;
-use crate::api_model::UpdateItem;
 use crate::command_line_interface;
 use crate::command_line_interface::CliOptions;
 use crate::error::Result;
@@ -63,8 +55,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let create_item = items_api
         .and(warp::path!(String / "create_item"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<CreateItem>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let cli = cli_options_arc_clone.deref();
             let result = warp_endpoints::create_item(owner, init_db.deref(), body, cli);
             let result = result.map(|result| warp::reply::json(&result));
@@ -75,8 +67,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let get_item = items_api
         .and(warp::path!(String / "get_item"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<String>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::get_item(owner, init_db.deref(), body);
             let result = result.map(|result| warp::reply::json(&result));
             respond_with_result(result)
@@ -86,8 +78,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let update_item = items_api
         .and(warp::path!(String / "update_item"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<UpdateItem>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::update_item(owner, init_db.deref(), body);
             let result = result.map(|()| warp::reply::json(&serde_json::json!({})));
             respond_with_result(result)
@@ -97,8 +89,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let get_edges = items_api
         .and(warp::path!(String / "get_edges"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<GetEdges>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::get_edges(owner, init_db.deref(), body);
             let result = result.map(|result| warp::reply::json(&result));
             respond_with_result(result)
@@ -108,8 +100,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let create_edge = items_api
         .and(warp::path!(String / "create_edge"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<CreateEdge>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::create_edge(owner, init_db.deref(), body);
             let result = result.map(|result| warp::reply::json(&result));
             respond_with_result(result)
@@ -120,8 +112,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let bulk_action = items_api
         .and(warp::path!(String / "bulk"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<Bulk>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let cli = cli_options_arc_clone.deref();
             let result = warp_endpoints::bulk(owner, init_db.deref(), body, cli);
             let result = result.map(|value| warp::reply::json(&value));
@@ -132,8 +124,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let delete_item = items_api
         .and(warp::path!(String / "delete_item"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<String>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::delete_item(owner, init_db.deref(), body);
             let result = result.map(|()| warp::reply::json(&serde_json::json!({})));
             respond_with_result(result)
@@ -143,8 +135,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let search = items_api
         .and(warp::path!(String / "search"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<Search>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::search(owner, init_db.deref(), body);
             let result = result.map(|result| warp::reply::json(&result));
             respond_with_result(result)
@@ -172,8 +164,8 @@ pub async fn run_server(cli_options: CliOptions) {
     let get_file = file_api
         .and(warp::path!(String / "get_file"))
         .and(warp::path::end())
-        .and(warp::body::json())
-        .map(move |owner: String, body: PayloadWrapper<GetFile>| {
+        .and(warp::body::bytes())
+        .map(move |owner: String, body: Bytes| {
             let result = warp_endpoints::get_file(owner, init_db.deref(), body);
             respond_with_result(result)
         });
diff --git a/src/warp_endpoints.rs b/src/warp_endpoints.rs
index 6fb1ffae4f4dd91166e0d67cc754062d39eb0763..843f201bb8bba5f98e7b98966894f8b07044a3ac 100644
--- a/src/warp_endpoints.rs
+++ b/src/warp_endpoints.rs
@@ -33,6 +33,7 @@ use std::ops::Deref;
 use std::path::PathBuf;
 use std::sync::RwLock;
 use warp::http::status::StatusCode;
+use warp::hyper::body::Bytes;
 
 //
 // Items API:
@@ -41,8 +42,10 @@ use warp::http::status::StatusCode;
 pub fn get_item(
     owner: String,
     init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<String>,
+    body: Bytes,
 ) -> Result<Vec<Value>> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<String> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -56,9 +59,11 @@ pub fn get_item(
 pub fn create_item(
     owner: String,
     init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<CreateItem>,
+    body: Bytes,
     cli: &CliOptions,
 ) -> Result<String> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<CreateItem> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -69,11 +74,9 @@ pub fn create_item(
     })
 }
 
-pub fn update_item(
-    owner: String,
-    init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<UpdateItem>,
-) -> Result<()> {
+pub fn update_item(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<()> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<UpdateItem> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -87,9 +90,11 @@ pub fn update_item(
 pub fn bulk(
     owner: String,
     init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<Bulk>,
+    body: Bytes,
     cli: &CliOptions,
 ) -> Result<Value> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<Bulk> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -100,11 +105,9 @@ pub fn bulk(
     })
 }
 
-pub fn delete_item(
-    owner: String,
-    init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<String>,
-) -> Result<()> {
+pub fn delete_item(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<()> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<String> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -118,8 +121,10 @@ pub fn delete_item(
 pub fn create_edge(
     owner: String,
     init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<CreateEdge>,
+    body: Bytes,
 ) -> Result<String> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<CreateEdge> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -130,8 +135,10 @@ pub fn create_edge(
 pub fn get_edges(
     owner: String,
     init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<GetEdges>,
+    body: Bytes,
 ) -> Result<Vec<Value>> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<GetEdges> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -142,11 +149,9 @@ pub fn get_edges(
     })
 }
 
-pub fn search(
-    owner: String,
-    init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<Search>,
-) -> Result<Vec<Value>> {
+pub fn search(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<Vec<Value>> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<Search> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;
@@ -177,11 +182,9 @@ pub fn upload_file(
     })
 }
 
-pub fn get_file(
-    owner: String,
-    init_db: &RwLock<HashSet<String>>,
-    body: PayloadWrapper<GetFile>,
-) -> Result<Vec<u8>> {
+pub fn get_file(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<Vec<u8>> {
+    let body = &mut serde_json::Deserializer::from_slice(body.deref());
+    let body: PayloadWrapper<GetFile> = serde_path_to_error::deserialize(body)?;
     let auth = body.auth;
     let payload = body.payload;
     let database_key = auth_to_database_key(auth)?;