diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -1,4 +1,3 @@
-use std::collections::HashMap;
 // Standard library imports
 use std::str::FromStr;
 
@@ -13,12 +12,9 @@
 
 // Workspace crate imports
 use crate::client_service::client_proto::{
-  inbound_keys_for_user_request, outbound_keys_for_user_request,
-  AddReservedUsernamesRequest, Empty, GenerateNonceResponse, InboundKeyInfo,
-  InboundKeysForUserRequest, InboundKeysForUserResponse,
+  AddReservedUsernamesRequest, Empty, GenerateNonceResponse,
   OpaqueLoginFinishRequest, OpaqueLoginFinishResponse, OpaqueLoginStartRequest,
-  OpaqueLoginStartResponse, OutboundKeyInfo, OutboundKeysForUserRequest,
-  OutboundKeysForUserResponse, RegistrationFinishRequest,
+  OpaqueLoginStartResponse, RegistrationFinishRequest,
   RegistrationFinishResponse, RegistrationStartRequest,
   RegistrationStartResponse, RemoveReservedUsernameRequest,
   ReservedRegistrationStartRequest, ReservedWalletLoginRequest,
@@ -30,7 +26,7 @@
   DBDeviceTypeInt, DatabaseClient, DeviceType, KeyPayload,
 };
 use crate::error::Error as DBError;
-use crate::grpc_utils::{DeviceInfoWithAuth, DeviceKeyUploadActions};
+use crate::grpc_utils::DeviceKeyUploadActions;
 use crate::id::generate_uuid;
 use crate::nonce::generate_nonce_data;
 use crate::reserved_users::{
@@ -576,104 +572,6 @@
     }
   }
 
-  async fn get_outbound_keys_for_user(
-    &self,
-    request: tonic::Request<OutboundKeysForUserRequest>,
-  ) -> Result<tonic::Response<OutboundKeysForUserResponse>, tonic::Status> {
-    let message = request.into_inner();
-
-    use outbound_keys_for_user_request::Identifier;
-    let (user_ident, auth_type) = match message.identifier {
-      None => {
-        return Err(tonic::Status::invalid_argument("no identifier provided"))
-      }
-      Some(Identifier::Username(username)) => (username, AuthType::Password),
-      Some(Identifier::WalletAddress(address)) => (address, AuthType::Wallet),
-    };
-
-    let devices_map = self
-      .client
-      .get_keys_for_user_info(user_ident, &auth_type, true)
-      .await
-      .map_err(handle_db_error)?
-      .ok_or_else(|| match auth_type {
-        AuthType::Password => tonic::Status::not_found("username not found"),
-        AuthType::Wallet => {
-          tonic::Status::not_found("wallet address not found")
-        }
-      })?;
-
-    let transformed_devices = devices_map
-      .into_iter()
-      .filter_map(|(key, device_info)| {
-        let device_info_with_auth = DeviceInfoWithAuth {
-          device_info,
-          auth_type: Some(&auth_type),
-        };
-        match OutboundKeyInfo::try_from(device_info_with_auth) {
-          Ok(key_info) => Some((key, key_info)),
-          Err(_) => {
-            error!("Failed to transform device info for key {}", key);
-            None
-          }
-        }
-      })
-      .collect::<HashMap<_, _>>();
-
-    Ok(tonic::Response::new(OutboundKeysForUserResponse {
-      devices: transformed_devices,
-    }))
-  }
-
-  async fn get_inbound_keys_for_user(
-    &self,
-    request: tonic::Request<InboundKeysForUserRequest>,
-  ) -> Result<tonic::Response<InboundKeysForUserResponse>, tonic::Status> {
-    let message = request.into_inner();
-
-    use inbound_keys_for_user_request::Identifier;
-    let (user_ident, auth_type) = match message.identifier {
-      None => {
-        return Err(tonic::Status::invalid_argument("no identifier provided"))
-      }
-      Some(Identifier::Username(username)) => (username, AuthType::Password),
-      Some(Identifier::WalletAddress(address)) => (address, AuthType::Wallet),
-    };
-
-    let devices_map = self
-      .client
-      .get_keys_for_user_info(user_ident, &auth_type, false)
-      .await
-      .map_err(handle_db_error)?
-      .ok_or_else(|| match auth_type {
-        AuthType::Password => tonic::Status::not_found("username not found"),
-        AuthType::Wallet => {
-          tonic::Status::not_found("wallet address not found")
-        }
-      })?;
-
-    let transformed_devices = devices_map
-      .into_iter()
-      .filter_map(|(key, device_info)| {
-        let device_info_with_auth = DeviceInfoWithAuth {
-          device_info,
-          auth_type: Some(&auth_type),
-        };
-        match InboundKeyInfo::try_from(device_info_with_auth) {
-          Ok(key_info) => Some((key, key_info)),
-          Err(_) => {
-            error!("Failed to transform device info for key {}", key);
-            None
-          }
-        }
-      })
-      .collect::<HashMap<_, _>>();
-
-    Ok(tonic::Response::new(InboundKeysForUserResponse {
-      devices: transformed_devices,
-    }))
-  }
-
   async fn verify_user_access_token(
     &self,
     request: tonic::Request<VerifyUserAccessTokenRequest>,
diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs
--- a/services/identity/src/database.rs
+++ b/services/identity/src/database.rs
@@ -951,21 +951,6 @@
     }
   }
 
