diff --git a/changelogs/client_server/newsfragments/3098.feature b/changelogs/client_server/newsfragments/3098.feature
new file mode 100644
index 00000000..0f3c3ab8
--- /dev/null
+++ b/changelogs/client_server/newsfragments/3098.feature
@@ -0,0 +1 @@
+Add support for spoilers ([MSC2010](https://github.com/matrix-org/matrix-doc/pull/2010) and [MSC2557](https://github.com/matrix-org/matrix-doc/pull/2557)), and `color` attribute ([MSC2422](https://github.com/matrix-org/matrix-doc/pull/2422)).
\ No newline at end of file
diff --git a/content/client-server-api/modules/instant_messaging.md b/content/client-server-api/modules/instant_messaging.md
index 3a933a93..ca2cb74a 100644
--- a/content/client-server-api/modules/instant_messaging.md
+++ b/content/client-server-api/modules/instant_messaging.md
@@ -63,10 +63,11 @@ are listed, clients should translate the value (a 6-character hex color
code) to the appropriate CSS/attributes for the tag.
`font`
-`data-mx-bg-color`, `data-mx-color`
+`data-mx-bg-color`, `data-mx-color`, `color`
`span`
-`data-mx-bg-color`, `data-mx-color`
+`data-mx-bg-color`, `data-mx-color`, `data-mx-spoiler` (see
+[spoiler messages](#spoiler-messages))
`a`
`name`, `target`, `href` (provided the value is not relative and has a
@@ -461,6 +462,52 @@ For `m.image`, the text should be `"sent an image."`. For `m.video`, the
text should be `"sent a video."`. For `m.audio`, the text should be
`"sent an audio file"`.
+##### Spoiler messages
+
+Parts of a message can be hidden visually from the user through use of spoilers.
+This does not affect the server's representation of the event content - it
+is simply a visual cue to the user that the message may reveal important
+information about something, spoiling any relevant surprise.
+
+To send spoilers clients MUST use the `formatted_body` and therefore the
+`org.matrix.custom.html` format, described above. This makes spoilers valid on
+any `msgtype` which can support this format appropriately.
+
+Spoilers themselves are contained with `span` tags, with the reason (optionally)
+being in the `data-mx-spoiler` attribute. Spoilers without a reason must at least
+specify the attribute, though the value may be empty/undefined.
+
+An example of a spoiler is:
+
+```json
+{
+ "msgtype": "m.text",
+ "format": "org.matrix.custom.html",
+ "body": "Alice [Spoiler](mxc://example.org/abc123) in the movie.",
+ "formatted_body": "Alice lived happily ever after in the movie."
+}
+```
+
+If a reason were to be supplied, it would look like:
+
+```json
+{
+ "msgtype": "m.text",
+ "format": "org.matrix.custom.html",
+ "body": "Alice [Spoiler for health of Alice](mxc://example.org/abc123) in the movie.",
+ "formatted_body": "Alice lived happily ever after in the movie."
+}
+```
+
+When sending a spoiler, clients SHOULD provide the plain text fallback in the `body`
+as shown above (including the reason). The fallback SHOULD omit the spoiler text verbatim
+since `body` might show up in text-only clients or in notifications. To prevent spoilers
+showing up in such situations, clients are strongly encouraged to first upload the plaintext
+to the media repository then reference the MXC URI in a markdown-style link, as shown above.
+
+Clients SHOULD render spoilers differently with some sort of disclosure. For example, the
+client could blur the actual text and ask the user to click on it for it to be revealed.
+
#### Server behaviour
Homeservers SHOULD reject `m.room.message` events which don't have a