diff --git a/packages/axum-rest-tracker-api-server/src/v1/middlewares/auth.rs b/packages/axum-rest-tracker-api-server/src/v1/middlewares/auth.rs
index 2ec046bed..9b5ec2320 100644
--- a/packages/axum-rest-tracker-api-server/src/v1/middlewares/auth.rs
+++ b/packages/axum-rest-tracker-api-server/src/v1/middlewares/auth.rs
@@ -1,7 +1,20 @@
 //! Authentication middleware for the API.
 //!
-//! It uses a "token" GET param to authenticate the user. URLs must be of the
-//! form:
+//! It uses a "token" to authenticate the user. The token must be one of the
+//! `access_tokens` in the tracker [HTTP API configuration](torrust_tracker_configuration::HttpApi).
+//!
+//! There are two ways to provide the token:
+//!
+//! 1. As a `Bearer` token in the `Authorization` header.
+//! 2. As a `token` GET param in the URL.
+//!
+//! Using the `Authorization` header:
+//!
+//! ```console
+//! curl -H "Authorization: Bearer MyAccessToken" http://<host>:<port>/api/v1/<context>
+//! ```
+//!
+//! Using the `token` GET param:
 //!
 //! `http://<host>:<port>/api/v1/<context>?token=<token>`.
 //!
@@ -21,6 +34,12 @@
 //! All the tokes have the same permissions, so it is not possible to have
 //! different permissions for different tokens. The label is only used to
 //! identify the token.
+//!
+//! NOTICE: The token is not encrypted, so it is recommended to use HTTPS to
+//! protect the token from being intercepted.
+//!
+//! NOTICE: If both the `Authorization` header and the `token` GET param are
+//! provided, the `Authorization` header will be used.
 use std::sync::Arc;
 
 use axum::extract::{self};
@@ -32,6 +51,8 @@ use torrust_tracker_configuration::AccessTokens;
 
 use crate::v1::responses::unhandled_rejection_response;
 
