summary refs log tree commit diff
path: root/docs
diff options
context:
space:
mode:
authorMark Haines <mark.haines@matrix.org>2014-08-26 16:07:05 +0100
committerMark Haines <mark.haines@matrix.org>2014-08-26 16:07:05 +0100
commit4b63b06cad3e72e3d3dee66d3d6c7801e4a7abaf (patch)
tree37b368d6039d986d70f153fb69d6345d1019d64a /docs
parentfix a few pyflakes errors (diff)
parentFix pyflakes errors (diff)
downloadsynapse-4b63b06cad3e72e3d3dee66d3d6c7801e4a7abaf.tar.xz
Merge branch 'develop' into storage_transactions
Conflicts:
	synapse/api/auth.py
	synapse/handlers/room.py
	synapse/storage/__init__.py
Diffstat (limited to 'docs')
-rw-r--r--docs/client-server/swagger_matrix/api-docs38
-rw-r--r--docs/client-server/swagger_matrix/events299
-rw-r--r--docs/client-server/swagger_matrix/login102
-rw-r--r--docs/client-server/swagger_matrix/presence164
-rw-r--r--docs/client-server/swagger_matrix/profile122
-rw-r--r--docs/client-server/swagger_matrix/registration75
-rw-r--r--docs/client-server/swagger_matrix/rooms807
7 files changed, 1607 insertions, 0 deletions
diff --git a/docs/client-server/swagger_matrix/api-docs b/docs/client-server/swagger_matrix/api-docs
new file mode 100644
index 0000000000..d974dbb374
--- /dev/null
+++ b/docs/client-server/swagger_matrix/api-docs
@@ -0,0 +1,38 @@
+{
+  "apiVersion": "1.0.0",
+  "swaggerVersion": "1.2",
+  "apis": [
+    {
+      "path": "/login",
+      "description": "Login operations"
+    },
+    {
+      "path": "/registration",
+      "description": "Registration operations"
+    },
+    {
+      "path": "/rooms",
+      "description": "Room operations"
+    },
+    {
+      "path": "/profile",
+      "description": "Profile operations"
+    },
+    {
+      "path": "/presence",
+      "description": "Presence operations"
+    }
+  ],
+  "authorizations": {
+    "token": {
+      "scopes": []
+    }
+  },
+  "info": {
+    "title": "Matrix Client-Server API Reference",
+    "description": "This contains the client-server API for the reference implementation of the home server",
+    "termsOfServiceUrl": "http://matrix.org",
+    "license": "Apache 2.0",
+    "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html"
+  }
+}
diff --git a/docs/client-server/swagger_matrix/events b/docs/client-server/swagger_matrix/events
new file mode 100644
index 0000000000..c9eb3f6ff7
--- /dev/null
+++ b/docs/client-server/swagger_matrix/events
@@ -0,0 +1,299 @@
+{
+  "apiVersion": "1.0.0",
+  "swaggerVersion": "1.2",
+  "basePath": "http://petstore.swagger.wordnik.com/api",
+  "resourcePath": "/user",
+  "produces": [
+    "application/json"
+  ],
+  "apis": [
+    {
+      "path": "/user",
+      "operations": [
+        {
+          "method": "POST",
+          "summary": "Create user",
+          "notes": "This can only be done by the logged in user.",
+          "type": "void",
+          "nickname": "createUser",
+          "authorizations": {
+            "oauth2": [
+              {
+                "scope": "test:anything",
+                "description": "anything"
+              }
+            ]
+          },
+          "parameters": [
+            {
+              "name": "body",
+              "description": "Created user object",
+              "required": true,
+              "type": "User",
+              "paramType": "body"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/user/logout",
+      "operations": [
+        {
+          "method": "GET",
+          "summary": "Logs out current logged in user session",
+          "notes": "",
+          "type": "void",
+          "nickname": "logoutUser",
+          "authorizations": {},
+          "parameters": []
+        }
+      ]
+    },
+    {
+      "path": "/user/createWithArray",
+      "operations": [
+        {
+          "method": "POST",
+          "summary": "Creates list of users with given input array",
+          "notes": "",
+          "type": "void",
+          "nickname": "createUsersWithArrayInput",
+          "authorizations": {
+            "oauth2": [
+              {
+                "scope": "test:anything",
+                "description": "anything"
+              }
+            ]
+          },
+          "parameters": [
+            {
+              "name": "body",
+              "description": "List of user object",
+              "required": true,
+              "type": "array",
+              "items": {
+                "$ref": "User"
+              },
+              "paramType": "body"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/user/createWithList",
+      "operations": [
+        {
+          "method": "POST",
+          "summary": "Creates list of users with given list input",
+          "notes": "",
+          "type": "void",
+          "nickname": "createUsersWithListInput",
+          "authorizations": {
+            "oauth2": [
+              {
+                "scope": "test:anything",
+                "description": "anything"
+              }
+            ]
+          },
+          "parameters": [
+            {
+              "name": "body",
+              "description": "List of user object",
+              "required": true,
+              "type": "array",
+              "items": {
+                "$ref": "User"
+              },
+              "paramType": "body"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/user/{username}",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Updated user",
+          "notes": "This can only be done by the logged in user.",
+          "type": "void",
+          "nickname": "updateUser",
+          "authorizations": {
+            "oauth2": [
+              {
+                "scope": "test:anything",
+                "description": "anything"
+              }
+            ]
+          },
+          "parameters": [
+            {
+              "name": "username",
+              "description": "name that need to be deleted",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "body",
+              "description": "Updated user object",
+              "required": true,
+              "type": "User",
+              "paramType": "body"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "Invalid username supplied"
+            },
+            {
+              "code": 404,
+              "message": "User not found"
+            }
+          ]
+        },
+        {
+          "method": "DELETE",
+          "summary": "Delete user",
+          "notes": "This can only be done by the logged in user.",
+          "type": "void",
+          "nickname": "deleteUser",
+          "authorizations": {
+            "oauth2": [
+              {
+                "scope": "test:anything",
+                "description": "anything"
+              }
+            ]
+          },
+          "parameters": [
+            {
+              "name": "username",
+              "description": "The name that needs to be deleted",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "Invalid username supplied"
+            },
+            {
+              "code": 404,
+              "message": "User not found"
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get user by user name",
+          "notes": "",
+          "type": "User",
+          "nickname": "getUserByName",
+          "authorizations": {},
+          "parameters": [
+            {
+              "name": "username",
+              "description": "The name that needs to be fetched. Use user1 for testing.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "Invalid username supplied"
+            },
+            {
+              "code": 404,
+              "message": "User not found"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/user/login",
+      "operations": [
+        {
+          "method": "GET",
+          "summary": "Logs user into the system",
+          "notes": "",
+          "type": "string",
+          "nickname": "loginUser",
+          "authorizations": {},
+          "parameters": [
+            {
+              "name": "username",
+              "description": "The user name for login",
+              "required": true,
+              "type": "string",
+              "paramType": "query"
+            },
+            {
+              "name": "password",
+              "description": "The password for login in clear text",
+              "required": true,
+              "type": "string",
+              "paramType": "query"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "Invalid username and password combination"
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "models": {
+    "User": {
+      "id": "User",
+      "properties": {
+        "id": {
+          "type": "integer",
+          "format": "int64"
+        },
+        "firstName": {
+          "type": "string"
+        },
+        "username": {
+          "type": "string"
+        },
+        "lastName": {
+          "type": "string"
+        },
+        "email": {
+          "type": "string"
+        },
+        "password": {
+          "type": "string"
+        },
+        "phone": {
+          "type": "string"
+        },
+        "userStatus": {
+          "type": "integer",
+          "format": "int32",
+          "description": "User Status",
+          "enum": [
+            "1-registered",
+            "2-active",
+            "3-closed"
+          ]
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/docs/client-server/swagger_matrix/login b/docs/client-server/swagger_matrix/login
new file mode 100644
index 0000000000..4410d3c887
--- /dev/null
+++ b/docs/client-server/swagger_matrix/login
@@ -0,0 +1,102 @@
+{
+  "apiVersion": "1.0.0", 
+  "apis": [
+    {
+      "operations": [
+        {
+          "method": "GET", 
+          "nickname": "get_login_info", 
+          "notes": "All login stages MUST be mentioned if there is >1 login type.", 
+          "summary": "Get the login mechanism to use when logging in.", 
+          "type": "LoginInfo"
+        }, 
+        {
+          "method": "POST", 
+          "nickname": "submit_login", 
+          "notes": "If this is part of a multi-stage login, there MUST be a 'session' key.", 
+          "parameters": [
+            {
+              "description": "A login submission", 
+              "name": "body", 
+              "paramType": "body", 
+              "required": true, 
+              "type": "LoginSubmission"
+            }
+          ], 
+          "responseMessages": [
+            {
+              "code": 400, 
+              "message": "Bad login type"
+            }, 
+            {
+              "code": 400, 
+              "message": "Missing JSON keys"
+            }
+          ], 
+          "summary": "Submit a login action.", 
+          "type": "LoginResult"
+        }
+      ], 
+      "path": "/login"
+    }
+  ], 
+  "basePath": "http://localhost:8080/matrix/client/api/v1", 
+  "consumes": [
+    "application/json"
+  ], 
+  "models": {
+    "LoginInfo": {
+      "id": "LoginInfo", 
+      "properties": {
+        "stages": {
+          "description": "Multi-stage login only: An array of all the login types required to login.", 
+          "format": "string", 
+          "type": "array"
+        }, 
+        "type": {
+          "description": "The login type that must be used when logging in.", 
+          "type": "string"
+        }
+      }
+    }, 
+    "LoginResult": {
+      "id": "LoginResult", 
+      "properties": {
+        "access_token": {
+          "description": "The access token for this user's login if this is the final stage of the login process.", 
+          "type": "string"
+        }, 
+        "next": {
+          "description": "Multi-stage login only: The next login type to submit.", 
+          "type": "string"
+        },
+        "session": {
+          "description": "Multi-stage login only: The session token to send when submitting the next login type.",
+          "type": "string"
+        }
+      }
+    }, 
+    "LoginSubmission": {
+      "id": "LoginSubmission", 
+      "properties": {
+        "type": {
+          "description": "The type of login being submitted.", 
+          "type": "string"
+        },
+        "session": {
+          "description": "Multi-stage login only: The session token from an earlier login stage.",
+          "type": "string"
+        },
+        "_login_type_defined_keys_": {
+          "description": "Keys as defined by the specified login type, e.g. \"user\", \"password\""
+        }
+      }
+    }
+  }, 
+  "produces": [
+    "application/json"
+  ], 
+  "resourcePath": "/login", 
+  "swaggerVersion": "1.2"
+}
+
diff --git a/docs/client-server/swagger_matrix/presence b/docs/client-server/swagger_matrix/presence
new file mode 100644
index 0000000000..ee9deb12f0
--- /dev/null
+++ b/docs/client-server/swagger_matrix/presence
@@ -0,0 +1,164 @@
+{
+  "apiVersion": "1.0.0",
+  "swaggerVersion": "1.2",
+  "basePath": "http://localhost:8080/matrix/client/api/v1",
+  "resourcePath": "/presence",
+  "produces": [
+    "application/json"
+  ],
+  "consumes": [
+    "application/json"
+  ],
+  "apis": [
+    {
+      "path": "/presence/{userId}/status",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Update this user's presence state.",
+          "notes": "This can only be done by the logged in user.",
+          "type": "void",
+          "nickname": "update_presence",
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The new presence state",
+              "required": true,
+              "type": "PresenceUpdate",
+              "paramType": "body"
+            },
+            {
+              "name": "userId",
+              "description": "The user whose presence to set.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get this user's presence state.",
+          "notes": "Get this user's presence state.",
+          "type": "PresenceUpdate",
+          "nickname": "get_presence",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user whose presence to get.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/presence_list/{userId}",
+      "operations": [
+        {
+          "method": "GET",
+          "summary": "Retrieve a list of presences for all of this user's friends.",
+          "notes": "",
+          "type": "array",
+          "items": {
+            "$ref": "Presence"
+          },
+          "nickname": "get_presence_list",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user whose presence list to get.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        },
+        {
+          "method": "POST",
+          "summary": "Add or remove users from this presence list.",
+          "notes": "Add or remove users from this presence list.",
+          "type": "void",
+          "nickname": "modify_presence_list",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user whose presence list is being modified.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "body",
+              "description": "The modifications to make to this presence list.",
+              "required": true,
+              "type": "PresenceListModifications",
+              "paramType": "body"
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "models": {
+    "PresenceUpdate": {
+      "id": "PresenceUpdate",
+      "properties": {
+        "state": {
+          "type": "string",
+          "description": "Enum: The presence state.",
+          "enum": [
+            "offline",
+            "unavailable",
+            "online",
+            "free_for_chat"
+          ]
+        },
+        "status_msg": {
+          "type": "string",
+          "description": "The user-defined message associated with this presence state."
+        }
+      },
+      "subTypes": [
+        "Presence"
+      ]
+    },
+    "Presence": {
+      "id": "Presence",
+      "properties": {
+        "mtime_age": {
+          "type": "integer",
+          "format": "int64",
+          "description": "The last time this user's presence state changed, in milliseconds."
+        },
+        "user_id": {
+          "type": "string",
+          "description": "The fully qualified user ID"
+        }
+      }
+    },
+    "PresenceListModifications": {
+      "id": "PresenceListModifications",
+      "properties": {
+        "invite": {
+          "type": "array",
+          "description": "A list of user IDs to add to the list.",
+          "items": {
+            "type": "string",
+            "description": "A fully qualified user ID."
+          }
+        },
+        "drop": {
+          "type": "array",
+          "description": "A list of user IDs to remove from the list.",
+          "items": {
+            "type": "string",
+            "description": "A fully qualified user ID."
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/docs/client-server/swagger_matrix/profile b/docs/client-server/swagger_matrix/profile
new file mode 100644
index 0000000000..1ebde62e20
--- /dev/null
+++ b/docs/client-server/swagger_matrix/profile
@@ -0,0 +1,122 @@
+{
+  "apiVersion": "1.0.0",
+  "swaggerVersion": "1.2",
+  "basePath": "http://localhost:8080/matrix/client/api/v1",
+  "resourcePath": "/profile",
+  "produces": [
+    "application/json"
+  ],
+  "consumes": [
+    "application/json"
+  ],
+  "apis": [
+    {
+      "path": "/profile/{userId}/displayname",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Set a display name.",
+          "notes": "This can only be done by the logged in user.",
+          "type": "void",
+          "nickname": "set_display_name",
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The new display name for this user.",
+              "required": true,
+              "type": "DisplayName",
+              "paramType": "body"
+            },
+            {
+              "name": "userId",
+              "description": "The user whose display name to set.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get a display name.",
+          "notes": "This can be done by anyone.",
+          "type": "DisplayName",
+          "nickname": "get_display_name",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user whose display name to get.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/profile/{userId}/avatar_url",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Set an avatar URL.",
+          "notes": "This can only be done by the logged in user.",
+          "type": "void",
+          "nickname": "set_avatar_url",
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The new avatar url for this user.",
+              "required": true,
+              "type": "AvatarUrl",
+              "paramType": "body"
+            },
+            {
+              "name": "userId",
+              "description": "The user whose avatar url to set.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get an avatar url.",
+          "notes": "This can be done by anyone.",
+          "type": "AvatarUrl",
+          "nickname": "get_avatar_url",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user whose avatar url to get.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "models": {
+    "DisplayName": {
+      "id": "DisplayName",
+      "properties": {
+        "displayname": {
+          "type": "string",
+          "description": "The textual display name"
+        }
+      }
+    },
+    "AvatarUrl": {
+      "id": "AvatarUrl",
+      "properties": {
+        "avatar_url": {
+          "type": "string",
+          "description": "A url to an image representing an avatar."
+        }
+      }
+    }
+  }
+}
diff --git a/docs/client-server/swagger_matrix/registration b/docs/client-server/swagger_matrix/registration
new file mode 100644
index 0000000000..ccd542d11e
--- /dev/null
+++ b/docs/client-server/swagger_matrix/registration
@@ -0,0 +1,75 @@
+{
+  "apiVersion": "1.0.0", 
+  "apis": [
+    {
+      "operations": [
+        {
+          "method": "POST", 
+          "nickname": "register", 
+          "notes": "Volatile: This API is likely to change.", 
+          "parameters": [
+            {
+              "description": "A registration request", 
+              "name": "body", 
+              "paramType": "body", 
+              "required": true, 
+              "type": "RegistrationRequest"
+            }
+          ], 
+          "responseMessages": [
+            {
+              "code": 400, 
+              "message": "No JSON object."
+            }, 
+            {
+              "code": 400, 
+              "message": "User ID must only contain characters which do not require url encoding."
+            },
+            {
+              "code": 400, 
+              "message": "User ID already taken."
+            }
+          ], 
+          "summary": "Register with the home server.", 
+          "type": "RegistrationResponse"
+        }
+      ], 
+      "path": "/register"
+    }
+  ], 
+  "basePath": "http://localhost:8080/matrix/client/api/v1", 
+  "consumes": [
+    "application/json"
+  ], 
+  "models": {
+    "RegistrationResponse": {
+      "id": "RegistrationResponse", 
+      "properties": {
+        "access_token": {
+          "description": "The access token for this user.", 
+          "type": "string"
+        }, 
+        "user_id": {
+          "description": "The fully-qualified user ID.", 
+          "type": "string"
+        }
+      }
+    }, 
+    "RegistrationRequest": {
+      "id": "RegistrationRequest", 
+      "properties": {
+        "user_id": {
+          "description": "The desired user ID. If not specified, a random user ID will be allocated.", 
+          "type": "string",
+          "required": false
+        }
+      }
+    }
+  }, 
+  "produces": [
+    "application/json"
+  ], 
+  "resourcePath": "/register", 
+  "swaggerVersion": "1.2"
+}
+
diff --git a/docs/client-server/swagger_matrix/rooms b/docs/client-server/swagger_matrix/rooms
new file mode 100644
index 0000000000..47a8887240
--- /dev/null
+++ b/docs/client-server/swagger_matrix/rooms
@@ -0,0 +1,807 @@
+{
+  "apiVersion": "1.0.0",
+  "swaggerVersion": "1.2",
+  "basePath": "http://localhost:8080/matrix/client/api/v1", 
+  "resourcePath": "/rooms",
+  "produces": [
+    "application/json"
+  ],
+  "consumes": [
+    "application/json"
+  ],
+  "authorizations": {
+    "token": []
+  },
+  "apis": [
+    {
+      "path": "/rooms/{roomId}/messages/{userId}/{messageId}",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Send a message in this room.",
+          "notes": "Send a message in this room.",
+          "type": "void",
+          "nickname": "send_message",
+          "consumes": [
+            "application/json"
+          ],
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The message contents",
+              "required": true,
+              "type": "Message",
+              "paramType": "body"
+            },
+            {
+              "name": "roomId",
+              "description": "The room to send the message in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "userId",
+              "description": "The fully qualified message sender's user ID.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "messageId",
+              "description": "A message ID which is unique for each room and user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 403,
+              "message": "Must send messages as yourself."
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get a message from this room.",
+          "notes": "Get a message from this room.",
+          "type": "Message",
+          "nickname": "get_message",
+          "parameters": [
+            {
+              "name": "roomId",
+              "description": "The room to send the message in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "userId",
+              "description": "The fully qualified message sender's user ID.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "messageId",
+              "description": "A message ID which is unique for each room and user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 404,
+              "message": "Message not found."
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/rooms/{roomId}/topic",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Set the topic for this room.",
+          "notes": "Set the topic for this room.",
+          "type": "void",
+          "nickname": "set_topic",
+          "consumes": [
+            "application/json"
+          ],
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The topic contents",
+              "required": true,
+              "type": "Topic",
+              "paramType": "body"
+            },
+            {
+              "name": "roomId",
+              "description": "The room to set the topic in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 403,
+              "message": "Must send messages as yourself."
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get the topic for this room.",
+          "notes": "Get the topic for this room.",
+          "type": "Topic",
+          "nickname": "get_topic",
+          "parameters": [
+            {
+              "name": "roomId",
+              "description": "The room to get topic in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 404,
+              "message": "Topic not found."
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/rooms/{roomId}/messages/{msgSenderId}/{messageId}/feedback/{senderId}/{feedbackType}",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Send feedback to a message.",
+          "notes": "Send feedback to a message.",
+          "type": "void",
+          "nickname": "send_feedback",
+          "consumes": [
+            "application/json"
+          ],
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The feedback contents",
+              "required": true,
+              "type": "Feedback",
+              "paramType": "body"
+            },
+            {
+              "name": "roomId",
+              "description": "The room to send the feedback in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "msgSenderId",
+              "description": "The fully qualified message sender's user ID.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "messageId",
+              "description": "A message ID which is unique for each room and user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "senderId",
+              "description": "The fully qualified feedback sender's user ID.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "feedbackType",
+              "description": "The type of feedback being sent.",
+              "required": true,
+              "type": "string",
+              "paramType": "path",
+              "enum": [
+                "d",
+                "r"
+              ]
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 403,
+              "message": "Must send feedback as yourself."
+            },
+            {
+              "code": 400,
+              "message": "Bad feedback type."
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get feedback for a message.",
+          "notes": "Get feedback for a message.",
+          "type": "Feedback",
+          "nickname": "get_feedback",
+          "parameters": [
+            {
+              "name": "roomId",
+              "description": "The room to send the message in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "msgSenderId",
+              "description": "The fully qualified message sender's user ID.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "messageId",
+              "description": "A message ID which is unique for each room and user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "senderId",
+              "description": "The fully qualified feedback sender's user ID.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "feedbackType",
+              "description": "Enum: The type of feedback being sent.",
+              "required": true,
+              "type": "string",
+              "paramType": "path",
+              "enum": [
+                "d",
+                "r"
+              ]
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 404,
+              "message": "Feedback not found."
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/rooms/{roomId}/members/{userId}/state",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Change the membership state for a user in a room.",
+          "notes": "Change the membership state for a user in a room.",
+          "type": "void",
+          "nickname": "set_membership",
+          "consumes": [
+            "application/json"
+          ],
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The new membership state",
+              "required": true,
+              "type": "Member",
+              "paramType": "body"
+            },
+            {
+              "name": "userId",
+              "description": "The user whose membership is being changed.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "roomId",
+              "description": "The room which has this user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "No membership key."
+            },
+            {
+              "code": 400,
+              "message": "Bad membership value."
+            },
+            {
+              "code": 403,
+              "message": "When inviting: You are not in the room."
+            },
+            {
+              "code": 403,
+              "message": "When inviting: <target> is already in the room."
+            },
+            {
+              "code": 403,
+              "message": "When joining: Cannot force another user to join."
+            },
+            {
+              "code": 403,
+              "message": "When joining: You are not invited to this room."
+            }
+          ]
+        },
+        {
+          "method": "GET",
+          "summary": "Get the membership state of a user in a room.",
+          "notes": "Get the membership state of a user in a room.",
+          "type": "Member",
+          "nickname": "get_membership",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user whose membership state you want to get.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "roomId",
+              "description": "The room which has this user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 404,
+              "message": "Member not found."
+            }
+          ]
+        },
+        {
+          "method": "DELETE",
+          "summary": "Leave a room.",
+          "notes": "Leave a room.",
+          "type": "void",
+          "nickname": "remove_membership",
+          "parameters": [
+            {
+              "name": "userId",
+              "description": "The user who is leaving.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "roomId",
+              "description": "The room which has this user.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 403,
+              "message": "You are not in the room."
+            },
+            {
+              "code": 403,
+              "message": "Cannot force another user to leave."
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/join/{roomAlias}",
+      "operations": [
+        {
+          "method": "PUT",
+          "summary": "Join a room via a room alias.",
+          "notes": "Join a room via a room alias.",
+          "type": "RoomInfo",
+          "nickname": "join_room_via_alias",
+          "consumes": [
+            "application/json"
+          ],
+          "parameters": [
+            {
+              "name": "roomAlias",
+              "description": "The room alias to join.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "Bad room alias."
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/rooms",
+      "operations": [
+        {
+          "method": "POST",
+          "summary": "Create a room.",
+          "notes": "Create a room.",
+          "type": "RoomInfo",
+          "nickname": "create_room",
+          "consumes": [
+            "application/json"
+          ],
+          "parameters": [
+            {
+              "name": "body",
+              "description": "The desired configuration for the room.",
+              "required": true,
+              "type": "RoomConfig",
+              "paramType": "body"
+            }
+          ],
+          "responseMessages": [
+            {
+              "code": 400,
+              "message": "Body must be JSON."
+            },
+            {
+              "code": 400,
+              "message": "Room alias already taken."
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/rooms/{roomId}/messages/list",
+      "operations": [
+        {
+          "method": "GET",
+          "summary": "Get a list of messages for this room.",
+          "notes": "Get a list of messages for this room.",
+          "type": "MessagePaginationChunk",
+          "nickname": "get_messages",
+          "parameters": [
+            {
+              "name": "roomId",
+              "description": "The room to get messages in.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "from",
+              "description": "The token to start getting results from.",
+              "required": false,
+              "type": "string",
+              "paramType": "query"
+            },
+            {
+              "name": "to",
+              "description": "The token to stop getting results at.",
+              "required": false,
+              "type": "string",
+              "paramType": "query"
+            },
+            {
+              "name": "limit",
+              "description": "The maximum number of messages to return.",
+              "required": false,
+              "type": "integer",
+              "paramType": "query"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "path": "/rooms/{roomId}/members/list",
+      "operations": [
+        {
+          "method": "GET",
+          "summary": "Get a list of members for this room.",
+          "notes": "Get a list of members for this room.",
+          "type": "MemberPaginationChunk",
+          "nickname": "get_members",
+          "parameters": [
+            {
+              "name": "roomId",
+              "description": "The room to get a list of members from.",
+              "required": true,
+              "type": "string",
+              "paramType": "path"
+            },
+            {
+              "name": "from",
+              "description": "The token to start getting results from.",
+              "required": false,
+              "type": "string",
+              "paramType": "query"
+            },
+            {
+              "name": "to",
+              "description": "The token to stop getting results at.",
+              "required": false,
+              "type": "string",
+              "paramType": "query"
+            },
+            {
+              "name": "limit",
+              "description": "The maximum number of members to return.",
+              "required": false,
+              "type": "integer",
+              "paramType": "query"
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "models": {
+    "Topic": {
+      "id": "Topic",
+      "properties": {
+        "topic": {
+          "type": "string",
+          "description": "The topic text"
+        }
+      }
+    },
+    "Message": {
+      "id": "Message",
+      "properties": {
+        "msgtype": {
+          "type": "string",
+          "description": "The type of message being sent, e.g. \"m.text\"",
+          "required": true
+        },
+        "_msgtype_defined_keys_": {
+          "description": "Additional keys as defined by the msgtype, e.g. \"body\""
+        }
+      }
+    },
+    "Feedback": {
+      "id": "Feedback",
+      "properties": {
+      }
+    },
+    "Member": {
+      "id": "Member",
+      "properties": {
+        "membership": {
+          "type": "string",
+          "description": "Enum: The membership state of this member.",
+          "enum": [
+            "invite",
+            "join",
+            "leave",
+            "knock"
+          ]
+        }
+      }
+    },
+    "RoomInfo": {
+      "id": "RoomInfo",
+      "properties": {
+        "room_id": {
+          "type": "string",
+          "description": "The allocated room ID.",
+          "required": true
+        },
+        "room_alias": {
+          "type": "string",
+          "description": "The alias for the room.",
+          "required": false
+        }
+      }
+    },
+    "RoomConfig": {
+      "id": "RoomConfig",
+      "properties": {
+        "visibility": {
+          "type": "string",
+          "description": "Enum: The room visibility.",
+          "required": false,
+          "enum": [
+            "public",
+            "private"
+          ]
+        },
+        "room_alias_name": {
+          "type": "string",
+          "description": "The alias to give the new room.",
+          "required": false
+        }
+      }
+    },
+    "PaginationRequest": {
+      "id": "PaginationRequest",
+      "properties": {
+        "from": {
+          "type": "string",
+          "description": "The token to start getting results from."
+        },
+        "to": {
+          "type": "string",
+          "description": "The token to stop getting results at."
+        },
+        "limit": {
+          "type": "integer",
+          "description": "The maximum number of entries to return."
+        }
+      }
+    },
+    "PaginationChunk": {
+      "id": "PaginationChunk",
+      "properties": {
+        "start": {
+          "type": "string",
+          "description": "A token which correlates to the first value in \"chunk\" for paginating.",
+          "required": true
+        },
+        "end": {
+          "type": "string",
+          "description": "A token which correlates to the last value in \"chunk\" for paginating.",
+          "required": true
+        }
+      },
+      "subTypes": [
+        "MessagePaginationChunk"
+      ]
+    },
+    "MessagePaginationChunk": {
+      "id": "MessagePaginationChunk",
+      "properties": {
+        "chunk": {
+          "type": "array",
+          "description": "A list of message events.",
+          "items": {
+            "$ref": "MessageEvent"
+          },
+          "required": true
+        }
+      }
+    },
+    "MemberPaginationChunk": {
+      "id": "MemberPaginationChunk",
+      "properties": {
+        "chunk": {
+          "type": "array",
+          "description": "A list of member events.",
+          "items": {
+            "$ref": "MemberEvent"
+          },
+          "required": true
+        }
+      }
+    },
+    "Event": {
+      "id": "Event",
+      "properties": {
+        "event_id": {
+          "type": "string",
+          "description": "An ID which uniquely identifies this event.",
+          "required": true
+        },
+        "room_id": {
+          "type": "string",
+          "description": "The room in which this event occurred.",
+          "required": true
+        }
+      },
+      "subTypes": [
+        "MessageEvent"
+      ]
+    },
+    "MessageEvent": {
+      "id": "MessageEvent",
+      "properties": {
+        "content": {
+          "type": "Message"
+        }
+      }
+    },
+    "MemberEvent": {
+      "id": "MemberEvent",
+      "properties": {
+        "content": {
+          "type": "Member"
+        }
+      }
+    },
+    "Tag": {
+      "id": "Tag",
+      "properties": {
+        "id": {
+          "type": "integer",
+          "format": "int64"
+        },
+        "name": {
+          "type": "string"
+        }
+      }
+    },
+    "Pet": {
+      "id": "Pet",
+      "required": [
+        "id",
+        "name"
+      ],
+      "properties": {
+        "id": {
+          "type": "integer",
+          "format": "int64",
+          "description": "unique identifier for the pet",
+          "minimum": "0.0",
+          "maximum": "100.0"
+        },
+        "category": {
+          "$ref": "Category"
+        },
+        "name": {
+          "type": "string"
+        },
+        "photoUrls": {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "tags": {
+          "type": "array",
+          "items": {
+            "$ref": "Tag"
+          }
+        },
+        "status": {
+          "type": "string",
+          "description": "pet status in the store",
+          "enum": [
+            "available",
+            "pending",
+            "sold"
+          ]
+        }
+      }
+    },
+    "Category": {
+      "id": "Category",
+      "properties": {
+        "id": {
+          "type": "integer",
+          "format": "int64"
+        },
+        "name": {
+          "type": "string"
+        },
+        "pet": {
+          "$ref": "Pet"
+        }
+      }
+    }
+  }
+}