diff --git a/drafts/cs-v2-http-api.rst b/drafts/cs-v2-http-api.rst deleted file mode 100644 index adfd4767..00000000 --- a/drafts/cs-v2-http-api.rst +++ /dev/null @@ -1,449 +0,0 @@ -Client-Server v2 HTTP API Draft -=============================== - -Filter API ----------- - -The intersection of the parameters given defines the filter. Unions of filters -can be achieved by querying multiple filters in parallel. - -XXX: Filters describe both what data to query and how to present it, so could -perhaps be better described as 'queries' or even 'subscriptions'? - -XXX: Is this actually sensible - should we instead have ordering & pagination & -limits etc provided per-query rather than lost in the filter? Or you provide the -defaults in the filter definition, and then clobber them with query params. - -You can define a reusable filter with the below POST API. The resulting filter_id -can then be passed to methods which can be filter. - -You can only create filters for your own user (filters are namespaced per user -as they are defined per-user data, like profiles etc) - -TODO: excluding filters (e.g. filter out "org.matrix.neb.*") - -XXX: how do we transition between non-coalesced pagination and coalesced pagination for related_to/updates - -:: - - POST /user/{userId}/filter - -.. code:: javascript - - { - // selectors: (bluntly selecting on the unencrypted fields) - types: [ "m.*", "net.arasphere.*" ], // default: all - rooms: [ "!83wy7whi:matrix.org" ], // default: all (may be aliases or IDs. wildcards supported) - sender_ids: [ "@matthew:matrix.org" ], // default: all (e.g. for narrowing down presence, and stalker mode. wildcards supported) - - // XXX: do we want this per-query; is it valid to reuse it? - // we probably don't need this as querying per-event-ID will be a parameter from a seperate API, - // with its own seperate filter token & pagination semantics. - event_ids: [ "$192318719:matrix.org" ], // default: all - useful for selecting relates_to data for a given event - - // parameters - - // 'format' gives the desired shape of the response - // federation = include the federation layer as well as the raw content of events. - // events = the plain events - format: "federation", - - // select specific specific fields of the event to be returned. - // N.B. you cannot guaranteeing filter content fields as they may be encrypted. - // e.g. selecting just event_id could be useful for doing server-side - // sorting/pagination/threading - select: [ "event_id", "origin_server_ts", "thread_id", "content", "content.body" ], - - // include bundled child-event updates (default false) - bundle_updates: true, - - // include bundled related events - bundle_relates_to: [ - { - relationship: "in_reply_to", - // As this is an optimisation to avoid having to explicitly select/paginate the - // related messages per-message, we have to include a limit here as if we were - // actually executing the query per-message for the initial result set. - // Limit gives the number of related events to bundle; the bundled events return chunk tokens - // to let you seperately paginate on them. - limit: 10, // maximum number of related events to bundle in the results of this filtered result set. - ancestors: true, // include all ancestors (default: true) - descendents: true, // include all descendents (default: true) - - - // need to support a sort criteria which reflects the linearised ordering of the relation graph - }, - ], - - // server-side sorting, so we can paginate serverside on a thin client. - // N.B. we can only order by unencrypted fields. - // N.B. clients will need to handle out-of-order messages intelligently - // N.B. subset of things you're allowed to sort by may be arbitrarily - // restricted by the server impl (XXX: capabilities?) - // Servers must support the "timeline" ordering - which is linearised logical chronological ordering. - // XXX: should this be done per-request rather than per-filter? Given streaming APIs (like eventStream) - // will be limited to sorting via timeline due to causality... - sort: [ - // sort by sender, and then by the timeline - { - type: "sender_id", - dir: "asc", // default asc - }, - { - type: "timeline", - dir: "asc", - }, - ], - } - -Returns ``200 OK``:: - - { - "filter_id": "583e98c2d983" - } - - -Global initial sync API ------------------------ - -``GET /initialSync`` - -GET parameters:: - - limit: maximum number of events per room to return - sort: fieldname, direction (e.g. "sender_id,asc"). // default: "timeline,asc". may appear multiple times. - since: to request an incremental update (*not* pagination) since the specified chunk token - We call this 'since' rather than 'from' because it's not for pagination, - backfill: true/false (default true): do we want to pull in state from federation if we have less than events available for a room? - presence: true/false (default true): return presence info - compact: boolean (default false): factor out common events. - XXX: I *really* think this should be turned on by default --matthew - filter: (XXX: allow different filters per room?) - # filter overrides: - filter_type: wildcard event type match e.g. "m.*": default, all. may appear multiple times. - filter_room: wildcard room id/name match e.g. "!83wy7whi:matrix.org": default, all. may appear multiple times. - filter_sender_id: wildcard sender id match e.g. "@matthew:matrix.org": default, all. may appear multiple times. - filter_event_id: event id to match e.g. "$192318719:matrix.org" // default, all: may appear multiple times - filter_format: "federation" or "events" - filter_select: event fields to return: default, all. may appear multiple times - filter_bundle_updates: true/false: default, false. bundle updates in events. - - // FIXME: kegan: how much does the v1 response actually change here? - -Returns ``200 OK``: - -.. code:: javascript - - // where compact is false: - { - "end": "s72595_4483_1934", // the chunk token we pass to from= - - // global presence info (if presence=true) - "presence": [{ - "content": { - "avatar_url": "http://matrix.tp.mu:8008/_matrix/content/QG1hdHRoZXc6dHAubXUOeJQMWFMvUdqdeLovZKsyaOT.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew Hodgson", - "last_active_ago": 368200528, - "presence": "online", - "user_id": "@matthew:tp.mu" - }, - "type": "m.presence" - }], - - "rooms": [{ - "membership": "join", - "eventStream": { // rename messages to eventstream as this is a list of all events, not just messages (non-state events) - "chunk": [{ - "content": { - "avatar_url": "https://matrix.org/_matrix/content/QG1hdHRoZXc6bWF0cml4Lm9yZwxaesQWnqdynuXIYaRisFnZdG.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew", - "membership": "join" - }, - "event_id": "$1417731086506PgoVf:matrix.org", - "membership": "join", - "origin_server_ts": 1417731086795, - "prev_content": { - "avatar_url": "https://matrix.org/_matrix/content/QG1hdHRoZXc6bWF0cml4Lm9yZwxaesQWnqdynuXIYaRisFnZdG.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Ara4n", - "membership": "join" - } - "prev_state": [["$1416420706925RVAWP:matrix.org", { - "sha256": "zVzi02R5aeO2HQDnybu1XuuyR6yBG8utLE/i1Sv8eyA" - } - ]], - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state_key": "@matthew:matrix.org", - "type": "m.room.member", - "user_id": "@matthew:matrix.org" - }], - "end": "s72595_4483_1934", - "start": "t67-41151_4483_1934" - }, - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state": [{ - "content": { - "avatar_url": "https://matrix.org/_matrix/content/QG1hdHRoZXc6bWF0cml4Lm9yZwxaesQWnqdynuXIYaRisFnZdG.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew", - "membership": "join" - }, - "event_id": "$1417731086506PgoVf:matrix.org", - "membership": "join", - "origin_server_ts": 1417731086795, - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state_key": "@matthew:matrix.org", - "type": "m.room.member", - "user_id": "@matthew:matrix.org" - }], - "visibility": "public" - }] - } - - - // where compact is true: - { - "end": "s72595_4483_1934", - // global presence info - "presence": [{ - "content": { - "avatar_url": "http://matrix.tp.mu:8008/_matrix/content/QG1hdHRoZXc6dHAubXUOeJQMWFMvUdqdeLovZKsyaOT.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew Hodgson", - "last_active_ago": 368200528, - "presence": "online", - "user_id": "@matthew:tp.mu" - }, - "type": "m.presence" - }], - "rooms": [{ - "events": { - "$1417731086506PgoVf:matrix.org": { - "content": { - "avatar_url": "https://matrix.org/_matrix/content/QG1hdHRoZXc6bWF0cml4Lm9yZwxaesQWnqdynuXIYaRisFnZdG.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew", - "membership": "join" - }, - "membership": "join", - "origin_server_ts": 1417731086795, - "prev_state": [["$1416420706925RVAWP:matrix.org", { - "sha256": "zVzi02R5aeO2HQDnybu1XuuyR6yBG8utLE/i1Sv8eyA" - } - ]], - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state_key": "@matthew:matrix.org", - "type": "m.room.member", - "user_id": "@matthew:matrix.org" - } - }, - "membership": "join", - "eventStream": { // rename messages to eventstream as this is a list of all events, not just messages (non-state events) - "chunk": [ "$1417731086506PgoVf:matrix.org" ], - "end": "s72595_4483_1934", - "start": "t67-41151_4483_1934" // XXX: do we need start? - }, - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state": [ "$1417731086506PgoVf:matrix.org" ], - "visibility": "public" - }] - } - -Event Stream API ----------------- - -GET ``/eventStream`` -GET parameters:: - - from: chunk token to continue streaming from (e.g. "end" given by initialsync) - filter*: as per initialSync (XXX: do we inherit this from the chunk token?) - // N.B. there is no limit or sort param here, as we get events in timeline order as fast as they come. - access_token: identifies both user and device - timeout: maximum time to poll before returning the request - presence: "offline" // optional parameter to tell the server not to interpret this as coming online - - XXX: this needs to be updated from v1. Presumably s/user_id/sender_id/? - -Returns ``200 OK``: - -.. code:: javascript - - // events precisely as per a room's eventStream key as returned by initialSync - // includes non-graph events like presence - { - "chunk": [{ - "content": { - "avatar_url": "https://matrix.org/_matrix/content/QG1hdHRoZXc6bWF0cml4Lm9yZwxaesQWnqdynuXIYaRisFnZdG.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew", - "last_active_ago": 1241, - "presence": "online", - "user_id": "@matthew:matrix.org" - }, - "type": "m.presence" - }, { - "age": 2595, - "content": { - "body": "test", - "msgtype": "m.text" - }, - "event_id": "$14211894201675TMbmz:matrix.org", - "origin_server_ts": 1421189420147, - "room_id": "!cURbafjkfsMDVwdRDQ:matrix.org", - "type": "m.room.message", - "user_id": "@matthew:matrix.org" - }], - "end": "s75460_2478_981", - "start": "s75459_2477_981" // XXX: do we need start here? - } - -Room Creation API ------------------ - -Joining API ------------ - -Room History ------------- - -Scrollback API -~~~~~~~~~~~~~~ - -:: - - GET /rooms//events - -GET parameters:: - - from: the chunk token to paginate from - Otherwise same as initialSync, except "compact", "since" and "presence" are not implemented - -Returns ``200 OK``: - -.. code:: javascript - - // events precisely as per a room's eventStream key as returned by initialSync - { - "chunk": [{ - "age": 28153452, // XXX: age and origin_server_ts are redundant here surely - "content": { - "body": "but obviously the XSF believes XMPP is the One True Way", - "msgtype": "m.text" - }, - "event_id": "$1421165049511TJpDp:matrix.org", - "origin_server_ts": 1421165049435, - "room_id": "!cURbafjkfsMDVwdRDQ:matrix.org", - "type": "m.room.message", - "user_id": "@irc_Arathorn:matrix.org" - }, { - "age": 28167245, - "content": { - "body": "which is all fair enough", - "msgtype": "m.text" - }, - "event_id": "$1421165035510CBwsU:matrix.org", - "origin_server_ts": 1421165035643, - "room_id": "!cURbafjkfsMDVwdRDQ:matrix.org", - "type": "m.room.message", - "user_id": "@irc_Arathorn:matrix.org" - }], - "end": "t9571-74545_2470_979", - "start": "t9601-75400_2470_979" // XXX: don't we just need end here as we can only paginate one way? - } - -Contextual windowing API -~~~~~~~~~~~~~~~~~~~~~~~~ -:: - - GET /events/ - -GET parameters:: - - context: "before", "after" or "around" - Otherwise same as initialSync, except "since" and "presence" are not implemented - -Returns ``200 OK``: - -.. code:: javascript - - // the room in question, formatted exactly as a room entry returned by /initialSync - // with the event in question present in the list as determined by the context param - { - "events": { - "$1417731086506PgoVf:matrix.org": { - "content": { - "avatar_url": "https://matrix.org/_matrix/content/QG1hdHRoZXc6bWF0cml4Lm9yZwxaesQWnqdynuXIYaRisFnZdG.aW1hZ2UvanBlZw==.jpeg", - "displayname": "Matthew", - "membership": "join" - }, - "membership": "join", - "origin_server_ts": 1417731086795, - "prev_state": [["$1416420706925RVAWP:matrix.org", { - "sha256": "zVzi02R5aeO2HQDnybu1XuuyR6yBG8utLE/i1Sv8eyA" - } - ]], - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state_key": "@matthew:matrix.org", - "type": "m.room.member", - "user_id": "@matthew:matrix.org" - } - }, - "membership": "join", - "eventStream": { - "chunk": [ "$1417731086506PgoVf:matrix.org" ], - "end": "s72595_4483_1934", - "start": "t67-41151_4483_1934" - }, - "room_id": "!KrLWMLDnZAyTapqLWW:matrix.org", - "state": [ "$1417731086506PgoVf:matrix.org" ], - "visibility": "public" - } - - -Room Alias API --------------- - -Room Directory API ------------------- - -User Profile API ----------------- - -Provides arbitrary per-user global state JSON storage with namespaced keys, -some of which have specific predefined serverside semantics. Keys must be named -(we don't support POSTing to anonymous key names) - -:: - - PUT /user/{userId}/data/m.displayname - PUT /user/{userId}/data/m.avatar_url - PUT /user/{userId}/data/m.contact_vcard - PUT /user/{userId}/data/net.arasphere.client.preferences - -Account Management API ----------------------- - -Actions API ------------ - -Presence API ------------- - -:: - - PUT /user/{userId}/presence/m.status // set DND/asleep/on holiday etc - - // XXX: do we need to distinguish between internationalisable presets like DND - // and free-form textual status messages? - // XXX: should this be in /user/{userId}/data/m.status instead? - // what's actually the difference? surely status is no different to avatar - // updates in terms of needing to be pushed around - - PUT /device/{deviceId}/presence/m.presence // explicitly set online/idle/offline - // or /presence/device/{deviceId} - - // XXX: need to remember how to handle activity notifications - -Typing API ----------- - -Relates_to pagination API -------------------------- - -Capabilities API ----------------- -