diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs
index eac30d93a..3b6419187 100644
--- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs
+++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs
@@ -16,6 +16,7 @@ async fn should_authenticate_requests_by_using_a_token_query_param() {
     let token = env.get_connection_info().api_token.unwrap();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_request_with_query("stats", Query::params([QueryParam::new("token", &token)].to_vec()), None)
         .await;
 
@@ -33,6 +34,7 @@ async fn should_not_authenticate_requests_when_the_token_is_missing() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_request_with_query("stats", Query::default(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -55,6 +57,7 @@ async fn should_not_authenticate_requests_when_the_token_is_empty() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_request_with_query(
             "stats",
             Query::params([QueryParam::new("token", "")].to_vec()),
@@ -81,6 +84,7 @@ async fn should_not_authenticate_requests_when_the_token_is_invalid() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_request_with_query(
             "stats",
             Query::params([QueryParam::new("token", "INVALID TOKEN")].to_vec()),
@@ -108,6 +112,7 @@ async fn should_allow_the_token_query_param_to_be_at_any_position_in_the_url_que
 
     // At the beginning of the query component
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_request(&format!("torrents?token={token}&limit=1"))
         .await;
 
@@ -115,6 +120,7 @@ async fn should_allow_the_token_query_param_to_be_at_any_position_in_the_url_que
 
     // At the end of the query component
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_request(&format!("torrents?limit=1&token={token}"))
         .await;
 
diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs
index f6355fc6e..3781f4f60 100644
--- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs
+++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs
@@ -25,6 +25,7 @@ async fn should_allow_generating_a_new_random_auth_key() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .add_auth_key(
             AddKeyForm {
                 opt_key: None,
@@ -56,6 +57,7 @@ async fn should_allow_uploading_a_preexisting_auth_key() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .add_auth_key(
             AddKeyForm {
                 opt_key: Some("Xc1L4PbQJSFGlrgSRZl8wxSFAuMa21z5".to_string()),
@@ -87,6 +89,7 @@ async fn should_not_allow_generating_a_new_auth_key_for_unauthenticated_users()
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .add_auth_key(
             AddKeyForm {
                 opt_key: None,
@@ -106,6 +109,7 @@ async fn should_not_allow_generating_a_new_auth_key_for_unauthenticated_users()
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .add_auth_key(
             AddKeyForm {
                 opt_key: None,
@@ -136,6 +140,7 @@ async fn should_fail_when_the_auth_key_cannot_be_generated() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .add_auth_key(
             AddKeyForm {
                 opt_key: None,
@@ -173,6 +178,7 @@ async fn should_allow_deleting_an_auth_key() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -207,6 +213,7 @@ async fn should_fail_generating_a_new_auth_key_when_the_provided_key_is_invalid(
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .post_form(
                 "keys",
                 &InvalidAddKeyForm {
@@ -246,6 +253,7 @@ async fn should_fail_generating_a_new_auth_key_when_the_key_duration_is_invalid(
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .post_form(
                 "keys",
                 &InvalidAddKeyForm {
@@ -282,6 +290,7 @@ async fn should_fail_deleting_an_auth_key_when_the_key_id_is_invalid() {
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .delete_auth_key(invalid_auth_key, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -311,6 +320,7 @@ async fn should_fail_when_the_auth_key_cannot_be_deleted() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -344,6 +354,7 @@ async fn should_not_allow_deleting_an_auth_key_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -366,6 +377,7 @@ async fn should_not_allow_deleting_an_auth_key_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -396,6 +408,7 @@ async fn should_allow_reloading_keys() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .reload_keys(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -423,6 +436,7 @@ async fn should_fail_when_keys_cannot_be_reloaded() {
     force_database_error(&env.container.tracker_core_container.database);
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .reload_keys(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -453,6 +467,7 @@ async fn should_not_allow_reloading_keys_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .reload_keys(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -466,6 +481,7 @@ async fn should_not_allow_reloading_keys_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .reload_keys(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -504,6 +520,7 @@ mod deprecated_generate_key_endpoint {
         let seconds_valid = 60;
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .generate_auth_key(seconds_valid, None)
             .await;
 
@@ -530,12 +547,14 @@ mod deprecated_generate_key_endpoint {
         let seconds_valid = 60;
 
         let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+            .unwrap()
             .generate_auth_key(seconds_valid, Some(headers_with_request_id(request_id)))
             .await;
 
         assert_token_not_valid(response).await;
 
         let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+            .unwrap()
             .generate_auth_key(seconds_valid, None)
             .await;
 
@@ -563,6 +582,7 @@ mod deprecated_generate_key_endpoint {
 
         for invalid_key_duration in invalid_key_durations {
             let response = Client::new(env.get_connection_info())
+                .unwrap()
                 .post_empty(&format!("key/{invalid_key_duration}"), None)
                 .await;
 
@@ -583,6 +603,7 @@ mod deprecated_generate_key_endpoint {
         let request_id = Uuid::new_v4();
         let seconds_valid = 60;
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .generate_auth_key(seconds_valid, Some(headers_with_request_id(request_id)))
             .await;
 
diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs
index 1e66eb4cc..51a4804e7 100644
--- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs
+++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs
@@ -26,6 +26,7 @@ async fn should_allow_getting_tracker_statistics() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_tracker_statistics(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -80,6 +81,7 @@ async fn should_not_allow_getting_tracker_statistics_for_unauthenticated_users()
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .get_tracker_statistics(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -93,6 +95,7 @@ async fn should_not_allow_getting_tracker_statistics_for_unauthenticated_users()
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .get_tracker_statistics(Some(headers_with_request_id(request_id)))
         .await;
 
diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs
index b479416e4..42421db99 100644
--- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs
+++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs
@@ -31,6 +31,7 @@ async fn should_allow_getting_all_torrents() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_torrents(Query::empty(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -64,6 +65,7 @@ async fn should_allow_limiting_the_torrents_in_the_result() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_torrents(
             Query::params([QueryParam::new("limit", "1")].to_vec()),
             Some(headers_with_request_id(request_id)),
@@ -100,6 +102,7 @@ async fn should_allow_the_torrents_result_pagination() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_torrents(
             Query::params([QueryParam::new("offset", "1")].to_vec()),
             Some(headers_with_request_id(request_id)),
@@ -135,6 +138,7 @@ async fn should_allow_getting_a_list_of_torrents_providing_infohashes() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_torrents(
             Query::params(
                 [
@@ -181,6 +185,7 @@ async fn should_fail_getting_torrents_when_the_offset_query_parameter_cannot_be_
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .get_torrents(
                 Query::params([QueryParam::new("offset", invalid_offset)].to_vec()),
                 Some(headers_with_request_id(request_id)),
@@ -209,6 +214,7 @@ async fn should_fail_getting_torrents_when_the_limit_query_parameter_cannot_be_p
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .get_torrents(
                 Query::params([QueryParam::new("limit", invalid_limit)].to_vec()),
                 Some(headers_with_request_id(request_id)),
@@ -237,6 +243,7 @@ async fn should_fail_getting_torrents_when_the_info_hash_parameter_is_invalid()
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .get_torrents(
                 Query::params([QueryParam::new("info_hash", invalid_info_hash)].to_vec()),
                 Some(headers_with_request_id(request_id)),
@@ -262,6 +269,7 @@ async fn should_not_allow_getting_torrents_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .get_torrents(Query::empty(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -275,6 +283,7 @@ async fn should_not_allow_getting_torrents_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .get_torrents(Query::default(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -303,6 +312,7 @@ async fn should_allow_getting_a_torrent_info() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -331,6 +341,7 @@ async fn should_fail_while_getting_a_torrent_info_when_the_torrent_does_not_exis
     let info_hash = InfoHash::from_str("9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d").unwrap(); // DevSkim: ignore DS173237
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -349,6 +360,7 @@ async fn should_fail_getting_a_torrent_info_when_the_provided_infohash_is_invali
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .get_torrent(invalid_infohash, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -359,6 +371,7 @@ async fn should_fail_getting_a_torrent_info_when_the_provided_infohash_is_invali
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .get_torrent(invalid_infohash, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -381,6 +394,7 @@ async fn should_not_allow_getting_a_torrent_info_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
@@ -394,6 +408,7 @@ async fn should_not_allow_getting_a_torrent_info_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id)))
         .await;
 
diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs
index e8f98b8ab..61fc233d0 100644
--- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs
+++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs
@@ -25,6 +25,7 @@ async fn should_allow_whitelisting_a_torrent() {
     let info_hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); // DevSkim: ignore DS173237
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -48,7 +49,7 @@ async fn should_allow_whitelisting_a_torrent_that_has_been_already_whitelisted()
 
     let info_hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); // DevSkim: ignore DS173237
 
-    let api_client = Client::new(env.get_connection_info());
+    let api_client = Client::new(env.get_connection_info()).unwrap();
 
     let request_id = Uuid::new_v4();
 
@@ -78,6 +79,7 @@ async fn should_not_allow_whitelisting_a_torrent_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -91,6 +93,7 @@ async fn should_not_allow_whitelisting_a_torrent_for_unauthenticated_users() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -117,6 +120,7 @@ async fn should_fail_when_the_torrent_cannot_be_whitelisted() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -140,6 +144,7 @@ async fn should_fail_whitelisting_a_torrent_when_the_provided_infohash_is_invali
 
     for invalid_infohash in &invalid_infohashes_returning_bad_request() {
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .whitelist_a_torrent(invalid_infohash, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -150,6 +155,7 @@ async fn should_fail_whitelisting_a_torrent_when_the_provided_infohash_is_invali
 
     for invalid_infohash in &invalid_infohashes_returning_not_found() {
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .whitelist_a_torrent(invalid_infohash, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -178,6 +184,7 @@ async fn should_allow_removing_a_torrent_from_the_whitelist() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -204,6 +211,7 @@ async fn should_not_fail_trying_to_remove_a_non_whitelisted_torrent_from_the_whi
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .remove_torrent_from_whitelist(&non_whitelisted_torrent_hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -222,6 +230,7 @@ async fn should_fail_removing_a_torrent_from_the_whitelist_when_the_provided_inf
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .remove_torrent_from_whitelist(invalid_infohash, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -232,6 +241,7 @@ async fn should_fail_removing_a_torrent_from_the_whitelist_when_the_provided_inf
         let request_id = Uuid::new_v4();
 
         let response = Client::new(env.get_connection_info())
+            .unwrap()
             .remove_torrent_from_whitelist(invalid_infohash, Some(headers_with_request_id(request_id)))
             .await;
 
@@ -261,6 +271,7 @@ async fn should_fail_when_the_torrent_cannot_be_removed_from_the_whitelist() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -293,6 +304,7 @@ async fn should_not_allow_removing_a_torrent_from_the_whitelist_for_unauthentica
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin))
+        .unwrap()
         .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -313,6 +325,7 @@ async fn should_not_allow_removing_a_torrent_from_the_whitelist_for_unauthentica
     let request_id = Uuid::new_v4();
 
     let response = Client::new(connection_with_no_token(env.get_connection_info().origin))
+        .unwrap()
         .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id)))
         .await;
 
@@ -334,6 +347,7 @@ async fn should_allow_reload_the_whitelist_from_the_database() {
 
     let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); // DevSkim: ignore DS173237
     let info_hash = InfoHash::from_str(&hash).unwrap();
+
     env.container
         .tracker_core_container
         .whitelist_manager
@@ -344,6 +358,7 @@ async fn should_allow_reload_the_whitelist_from_the_database() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .reload_whitelist(Some(headers_with_request_id(request_id)))
         .await;
 
@@ -382,6 +397,7 @@ async fn should_fail_when_the_whitelist_cannot_be_reloaded_from_the_database() {
     let request_id = Uuid::new_v4();
 
     let response = Client::new(env.get_connection_info())
+        .unwrap()
         .reload_whitelist(Some(headers_with_request_id(request_id)))
         .await;
 
diff --git a/packages/rest-tracker-api-client/src/v1/client.rs b/packages/rest-tracker-api-client/src/v1/client.rs
index 54daa3289..65e3fceb8 100644
--- a/packages/rest-tracker-api-client/src/v1/client.rs
+++ b/packages/rest-tracker-api-client/src/v1/client.rs
@@ -1,5 +1,7 @@
+use std::time::Duration;
+
 use hyper::HeaderMap;
-use reqwest::Response;
+use reqwest::{Error, Response};
 use serde::Serialize;
 use url::Url;
 use uuid::Uuid;
@@ -7,19 +9,31 @@ use uuid::Uuid;
 use crate::common::http::{Query, QueryParam, ReqwestQuery};
 use crate::connection_info::ConnectionInfo;
 
+const TOKEN_PARAM_NAME: &str = "token";
+const API_PATH: &str = "api/v1/";
+const DEFAULT_REQUEST_TIMEOUT_IN_SECS: u64 = 5;
+
 /// API Client
 pub struct Client {
     connection_info: ConnectionInfo,
     base_path: String,
+    client: reqwest::Client,
 }
 
 impl Client {
-    #[must_use]
-    pub fn new(connection_info: ConnectionInfo) -> Self {
-        Self {
+    /// # Errors
+    ///
+    /// Will return an error if the HTTP client can't be created.
+    pub fn new(connection_info: ConnectionInfo) -> Result<Self, Error> {
+        let client = reqwest::Client::builder()
+            .timeout(Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_IN_SECS))
+            .build()?;
+
+        Ok(Self {
             connection_info,
-            base_path: "api/v1/".to_string(),
-        }
+            base_path: API_PATH.to_string(),
+            client,
+        })
     }
 
     pub async fn generate_auth_key(&self, seconds_valid: i32, headers: Option<HeaderMap>) -> Response {
@@ -66,7 +80,7 @@ impl Client {
         let mut query: Query = params;
 
         if let Some(token) = &self.connection_info.api_token {
-            query.add_param(QueryParam::new("token", token));
+            query.add_param(QueryParam::new(TOKEN_PARAM_NAME, token));
         }
 
         self.get_request_with_query(path, query, headers).await
@@ -76,7 +90,8 @@ impl Client {
     ///
     /// Will panic if the request can't be sent
     pub async fn post_empty(&self, path: &str, headers: Option<HeaderMap>) -> Response {
-        let builder = reqwest::Client::new()
+        let builder = self
+            .client
             .post(self.base_url(path).clone())
             .query(&ReqwestQuery::from(self.query_with_token()));
 
@@ -92,7 +107,8 @@ impl Client {
     ///
     /// Will panic if the request can't be sent
     pub async fn post_form<T: Serialize + ?Sized>(&self, path: &str, form: &T, headers: Option<HeaderMap>) -> Response {
-        let builder = reqwest::Client::new()
+        let builder = self
+            .client
             .post(self.base_url(path).clone())
             .query(&ReqwestQuery::from(self.query_with_token()))
             .json(&form);
@@ -109,7 +125,8 @@ impl Client {
     ///
     /// Will panic if the request can't be sent
     async fn delete(&self, path: &str, headers: Option<HeaderMap>) -> Response {
-        let builder = reqwest::Client::new()
+        let builder = self
+            .client
             .delete(self.base_url(path).clone())
             .query(&ReqwestQuery::from(self.query_with_token()));
 
@@ -145,7 +162,10 @@ impl Client {
 ///
 /// Will panic if the request can't be sent
 pub async fn get(path: Url, query: Option<Query>, headers: Option<HeaderMap>) -> Response {
-    let builder = reqwest::Client::builder().build().unwrap();
+    let builder = reqwest::Client::builder()
+        .timeout(Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_IN_SECS))
+        .build()
+        .unwrap();
 
     let builder = match query {
         Some(params) => builder.get(path).query(&ReqwestQuery::from(params)),