-  pub async fn get_keys_for_user_info(
-    &self,
-    user_info: String,
-    auth_type: &AuthType,
-    get_one_time_keys: bool,
-  ) -> Result<Option<Devices>, Error> {
-    let Some(user) =
-      self.get_user_from_user_info(user_info, auth_type).await?
-    else {
-      return Ok(None);
-    };
-
-    self.get_keys_for_user(user, get_one_time_keys).await
-  }
-
   pub async fn get_keys_for_user_id(
     &self,
     user_id: &str,
diff --git a/shared/protos/identity_client.proto b/shared/protos/identity_client.proto
--- a/shared/protos/identity_client.proto
+++ b/shared/protos/identity_client.proto
@@ -31,22 +31,6 @@
   // Called by clients to get a nonce for a Sign-In with Ethereum message
   rpc GenerateNonce(Empty) returns (GenerateNonceResponse) {}
 
-  // X3DH actions
-
-  // Called by clients to get all device keys associated with a user in order
-  // to open a new channel of communication on any of their devices.
-  // Specially, this will return the following per device:
-  //   - Identity keys (both Content and Notif Keys)
-  //   - PreKey (including preKey signature)
-  //   - One-time PreKey
-  rpc GetOutboundKeysForUser(OutboundKeysForUserRequest) returns
-    (OutboundKeysForUserResponse) {}
-  // Called by receivers of a communication request. The reponse will only
-  // return identity keys (both content and notif keys) and related prekeys per
-  // device, but will not contain one-time keys.
-  rpc GetInboundKeysForUser(InboundKeysForUserRequest) returns
-    (InboundKeysForUserResponse) {}
-
   // Service actions
 
   // Called by other services to verify a user's access token
@@ -241,16 +225,6 @@
   optional string oneTimeNotifPrekey = 5;
 }
 
-// Information needed by a device to establish communcation when responding
-// to a request.
-// The device receiving a request only needs the content key and prekey.
-message OutboundKeysForUserRequest {
-  oneof identifier {
-    string username = 1;
-    string walletAddress = 2;
-  }
-}
-
 message OutboundKeysForUserResponse {
   // Map is keyed on devices' public ed25519 key used for signing
   map<string, OutboundKeyInfo> devices = 1;
@@ -264,13 +238,6 @@
   PreKey notifPrekey = 3;
 }
 
-message InboundKeysForUserRequest {
-  oneof identifier {
-    string username = 1;
-    string walletAddress = 2;
-  }
-}
-
 message InboundKeysForUserResponse {
   // Map is keyed on devices' public ed25519 key used for signing
   map<string, InboundKeyInfo> devices = 1;