+pub const AUTH_BEARER_TOKEN_HEADER_PREFIX: &str = "Bearer";
+
 /// Container for the `token` extracted from the query params.
 #[derive(Deserialize, Debug)]
 pub struct QueryParams {
@@ -43,7 +64,8 @@ pub struct State {
     pub access_tokens: Arc<AccessTokens>,
 }
 
-/// Middleware for authentication using a "token" GET param.
+/// Middleware for authentication.
+///
 /// The token must be one of the tokens in the tracker [HTTP API configuration](torrust_tracker_configuration::HttpApi).
 pub async fn auth(
     extract::State(state): extract::State<State>,
@@ -51,8 +73,20 @@ pub async fn auth(
     request: Request<axum::body::Body>,
     next: Next,
 ) -> Response {
-    let Some(token) = params.token else {
-        return AuthError::Unauthorized.into_response();
+    let token_from_header = match extract_bearer_token_from_header(&request) {
+        Ok(token) => token,
+        Err(err) => return err.into_response(),
+    };
+
+    let token_from_get_param = params.token.clone();
+
+    let provided_tokens = (token_from_header, token_from_get_param);
+
+    let token = match provided_tokens {
+        (Some(token_from_header), Some(_token_from_get_param)) => token_from_header,
+        (Some(token_from_header), None) => token_from_header,
+        (None, Some(token_from_get_param)) => token_from_get_param,
+        (None, None) => return AuthError::Unauthorized.into_response(),
     };
 
     if !authenticate(&token, &state.access_tokens) {
@@ -62,11 +96,42 @@ pub async fn auth(
     next.run(request).await
 }
 
+fn extract_bearer_token_from_header(request: &Request<axum::body::Body>) -> Result<Option<String>, AuthError> {
+    let headers = request.headers();
+
+    let header_value = headers
+        .get(axum::http::header::AUTHORIZATION)
+        .and_then(|header_value| header_value.to_str().ok());
+
+    match header_value {
+        None => Ok(None),
+        Some(header_value) => {
+            if header_value == AUTH_BEARER_TOKEN_HEADER_PREFIX {
+                // Empty token
+                return Ok(Some(String::new()));
+            }
+
+            if !header_value.starts_with(&format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} ").to_string()) {
+                // Invalid token type. Missing "Bearer" prefix.
+                return Err(AuthError::UnknownTokenProvided);
+            }
+
+            Ok(header_value
+                .strip_prefix(&format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} ").to_string())
+                .map(std::string::ToString::to_string))
+        }
+    }
+}
+
 enum AuthError {
     /// Missing token for authentication.
     Unauthorized,
+
     /// Token was provided but it is not valid.
     TokenNotValid,
+
+    /// Token was provided but it is not in a format that the server can't understands.
+    UnknownTokenProvided,
 }
 
 impl IntoResponse for AuthError {
@@ -74,6 +139,7 @@ impl IntoResponse for AuthError {
         match self {
             AuthError::Unauthorized => unauthorized_response(),
             AuthError::TokenNotValid => token_not_valid_response(),
+            AuthError::UnknownTokenProvided => unknown_auth_data_provided_response(),
         }
     }
 }
@@ -93,3 +159,12 @@ pub fn unauthorized_response() -> Response {
 pub fn token_not_valid_response() -> Response {
     unhandled_rejection_response("token not valid".to_string())
 }
+
+/// `500` error response when the provided token type is not valid.
+///
+/// The client has provided authentication information that the server does not
+/// understand.
+#[must_use]
+pub fn unknown_auth_data_provided_response() -> Response {
+    unhandled_rejection_response("unknown token provided".to_string())
+}
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 3b6419187..be291a50c 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
@@ -1,130 +1,294 @@
-use torrust_axum_rest_tracker_api_server::environment::Started;
-use torrust_rest_tracker_api_client::common::http::{Query, QueryParam};
-use torrust_rest_tracker_api_client::v1::client::{headers_with_request_id, Client};
-use torrust_tracker_test_helpers::logging::logs_contains_a_line_with;
-use torrust_tracker_test_helpers::{configuration, logging};
-use uuid::Uuid;
+mod given_that_the_token_is_only_provided_in_the_authentication_header {
+    use hyper::header;
+    use torrust_axum_rest_tracker_api_server::environment::Started;
+    use torrust_rest_tracker_api_client::common::http::Query;
+    use torrust_rest_tracker_api_client::connection_info::ConnectionInfo;
+    use torrust_rest_tracker_api_client::v1::client::{
+        headers_with_auth_token, headers_with_request_id, Client, AUTH_BEARER_TOKEN_HEADER_PREFIX,
+    };
+    use torrust_tracker_test_helpers::logging::logs_contains_a_line_with;
+    use torrust_tracker_test_helpers::{configuration, logging};
+    use uuid::Uuid;
 
-use crate::server::v1::asserts::{assert_token_not_valid, assert_unauthorized};
+    use crate::server::v1::asserts::assert_token_not_valid;
 
-#[tokio::test]
-async fn should_authenticate_requests_by_using_a_token_query_param() {
-    logging::setup();
+    #[tokio::test]
+    async fn it_should_authenticate_requests_when_the_token_is_provided_in_the_authentication_header() {
+        logging::setup();
 
-    let env = Started::new(&configuration::ephemeral().into()).await;
+        let env = Started::new(&configuration::ephemeral().into()).await;
 
-    let token = env.get_connection_info().api_token.unwrap();
+        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;
+        let response = Client::new(env.get_connection_info())
+            .unwrap()
+            .get_request_with_query("stats", Query::default(), Some(headers_with_auth_token(&token)))
+            .await;
 
-    assert_eq!(response.status(), 200);
+        assert_eq!(response.status(), 200);
 
-    env.stop().await;
-}
+        env.stop().await;
+    }
+
+    #[tokio::test]
+    async fn it_should_not_authenticate_requests_when_the_token_is_empty() {
+        logging::setup();
+
+        let env = Started::new(&configuration::ephemeral().into()).await;
+
+        let request_id = Uuid::new_v4();
+
+        let mut headers = headers_with_request_id(request_id);
+
+        // Send the header with an empty token
+        headers.insert(
+            header::AUTHORIZATION,
+            format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} ")
+                .parse()
+                .expect("the auth token is not a valid header value"),
+        );
+
+        let response = Client::new(env.get_connection_info())
+            .unwrap()
+            .get_request_with_query("stats", Query::default(), Some(headers))
+            .await;
+
+        assert_token_not_valid(response).await;
+
+        assert!(
+            logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
+            "Expected logs to contain: ERROR ... API ... request_id={request_id}"
+        );
+
+        env.stop().await;
+    }
+
+    #[tokio::test]
+    async fn it_should_not_authenticate_requests_when_the_token_is_invalid() {
+        logging::setup();
 
-#[tokio::test]
-async fn should_not_authenticate_requests_when_the_token_is_missing() {
-    logging::setup();
+        let env = Started::new(&configuration::ephemeral().into()).await;
 
-    let env = Started::new(&configuration::ephemeral().into()).await;
+        let request_id = Uuid::new_v4();
 
-    let request_id = Uuid::new_v4();
+        let mut headers = headers_with_request_id(request_id);
 
-    let response = Client::new(env.get_connection_info())
-        .unwrap()
-        .get_request_with_query("stats", Query::default(), Some(headers_with_request_id(request_id)))
-        .await;
+        // Send the header with an empty token
+        headers.insert(
+            header::AUTHORIZATION,
+            "Bearer INVALID TOKEN"
+                .parse()
+                .expect("the auth token is not a valid header value"),
+        );
 
-    assert_unauthorized(response).await;
+        let connection_info = ConnectionInfo::anonymous(env.get_connection_info().origin);
 
-    assert!(
-        logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
-        "Expected logs to contain: ERROR ... API ... request_id={request_id}"
-    );
+        let response = Client::new(connection_info)
+            .unwrap()
+            .get_request_with_query("stats", Query::default(), Some(headers))
+            .await;
 
-    env.stop().await;
+        assert_token_not_valid(response).await;
+
+        assert!(
+            logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
+            "Expected logs to contain: ERROR ... API ... request_id={request_id}"
+        );
+
+        env.stop().await;
+    }
 }
+mod given_that_the_token_is_only_provided_in_the_query_param {
+
+    use torrust_axum_rest_tracker_api_server::environment::Started;
+    use torrust_rest_tracker_api_client::common::http::{Query, QueryParam};
+    use torrust_rest_tracker_api_client::connection_info::ConnectionInfo;
+    use torrust_rest_tracker_api_client::v1::client::{headers_with_request_id, Client, TOKEN_PARAM_NAME};
+    use torrust_tracker_test_helpers::logging::logs_contains_a_line_with;
+    use torrust_tracker_test_helpers::{configuration, logging};
+    use uuid::Uuid;
+
+    use crate::server::v1::asserts::assert_token_not_valid;
+
+    #[tokio::test]
+    async fn it_should_authenticate_requests_when_the_token_is_provided_as_a_query_param() {
+        logging::setup();
+
+        let env = Started::new(&configuration::ephemeral().into()).await;
+
+        let token = env.get_connection_info().api_token.unwrap();
+
+        let connection_info = ConnectionInfo::anonymous(env.get_connection_info().origin);
+
+        let response = Client::new(connection_info)
+            .unwrap()
+            .get_request_with_query(
+                "stats",
+                Query::params([QueryParam::new(TOKEN_PARAM_NAME, &token)].to_vec()),
+                None,
+            )
+            .await;
+
+        assert_eq!(response.status(), 200);
+
+        env.stop().await;
+    }
 
-#[tokio::test]
-async fn should_not_authenticate_requests_when_the_token_is_empty() {
-    logging::setup();
+    #[tokio::test]
+    async fn it_should_not_authenticate_requests_when_the_token_is_empty() {
+        logging::setup();
 
-    let env = Started::new(&configuration::ephemeral().into()).await;
+        let env = Started::new(&configuration::ephemeral().into()).await;
 
-    let request_id = Uuid::new_v4();
+        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()),
-            Some(headers_with_request_id(request_id)),
-        )
-        .await;
+        let connection_info = ConnectionInfo::anonymous(env.get_connection_info().origin);
 
-    assert_token_not_valid(response).await;
+        let response = Client::new(connection_info)
+            .unwrap()
+            .get_request_with_query(
+                "stats",
+                Query::params([QueryParam::new(TOKEN_PARAM_NAME, "")].to_vec()),
+                Some(headers_with_request_id(request_id)),
+            )
+            .await;
 
-    assert!(
-        logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
-        "Expected logs to contain: ERROR ... API ... request_id={request_id}"
-    );
+        assert_token_not_valid(response).await;
 
-    env.stop().await;
+        assert!(
+            logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
+            "Expected logs to contain: ERROR ... API ... request_id={request_id}"
+        );
+
+        env.stop().await;
+    }
+
+    #[tokio::test]
+    async fn it_should_not_authenticate_requests_when_the_token_is_invalid() {
+        logging::setup();
+
+        let env = Started::new(&configuration::ephemeral().into()).await;
+
+        let request_id = Uuid::new_v4();
+
+        let connection_info = ConnectionInfo::anonymous(env.get_connection_info().origin);
+
+        let response = Client::new(connection_info)
+            .unwrap()
+            .get_request_with_query(
+                "stats",
+                Query::params([QueryParam::new(TOKEN_PARAM_NAME, "INVALID TOKEN")].to_vec()),
+                Some(headers_with_request_id(request_id)),
+            )
+            .await;
+
+        assert_token_not_valid(response).await;
+
+        assert!(
+            logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
+            "Expected logs to contain: ERROR ... API ... request_id={request_id}"
+        );
+
+        env.stop().await;
+    }
+
+    #[tokio::test]
+    async fn it_should_allow_the_token_query_param_to_be_at_any_position_in_the_url_query() {
+        logging::setup();
+
+        let env = Started::new(&configuration::ephemeral().into()).await;
+
+        let token = env.get_connection_info().api_token.unwrap();
+
+        let connection_info = ConnectionInfo::anonymous(env.get_connection_info().origin);
+
+        // At the beginning of the query component
+        let response = Client::new(connection_info)
+            .unwrap()
+            .get_request(&format!("torrents?token={token}&limit=1"))
+            .await;
+
+        assert_eq!(response.status(), 200);
+
+        // 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;
+
+        assert_eq!(response.status(), 200);
+
+        env.stop().await;
+    }
 }
 
-#[tokio::test]
-async fn should_not_authenticate_requests_when_the_token_is_invalid() {
-    logging::setup();
+mod given_that_not_token_is_provided {
+
+    use torrust_axum_rest_tracker_api_server::environment::Started;
+    use torrust_rest_tracker_api_client::common::http::Query;
+    use torrust_rest_tracker_api_client::connection_info::ConnectionInfo;
+    use torrust_rest_tracker_api_client::v1::client::{headers_with_request_id, Client};
+    use torrust_tracker_test_helpers::logging::logs_contains_a_line_with;
+    use torrust_tracker_test_helpers::{configuration, logging};
+    use uuid::Uuid;
+
+    use crate::server::v1::asserts::assert_unauthorized;
+
+    #[tokio::test]
+    async fn it_should_not_authenticate_requests_when_the_token_is_missing() {
+        logging::setup();
+
+        let env = Started::new(&configuration::ephemeral().into()).await;
 
-    let env = Started::new(&configuration::ephemeral().into()).await;
+        let request_id = Uuid::new_v4();
 
-    let request_id = Uuid::new_v4();
+        let connection_info = ConnectionInfo::anonymous(env.get_connection_info().origin);
 
-    let response = Client::new(env.get_connection_info())
-        .unwrap()
-        .get_request_with_query(
-            "stats",
-            Query::params([QueryParam::new("token", "INVALID TOKEN")].to_vec()),
-            Some(headers_with_request_id(request_id)),
-        )
-        .await;
+        let response = Client::new(connection_info)
+            .unwrap()
+            .get_request_with_query("stats", Query::default(), Some(headers_with_request_id(request_id)))
+            .await;
 
-    assert_token_not_valid(response).await;
+        assert_unauthorized(response).await;
 
-    assert!(
-        logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
-        "Expected logs to contain: ERROR ... API ... request_id={request_id}"
-    );
+        assert!(
+            logs_contains_a_line_with(&["ERROR", "API", &format!("{request_id}")]),
+            "Expected logs to contain: ERROR ... API ... request_id={request_id}"
+        );
 
-    env.stop().await;
+        env.stop().await;
+    }
 }
 
-#[tokio::test]
-async fn should_allow_the_token_query_param_to_be_at_any_position_in_the_url_query() {
-    logging::setup();
+mod given_that_token_is_provided_via_get_param_and_authentication_header {
+    use torrust_axum_rest_tracker_api_server::environment::Started;
+    use torrust_rest_tracker_api_client::common::http::{Query, QueryParam};
+    use torrust_rest_tracker_api_client::v1::client::{headers_with_auth_token, Client, TOKEN_PARAM_NAME};
+    use torrust_tracker_test_helpers::{configuration, logging};
 
-    let env = Started::new(&configuration::ephemeral().into()).await;
+    #[tokio::test]
+    async fn it_should_authenticate_requests_using_the_token_provided_in_the_authentication_header() {
+        logging::setup();
 
-    let token = env.get_connection_info().api_token.unwrap();
+        let env = Started::new(&configuration::ephemeral().into()).await;
 
-    // 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;
+        let authorized_token = env.get_connection_info().api_token.unwrap();
 
-    assert_eq!(response.status(), 200);
+        let non_authorized_token = "NonAuthorizedToken";
 
-    // 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;
+        let response = Client::new(env.get_connection_info())
+            .unwrap()
+            .get_request_with_query(
+                "stats",
+                Query::params([QueryParam::new(TOKEN_PARAM_NAME, non_authorized_token)].to_vec()),
+                Some(headers_with_auth_token(&authorized_token)),
+            )
+            .await;
 
-    assert_eq!(response.status(), 200);
+        // The token provided in the query param should be ignored and the token
+        // in the authentication header should be used.
+        assert_eq!(response.status(), 200);
 
-    env.stop().await;
+        env.stop().await;
+    }
 }
diff --git a/packages/rest-tracker-api-client/src/v1/client.rs b/packages/rest-tracker-api-client/src/v1/client.rs
index 65e3fceb8..da1b709da 100644
--- a/packages/rest-tracker-api-client/src/v1/client.rs
+++ b/packages/rest-tracker-api-client/src/v1/client.rs
@@ -1,6 +1,6 @@
 use std::time::Duration;
 
-use hyper::HeaderMap;
+use hyper::{header, HeaderMap};
 use reqwest::{Error, Response};
 use serde::Serialize;
 use url::Url;
@@ -9,7 +9,9 @@ use uuid::Uuid;
 use crate::common::http::{Query, QueryParam, ReqwestQuery};
 use crate::connection_info::ConnectionInfo;
 
-const TOKEN_PARAM_NAME: &str = "token";
+pub const TOKEN_PARAM_NAME: &str = "token";
+pub const AUTH_BEARER_TOKEN_HEADER_PREFIX: &str = "Bearer";
+
 const API_PATH: &str = "api/v1/";
 const DEFAULT_REQUEST_TIMEOUT_IN_SECS: u64 = 5;
 
@@ -90,16 +92,18 @@ 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 = self
-            .client
-            .post(self.base_url(path).clone())
-            .query(&ReqwestQuery::from(self.query_with_token()));
+        let builder = self.client.post(self.base_url(path).clone());
 
         let builder = match headers {
             Some(headers) => builder.headers(headers),
             None => builder,
         };
 
+        let builder = match &self.connection_info.api_token {
+            Some(token) => builder.header(header::AUTHORIZATION, format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} {token}")),
+            None => builder,
+        };
+
         builder.send().await.unwrap()
     }
 
@@ -107,17 +111,18 @@ 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 = self
-            .client
-            .post(self.base_url(path).clone())
-            .query(&ReqwestQuery::from(self.query_with_token()))
-            .json(&form);
+        let builder = self.client.post(self.base_url(path).clone()).json(&form);
 
         let builder = match headers {
             Some(headers) => builder.headers(headers),
             None => builder,
         };
 
+        let builder = match &self.connection_info.api_token {
+            Some(token) => builder.header(header::AUTHORIZATION, format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} {token}")),
+            None => builder,
+        };
+
         builder.send().await.unwrap()
     }
 
@@ -125,34 +130,70 @@ impl Client {
     ///
     /// Will panic if the request can't be sent
     async fn delete(&self, path: &str, headers: Option<HeaderMap>) -> Response {
-        let builder = self
-            .client
-            .delete(self.base_url(path).clone())
-            .query(&ReqwestQuery::from(self.query_with_token()));
+        let builder = self.client.delete(self.base_url(path).clone());
 
         let builder = match headers {
             Some(headers) => builder.headers(headers),
             None => builder,
         };
 
+        let builder = match &self.connection_info.api_token {
+            Some(token) => builder.header(header::AUTHORIZATION, format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} {token}")),
+            None => builder,
+        };
+
         builder.send().await.unwrap()
     }
 
+    /// # Panics
+    ///
+    /// Will panic if it can't convert the authentication token to a `HeaderValue`.
     pub async fn get_request_with_query(&self, path: &str, params: Query, headers: Option<HeaderMap>) -> Response {
-        get(self.base_url(path), Some(params), headers).await
+        match &self.connection_info.api_token {
+            Some(token) => {
+                let headers = if let Some(headers) = headers {
+                    // Headers provided -> add auth token if not already present
+
+                    if headers.get(header::AUTHORIZATION).is_some() {
+                        // Auth token already present -> use provided
+                        headers
+                    } else {
+                        let mut headers = headers;
+
+                        headers.insert(
+                            header::AUTHORIZATION,
+                            format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} {token}")
+                                .parse()
+                                .expect("the auth token is not a valid header value"),
+                        );
+
+                        headers
+                    }
+                } else {
+                    // No headers provided -> create headers with auth token
+
+                    let mut headers = HeaderMap::new();
+
+                    headers.insert(
+                        header::AUTHORIZATION,
+                        format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} {token}")
+                            .parse()
+                            .expect("the auth token is not a valid header value"),
+                    );
+
+                    headers
+                };
+
+                get(self.base_url(path), Some(params), Some(headers)).await
+            }
+            None => get(self.base_url(path), Some(params), headers).await,
+        }
     }
 
     pub async fn get_request(&self, path: &str) -> Response {
         get(self.base_url(path), None, None).await
     }
 
-    fn query_with_token(&self) -> Query {
-        match &self.connection_info.api_token {
-            Some(token) => Query::params([QueryParam::new("token", token)].to_vec()),
-            None => Query::default(),
-        }
-    }
-
     fn base_url(&self, path: &str) -> Url {
         Url::parse(&format!("{}{}{path}", &self.connection_info.origin, &self.base_path)).unwrap()
     }
@@ -180,15 +221,38 @@ pub async fn get(path: Url, query: Option<Query>, headers: Option<HeaderMap>) ->
     builder.send().await.unwrap()
 }
 
-/// Returns a `HeaderMap` with a request id header
+/// Returns a `HeaderMap` with a request id header.
 ///
 /// # Panics
 ///
-/// Will panic if the request ID can't be parsed into a string.
+/// Will panic if the request ID can't be parsed into a `HeaderValue`.
 #[must_use]
 pub fn headers_with_request_id(request_id: Uuid) -> HeaderMap {
     let mut headers = HeaderMap::new();
-    headers.insert("x-request-id", request_id.to_string().parse().unwrap());
+    headers.insert(
+        "x-request-id",
+        request_id
+            .to_string()
+            .parse()
+            .expect("the request ID is not a valid header value"),
+    );
+    headers
+}
+
+/// Returns a `HeaderMap` with an authorization token.
+///
+/// # Panics
+///
+/// Will panic if the token can't be parsed into a `HeaderValue`.
+#[must_use]
+pub fn headers_with_auth_token(token: &str) -> HeaderMap {
+    let mut headers = HeaderMap::new();
+    headers.insert(
+        header::AUTHORIZATION,
+        format!("{AUTH_BEARER_TOKEN_HEADER_PREFIX} {token}")
+            .parse()
+            .expect("the auth token is not a valid header value"),
+    );
     headers
 }