diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h
--- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h
+++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h
@@ -43,7 +43,7 @@
       const std::string &oneTimeKeys);
 
   std::string getIdentityKeys();
-  std::string getOneTimeKeys(size_t oneTimeKeysAmount = 50);
+  std::string getOneTimeKeysForPublishing(size_t oneTimeKeysAmount = 10);
 
   // Prekey rotation methods for X3DH
   std::uint8_t getNumPrekeys();
diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp
--- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp
+++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp
@@ -4,6 +4,8 @@
 #include "olm/account.hh"
 #include "olm/session.hh"
 
+#include <folly/dynamic.h>
+#include <folly/json.h>
 #include <ctime>
 #include <stdexcept>
 
@@ -67,13 +69,12 @@
 }
 
 void CryptoModule::generateOneTimeKeys(size_t oneTimeKeysAmount) {
-  size_t oneTimeKeysSize = ::olm_account_generate_one_time_keys_random_length(
-      this->getOlmAccount(), oneTimeKeysAmount);
-  if (this->keys.oneTimeKeys.size() == oneTimeKeysSize) {
-    return;
-  }
+  size_t numRandomBytesRequired =
+      ::olm_account_generate_one_time_keys_random_length(
+          this->getOlmAccount(), oneTimeKeysAmount);
   OlmBuffer random;
-  PlatformSpecificTools::generateSecureRandomBytes(random, oneTimeKeysSize);
+  PlatformSpecificTools::generateSecureRandomBytes(
+      random, numRandomBytesRequired);
 
   if (-1 ==
       ::olm_account_generate_one_time_keys(
@@ -133,17 +134,34 @@
       this->keys.identityKeys.begin(), this->keys.identityKeys.end()};
 }
 
-std::string CryptoModule::getOneTimeKeys(size_t oneTimeKeysAmount) {
-  this->generateOneTimeKeys(oneTimeKeysAmount);
-  size_t publishedOneTimeKeys = this->publishOneTimeKeys();
-  if (publishedOneTimeKeys != oneTimeKeysAmount) {
+std::string
+CryptoModule::getOneTimeKeysForPublishing(size_t oneTimeKeysAmount) {
+  OlmBuffer unpublishedOneTimeKeys;
+  unpublishedOneTimeKeys.resize(
+      ::olm_account_one_time_keys_length(this->getOlmAccount()));
+  if (-1 ==
+      ::olm_account_one_time_keys(
+          this->getOlmAccount(),
+          unpublishedOneTimeKeys.data(),
+          unpublishedOneTimeKeys.size())) {
     throw std::runtime_error{
-        "error generateKeys => invalid amount of one-time keys published. "
-        "Expected " +
-        std::to_string(oneTimeKeysAmount) + ", got " +
-        std::to_string(publishedOneTimeKeys)};
+        "error getOneTimeKeysForPublishing => " +
+        std::string{::olm_account_last_error(this->getOlmAccount())}};
+  }
+  std::string unpublishedKeysString =
+      std::string{unpublishedOneTimeKeys.begin(), unpublishedOneTimeKeys.end()};
+
+  folly::dynamic parsedUnpublishedKeys =
+      folly::parseJson(unpublishedKeysString);
+
+  size_t numUnpublishedKeys = parsedUnpublishedKeys["curve25519"].size();
+
+  if (numUnpublishedKeys < oneTimeKeysAmount) {
+    this->generateOneTimeKeys(oneTimeKeysAmount - numUnpublishedKeys);
   }
 
+  this->publishOneTimeKeys();
+
   return std::string{
       this->keys.oneTimeKeys.begin(), this->keys.oneTimeKeys.end()};
 }
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
@@ -72,10 +72,7 @@
   virtual jsi::Value initializeCryptoAccount(jsi::Runtime &rt) override;
   virtual jsi::Value getUserPublicKey(jsi::Runtime &rt) override;
   virtual jsi::Value
-  getPrimaryOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) override;
-  virtual jsi::Value getNotificationsOneTimeKeys(
-      jsi::Runtime &rt,
-      double oneTimeKeysAmount) override;
+  getOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) override;
   virtual jsi::Value generateAndGetPrekeys(jsi::Runtime &rt) override;
   virtual jsi::Value validateAndUploadPrekeys(
       jsi::Runtime &rt,
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
@@ -565,43 +565,42 @@
   return jsiOneTimeKeys;
 }
 
