diff --git a/examples/crypto_bot.cpp b/examples/crypto_bot.cpp
index 78d81347f312d515e67d57274cd923ff6a0ab64a..f0f6064e985af3f30d79edf16686e9402babde9a 100644
--- a/examples/crypto_bot.cpp
+++ b/examples/crypto_bot.cpp
@@ -473,7 +473,7 @@ create_outbound_megolm_session(const std::string &room_id, const std::string &re
                                 };
 
                                 // TODO: we should bulk request device keys here
-                                client->claim_keys(parse<User>(member.first), {dev}, cb);
+                                client->claim_keys(member.first, {dev}, cb);
                         }
                 }
         }
diff --git a/include/mtxclient/http/client.hpp b/include/mtxclient/http/client.hpp
index b90e7f574b65c476f0142684e7aedd453479f19a..f90c734fe8c48a413fa8f81e445d5c82e986f143 100644
--- a/include/mtxclient/http/client.hpp
+++ b/include/mtxclient/http/client.hpp
@@ -126,11 +126,9 @@ public:
         //! Change displayname.
         void set_displayname(const std::string &displayname, ErrCallback cb);
         //! Get user profile.
-        void get_profile(const mtx::identifiers::User &user_id,
-                         Callback<mtx::responses::Profile> cb);
+        void get_profile(const std::string &user_id, Callback<mtx::responses::Profile> cb);
         //! Get user avatar URL.
-        void get_avatar_url(const mtx::identifiers::User &user_id,
-                            Callback<mtx::responses::AvatarUrl> cb);
+        void get_avatar_url(const std::string &user_id, Callback<mtx::responses::AvatarUrl> cb);
         //! Create a room with the given options.
         void create_room(const mtx::requests::CreateRoom &room_options,
                          Callback<mtx::responses::CreateRoom> cb);
@@ -234,7 +232,7 @@ public:
                         Callback<mtx::responses::QueryKeys> cb);
 
         //! Claims one-time keys for use in pre-key messages.
-        void claim_keys(const mtx::identifiers::User &user,
+        void claim_keys(const std::string &user,
                         const std::vector<std::string> &devices,
                         Callback<mtx::responses::ClaimKeys> cb);
 
diff --git a/lib/http/client.cpp b/lib/http/client.cpp
index 8397756c5676f582b4cf9d9b10bc38048060c624..28b0b3d55cf451521d3e1bdb5d8056435bb29e66 100644
--- a/lib/http/client.cpp
+++ b/lib/http/client.cpp
@@ -126,20 +126,18 @@ Client::set_displayname(const std::string &displayname, ErrCallback callback)
 }
 
 void
