Index: src/MTXClient.m ================================================================== --- src/MTXClient.m +++ src/MTXClient.m @@ -201,11 +201,15 @@ { void *pool = objc_autoreleasePoolPush(); MTXRequest *request = [self requestWithPath: @"/_matrix/client/r0/sync"]; unsigned long long timeoutMs = timeout * 1000; - request.query = [OFString stringWithFormat: @"timeout=%llu", timeoutMs]; + OFMutableDictionary *query = + [OFMutableDictionary dictionaryWithObject: @(timeoutMs).stringValue + forKey: @"timeout"]; + query[@"since"] = [_storage nextBatchForDeviceID: _deviceID]; + request.query = query; [request performWithBlock: ^ (mtx_response_t response, int statusCode, id exception) { if (exception != nil) { block(exception); return; Index: src/MTXRequest.h ================================================================== --- src/MTXRequest.h +++ src/MTXRequest.h @@ -71,11 +71,12 @@ @property (copy, nonatomic) OFString *path; /** * @brief The query for the request. */ -@property (copy, nullable, nonatomic) OFString *query; +@property (copy, nullable, nonatomic) + OFDictionary *query; /** * @brief An optional body to send along with the request. * * This is a dictionary that gets serialized to JSON when the request is sent. Index: src/MTXRequest.m ================================================================== --- src/MTXRequest.m +++ src/MTXRequest.m @@ -95,11 +95,11 @@ /* Not the best exception to indicate it's already in-flight. */ @throw [OFAlreadyConnectedException exception]; OFMutableURL *requestURL = [[_homeserver mutableCopy] autorelease]; requestURL.path = _path; - requestURL.query = _query; + requestURL.queryDictionary = _query; OFMutableDictionary *headers = [OFMutableDictionary dictionary]; headers[@"User-Agent"] = @"ObjMatrix"; if (_accessToken != nil) headers[@"Authorization"] =