-jsi::Value CommCoreModule::getPrimaryOneTimeKeys(
+jsi::Object parseOneTimeKeysResult(
     jsi::Runtime &rt,
-    double oneTimeKeysAmount) {
-  return createPromiseAsJSIValue(
-      rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
-        taskType job = [=, &innerRt]() {
-          std::string error;
-          std::string result;
-          if (this->cryptoModule == nullptr) {
-            error = "user has not been initialized";
-          } else {
-            result = this->cryptoModule->getOneTimeKeys(oneTimeKeysAmount);
-            this->persistCryptoModule();
-          }
-          this->jsInvoker_->invokeAsync([=, &innerRt]() {
-            if (error.size()) {
-              promise->reject(error);
-              return;
-            }
-            promise->resolve(parseOLMOneTimeKeys(innerRt, result));
-          });
-        };
-        this->cryptoThread->scheduleTask(job);
-      });
+    std::string contentOneTimeKeysBlob,
+    std::string notifOneTimeKeysBlob) {
+  auto contentOneTimeKeys = parseOLMOneTimeKeys(rt, contentOneTimeKeysBlob);
+  auto notifOneTimeKeys = parseOLMOneTimeKeys(rt, notifOneTimeKeysBlob);
+  auto jsiOneTimeKeysResult = jsi::Object(rt);
+  jsiOneTimeKeysResult.setProperty(
+      rt, "contentOneTimeKeys", contentOneTimeKeys);
+  jsiOneTimeKeysResult.setProperty(
+      rt, "notificationsOneTimeKeys", notifOneTimeKeys);
+
+  return jsiOneTimeKeysResult;
 }
 
-jsi::Value CommCoreModule::getNotificationsOneTimeKeys(
-    jsi::Runtime &rt,
-    double oneTimeKeysAmount) {
+jsi::Value
+CommCoreModule::getOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) {
   return createPromiseAsJSIValue(
       rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
         taskType job = [=, &innerRt]() {
           std::string error;
-          std::string result;
+          std::string contentResult;
+          std::string notifResult;
+          if (this->cryptoModule == nullptr) {
+            this->jsInvoker_->invokeAsync([=, &innerRt]() {
+              promise->reject("user has not been initialized");
+            });
+            return;
+          }
           try {
-            result = NotificationsCryptoModule::getNotificationsOneTimeKeys(
-                oneTimeKeysAmount, "Comm");
+            contentResult = this->cryptoModule->getOneTimeKeysForPublishing(
+                oneTimeKeysAmount);
+            this->persistCryptoModule();
+            notifResult = NotificationsCryptoModule::
+                getNotificationsOneTimeKeysForPublishing(
+                    oneTimeKeysAmount, "Comm");
           } catch (const std::exception &e) {
             error = e.what();
           }
@@ -610,7 +609,8 @@
               promise->reject(error);
               return;
             }
-            promise->resolve(parseOLMOneTimeKeys(innerRt, result));
+            promise->resolve(
+                parseOneTimeKeysResult(innerRt, contentResult, notifResult));
           });
         };
         this->cryptoThread->scheduleTask(job);
diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h
--- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h
+++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h
@@ -38,7 +38,7 @@
   generateAndGetNotificationsPrekey(const std::string &callingProcessName);
   static std::string
   getNotificationsPrekeySignature(const std::string &callingProcessName);