-Client::get_profile(const mtx::identifiers::User &user_id,
-                    Callback<mtx::responses::Profile> callback)
+Client::get_profile(const std::string &user_id, Callback<mtx::responses::Profile> callback)
 {
-        get<mtx::responses::Profile>("/client/r0/profile/" + user_id.to_string(),
+        get<mtx::responses::Profile>("/client/r0/profile/" + user_id,
                                      [callback](const mtx::responses::Profile &res,
                                                 HeaderFields,
                                                 RequestErr err) { callback(res, err); });
 }
 
 void
-Client::get_avatar_url(const mtx::identifiers::User &user_id,
-                       Callback<mtx::responses::AvatarUrl> callback)
+Client::get_avatar_url(const std::string &user_id, Callback<mtx::responses::AvatarUrl> callback)
 {
-        get<mtx::responses::AvatarUrl>("/client/r0/profile/" + user_id.to_string() + "/avatar_url",
+        get<mtx::responses::AvatarUrl>("/client/r0/profile/" + user_id + "/avatar_url",
                                        [callback](const mtx::responses::AvatarUrl &res,
                                                   HeaderFields,
                                                   RequestErr err) { callback(res, err); });
@@ -409,7 +407,7 @@ Client::query_keys(const mtx::requests::QueryKeys &req,
 
 //! Claims one-time keys for use in pre-key messages.
 void
-Client::claim_keys(const mtx::identifiers::User &user,
+Client::claim_keys(const std::string &user,
                    const std::vector<std::string> &devices,
                    Callback<mtx::responses::ClaimKeys> cb)
 {
@@ -419,7 +417,7 @@ Client::claim_keys(const mtx::identifiers::User &user,
         for (const auto &d : devices)
                 dev_to_algorithm.emplace(d, "signed_curve25519");
 
-        req.one_time_keys[user.to_string()] = dev_to_algorithm;
+        req.one_time_keys[user] = dev_to_algorithm;
 
         post<mtx::requests::ClaimKeys, mtx::responses::ClaimKeys>(
           "/client/r0/keys/claim", std::move(req), std::move(cb));
diff --git a/tests/client_api.cpp b/tests/client_api.cpp
index 1116a4bccb3c68ae755215d97c6ca7b619c5254a..432c6c75772953f7154739290cc8dd191a8fcfdb 100644
--- a/tests/client_api.cpp
+++ b/tests/client_api.cpp
@@ -135,7 +135,8 @@ TEST(ClientAPI, EmptyUserAvatar)
                         auto done = false;
 
                         alice->get_profile(
-                          alice_id, [&done](const mtx::responses::Profile &res, RequestErr err) {
+                          alice_id.to_string(),
+                          [&done](const mtx::responses::Profile &res, RequestErr err) {
                                   ASSERT_FALSE(err);
                                   ASSERT_TRUE(res.avatar_url.size() == 0);
                                   done = true;
@@ -145,7 +146,8 @@ TEST(ClientAPI, EmptyUserAvatar)
                                 sleep();
 
                         alice->get_avatar_url(
-                          alice_id, [](const mtx::responses::AvatarUrl &res, RequestErr err) {
+                          alice_id.to_string(),
+                          [](const mtx::responses::AvatarUrl &res, RequestErr err) {
                                   ASSERT_FALSE(err);
                                   ASSERT_TRUE(res.avatar_url.size() == 0);
                           });
@@ -173,7 +175,7 @@ TEST(ClientAPI, RealUserAvatar)
                         auto done = false;
 
                         alice->get_profile(
-                          alice_id,
+                          alice_id.to_string(),
                           [avatar_url, &done](const mtx::responses::Profile &res, RequestErr err) {
                                   ASSERT_FALSE(err);
                                   ASSERT_TRUE(res.avatar_url == avatar_url);
@@ -184,7 +186,7 @@ TEST(ClientAPI, RealUserAvatar)
                                 sleep();
 
                         alice->get_avatar_url(
-                          alice_id,
+                          alice_id.to_string(),
                           [avatar_url](const mtx::responses::AvatarUrl &res, RequestErr err) {
                                   ASSERT_FALSE(err);
                                   ASSERT_TRUE(res.avatar_url == avatar_url);
diff --git a/tests/e2ee.cpp b/tests/e2ee.cpp
index 092b5850fc0d1cf6ae4616c5ffb27f836980d900..e3641474115f389bcf31123e29d14d9377b1bd8e 100644
--- a/tests/e2ee.cpp
+++ b/tests/e2ee.cpp
@@ -380,7 +380,7 @@ TEST(Encryption, ClaimKeys)
                                                         DeviceId(bob->device_id()),
                                                         UserId(bob->user_id().to_string())));
 
-                  alice->claim_keys(bob->user_id(),
+                  alice->claim_keys(bob->user_id().to_string(),
                                     devices,
                                     [alice_olm, bob, bob_ed25519](
                                       const mtx::responses::ClaimKeys &res, RequestErr err) {
@@ -745,7 +745,7 @@ TEST(Encryption, OlmRoomKeyEncryption)
 
         // Alice needs one of Bob's one time keys.
         request_finished = false;
-        alice_http->claim_keys(bob_http->user_id(),
+        alice_http->claim_keys(bob_http->user_id().to_string(),
                                {bob_http->device_id()},
                                [&bob_otk, bob = bob_http, &request_finished](
                                  const mtx::responses::ClaimKeys &res, RequestErr err) {