diff --git a/lib/http/client.cpp b/lib/http/client.cpp
index 96cfc7f5d9721054594e17cc7da65e1f85fa5f23..ad2ca10089e14cbd10c57769e9bc2a6b7c01abc0 100644
--- a/lib/http/client.cpp
+++ b/lib/http/client.cpp
@@ -751,8 +751,8 @@ Client::messages(const MessagesOpts &opts, Callback<mtx::responses::Messages> ca
         if (!opts.filter.empty())
                 params.emplace("filter", opts.filter);
 
-        const auto api_path =
-          "/client/r0/rooms/" + opts.room_id + "/messages?" + client::utils::query_params(params);
+        const auto api_path = "/client/r0/rooms/" + mtx::client::utils::url_encode(opts.room_id) +
+                              "/messages?" + client::utils::query_params(params);
 
         get<mtx::responses::Messages>(
           api_path, [callback](const mtx::responses::Messages &res, HeaderFields, RequestErr err) {
diff --git a/lib/structs/responses/messages.cpp b/lib/structs/responses/messages.cpp
index d95530a65f9d9df9b45831ed3db2f5997231cc37..a116f2327de2cd93927a3027f2a3f500feb9ce3b 100644
--- a/lib/structs/responses/messages.cpp
+++ b/lib/structs/responses/messages.cpp
@@ -9,10 +9,11 @@ namespace responses {
 void
 from_json(const json &obj, Messages &messages)
 {
-        messages.start = obj.at("start").get<std::string>();
-        messages.end   = obj.at("end").get<std::string>();
+        messages.start = obj.value("start", "");
+        messages.end   = obj.value("end", "");
 
-        utils::parse_timeline_events(obj.at("chunk"), messages.chunk);
+        if (obj.contains("chunk"))
+                utils::parse_timeline_events(obj.at("chunk"), messages.chunk);
 }
 }
 }