-  static std::string getNotificationsOneTimeKeys(
+  static std::string getNotificationsOneTimeKeysForPublishing(
       const size_t oneTimeKeysAmount,
       const std::string &callingProcessName);
   static crypto::EncryptedData initializeNotificationsSession(
diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp
--- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp
+++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp
@@ -236,13 +236,13 @@
   return prekeySignature;
 }
 
-std::string NotificationsCryptoModule::getNotificationsOneTimeKeys(
+std::string NotificationsCryptoModule::getNotificationsOneTimeKeysForPublishing(
     const size_t oneTimeKeysAmount,
     const std::string &callingProcessName) {
   std::string oneTimeKeys;
   auto caller = [&oneTimeKeys, oneTimeKeysAmount](
                     const std::unique_ptr<crypto::CryptoModule> &cryptoModule) {
-    oneTimeKeys = cryptoModule->getOneTimeKeys(oneTimeKeysAmount);
+    oneTimeKeys = cryptoModule->getOneTimeKeysForPublishing(oneTimeKeysAmount);
   };
   NotificationsCryptoModule::callCryptoModule(caller, callingProcessName);
   return oneTimeKeys;
diff --git a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
--- a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
+++ b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
@@ -69,11 +69,8 @@
 static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getUserPublicKey(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
   return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->getUserPublicKey(rt);
 }
-static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getPrimaryOneTimeKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
-  return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->getPrimaryOneTimeKeys(rt, args[0].asNumber());
-}
-static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getNotificationsOneTimeKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
-  return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->getNotificationsOneTimeKeys(rt, args[0].asNumber());
+static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getOneTimeKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+  return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->getOneTimeKeys(rt, args[0].asNumber());
 }
 static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_generateAndGetPrekeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
   return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->generateAndGetPrekeys(rt);
@@ -181,8 +178,7 @@
   methodMap_["processKeyserverStoreOperations"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processKeyserverStoreOperations};
   methodMap_["initializeCryptoAccount"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeCryptoAccount};
   methodMap_["getUserPublicKey"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getUserPublicKey};
-  methodMap_["getPrimaryOneTimeKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getPrimaryOneTimeKeys};
-  methodMap_["getNotificationsOneTimeKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getNotificationsOneTimeKeys};
+  methodMap_["getOneTimeKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getOneTimeKeys};
   methodMap_["generateAndGetPrekeys"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_generateAndGetPrekeys};
   methodMap_["validateAndUploadPrekeys"] = MethodMetadata {3, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_validateAndUploadPrekeys};
   methodMap_["initializeNotificationsSession"] = MethodMetadata {5, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeNotificationsSession};
diff --git a/native/cpp/CommonCpp/_generated/commJSI.h b/native/cpp/CommonCpp/_generated/commJSI.h
--- a/native/cpp/CommonCpp/_generated/commJSI.h
+++ b/native/cpp/CommonCpp/_generated/commJSI.h
@@ -38,8 +38,7 @@
   virtual jsi::Value processKeyserverStoreOperations(jsi::Runtime &rt, jsi::Array operations) = 0;
   virtual jsi::Value initializeCryptoAccount(jsi::Runtime &rt) = 0;
   virtual jsi::Value getUserPublicKey(jsi::Runtime &rt) = 0;
-  virtual jsi::Value getPrimaryOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0;
-  virtual jsi::Value getNotificationsOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0;
+  virtual jsi::Value getOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0;
   virtual jsi::Value generateAndGetPrekeys(jsi::Runtime &rt) = 0;
   virtual jsi::Value validateAndUploadPrekeys(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken) = 0;
   virtual jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys, jsi::String keyserverID) = 0;
@@ -232,21 +231,13 @@
       return bridging::callFromJs<jsi::Value>(
           rt, &T::getUserPublicKey, jsInvoker_, instance_);
     }
-    jsi::Value getPrimaryOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) override {
+    jsi::Value getOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) override {
       static_assert(
-          bridging::getParameterCount(&T::getPrimaryOneTimeKeys) == 2,
-          "Expected getPrimaryOneTimeKeys(...) to have 2 parameters");
+          bridging::getParameterCount(&T::getOneTimeKeys) == 2,
+          "Expected getOneTimeKeys(...) to have 2 parameters");
 
       return bridging::callFromJs<jsi::Value>(
-          rt, &T::getPrimaryOneTimeKeys, jsInvoker_, instance_, std::move(oneTimeKeysAmount));
-    }
-    jsi::Value getNotificationsOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) override {
-      static_assert(
-          bridging::getParameterCount(&T::getNotificationsOneTimeKeys) == 2,
-          "Expected getNotificationsOneTimeKeys(...) to have 2 parameters");
-
-      return bridging::callFromJs<jsi::Value>(
-          rt, &T::getNotificationsOneTimeKeys, jsInvoker_, instance_, std::move(oneTimeKeysAmount));
+          rt, &T::getOneTimeKeys, jsInvoker_, instance_, std::move(oneTimeKeysAmount));
     }
     jsi::Value generateAndGetPrekeys(jsi::Runtime &rt) override {
       static_assert(
diff --git a/native/handlers/peer-to-peer-message-handler.js b/native/handlers/peer-to-peer-message-handler.js
--- a/native/handlers/peer-to-peer-message-handler.js
+++ b/native/handlers/peer-to-peer-message-handler.js
@@ -46,12 +46,10 @@
     await commCoreModule.initializeCryptoAccount();
     const [
       { userID, deviceID, accessToken },
-      notificationsOneTimeKeys,
-      primaryOneTimeKeys,
+      { contentOneTimeKeys, notificationsOneTimeKeys },
     ] = await Promise.all([
       commCoreModule.getCommServicesAuthMetadata(),
-      commCoreModule.getNotificationsOneTimeKeys(message.numberOfKeys),
-      commCoreModule.getPrimaryOneTimeKeys(message.numberOfKeys),
+      commCoreModule.getOneTimeKeys(message.numberOfKeys),
     ]);
 
     if (!userID || !deviceID || !accessToken) {
@@ -66,7 +64,7 @@
         userID,
         deviceID,
         accessToken,
-        getOneTimeKeyArray(primaryOneTimeKeys),
+        getOneTimeKeyArray(contentOneTimeKeys),
         getOneTimeKeyArray(notificationsOneTimeKeys),
       );
     } catch (e) {
diff --git a/native/identity-service/identity-service-context-provider.react.js b/native/identity-service/identity-service-context-provider.react.js
--- a/native/identity-service/identity-service-context-provider.react.js
+++ b/native/identity-service/identity-service-context-provider.react.js
@@ -201,13 +201,11 @@
         await commCoreModule.initializeCryptoAccount();
         const [
           { blobPayload, signature },
-          notificationsOneTimeKeys,
-          primaryOneTimeKeys,
+          { contentOneTimeKeys, notificationsOneTimeKeys },
           prekeys,
         ] = await Promise.all([
           commCoreModule.getUserPublicKey(),
-          commCoreModule.getNotificationsOneTimeKeys(ONE_TIME_KEYS_NUMBER),
-          commCoreModule.getPrimaryOneTimeKeys(ONE_TIME_KEYS_NUMBER),
+          commCoreModule.getOneTimeKeys(ONE_TIME_KEYS_NUMBER),
           commCoreModule.generateAndGetPrekeys(),
         ]);
         const registrationResult = await commRustModule.registerUser(
@@ -219,7 +217,7 @@
           prekeys.contentPrekeySignature,
           prekeys.notifPrekey,
           prekeys.notifPrekeySignature,
-          getOneTimeKeyArray(primaryOneTimeKeys),
+          getOneTimeKeyArray(contentOneTimeKeys),
           getOneTimeKeyArray(notificationsOneTimeKeys),
         );
         const { userID, accessToken: token } = JSON.parse(registrationResult);
diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js
--- a/native/schema/CommCoreModuleSchema.js
+++ b/native/schema/CommCoreModuleSchema.js
@@ -42,6 +42,11 @@
   +accessToken?: ?string,
 };
 
+type OneTimeKeysResult = {
+  contentOneTimeKeys: OLMOneTimeKeys,
+  notificationsOneTimeKeys: OLMOneTimeKeys,
+};
+
 interface Spec extends TurboModule {
   +getDraft: (key: string) => Promise<string>;
   +updateDraft: (key: string, text: string) => Promise<boolean>;
@@ -79,12 +84,7 @@
   ) => Promise<void>;
   +initializeCryptoAccount: () => Promise<string>;
   +getUserPublicKey: () => Promise<ClientPublicKeys>;
-  +getPrimaryOneTimeKeys: (
-    oneTimeKeysAmount: number,
-  ) => Promise<OLMOneTimeKeys>;
-  +getNotificationsOneTimeKeys: (
-    oneTimeKeysAmount: number,
-  ) => Promise<OLMOneTimeKeys>;
+  +getOneTimeKeys: (oneTimeKeysAmount: number) => Promise<OneTimeKeysResult>;
   +generateAndGetPrekeys: () => Promise<SignedPrekeys>;
   +validateAndUploadPrekeys: (
     authUserID: string,