Coverage

Every endpoint below is read out of the router at build time, so this page cannot claim a surface the server does not serve. What is missing is curated, reviewed in pull requests, and cross-checked against the router — a gap that gets implemented and left listed here fails the build.

292routes served
0known gaps
100%of scoped surface

Where the gaps are

Implemented against implemented-plus-planned, per area. The denominator is what this roadmap has scoped, not the whole specification: a full bar means nothing we intend to build in that area is outstanding.

Admin & moderation89 served · 0 left
Delegated auth & OIDC19 served · 0 left
Appservices2 served · 0 left
VoIP & MatrixRTC11 served · 0 left
Key backup5 served · 0 left
Federation29 served · 0 left
End-to-end encryption7 served · 0 left
Sync2 served · 0 left
Account data, filters & push10 served · 0 left
Media8 served · 0 left
Timeline, messaging & search13 served · 0 left
Rooms & membership27 served · 0 left
Profiles & presence5 served · 0 left
Accounts, devices & auth13 served · 0 left
Server, discovery & operations52 served · 0 left

What is still missing

Nothing in scope is outstanding.

Deprecated surfaces and deliberately-unbundled services — TURN, the push gateway, an identity server; see #4's what not to build early — are neither implemented nor counted here.

Milestones

Roadmap: #4. These are the current standing rather than the plan.

M0 — Prove the core

Done

Fork resolution vs ruma-state-res and HAMT-vs-im benchmarks published on the benchmark site; durability and recovery covered by restart and torn-write tests.

M1 — Usable local homeserver

Done

Full local CS-API surface with classic /sync; leftovers tracked on #7 (room upgrade, spaces, search, OpenAPI validation, Element Web rig). Benchmarked vs Synapse and Continuwuity — see docs/benchmarks.md.

M2 — Modern encrypted clients

Done

Media + thumbnails (#99, #104), Simplified Sliding Sync (#105) with the to-device, E2EE, account-data, receipts and typing extensions Element X reads everything but timelines through, E2EE transport (#106), fallback keys + device lists (#107), key backup + cross-signing (#108), URL previews (#109), S3 media backend (#110). Close-out benchmark: four-way vs Synapse, Continuwuity and Tuwunel (built from source) — 60 of 63 cells won; the one real loss became #113's unread-index fix (11.79 ms → 1.00 ms); the three residual cells are within measured noise. See docs/benchmarks.md and the comparisons page. Element X client-gate work continues as #112.

M3 — Ordinary Matrix federation

In progress

The identity, transport, join, state, history, catch-up and fork-rig tracks are complete (#14–#16). Synapse interoperability runs nightly in both directions, and federation_fork.rs checks stale, disjoint, contested and partition-and-heal forks through real federation. The remaining frontier is the intermittent restricted-room join in #342; its suspected stale-copy mechanism was disproved and its faithful local sequence is now a permanent regression test.

M4 — Ecosystem integration

Done

Delegated MAS/OIDC authentication and the built-in OIDC provider are complete (#17). The application-service surface is complete (#18), with matrix-hookshot and the mautrix-go harness running in scheduled CI. Evidence and operator guidance live under docs/evidence/ and docs/delegated-auth.md.

M5 — Production lifecycle

In progress

#83's admin API is served: 20 endpoints under /_spindle/admin/v1, each also mounted at /_synapse/admin/v1 for existing tooling — users, rooms, state-at, purge_history, room deletion, make_room_admin, event reports and the audit log. #166's observability landed too: a /metrics exposition on its own listener with the fork-case counter, append and HTTP histograms. #21 has its counting performance gate (read_budget.rs, #177), which asserts flat-in-membership rather than timing on CI. #20 is three-quarters done and split: spindle backup, restore and verify-media are served, and #230 added versioned schema migrations whose guarantees — chaining, the no-path refusal, dry runs writing nothing, and the marker never landing ahead of the data — are proven against synthetic tables; the real migration table is deliberately empty because no schema change has yet needed a data rewrite, and docs/lifecycle.md says so rather than implying otherwise. The Synapse importer moved to #240 and is parked behind the API surface and MatrixRTC: its fixture (#234, #237), ordering and divergence check (#235) and SQLite reader (#239) are on main, and the exit criterion has been executed end to end once. backups.rs is M2's E2EE key backup and not this. #42's parity gate vs Synapse and Tuwunel remains part of the definition of done.

M6 — Optional differentiators

Not started

#22 hub mode, #23 MLS.

M7 — MatrixRTC

In progress

#36's delayed events (MSC4140) are served, which no other Rust homeserver has — Tuwunel's compliance table records the endpoints as unimplemented despite having the Ruma types. All four endpoints, authorisation at *fire* time rather than schedule time, survival across a restart, and both caps configurable with a zero refused at startup rather than silently disabling the mechanism. restart is the hot path and costs no writes: it moves an in-memory deadline and lets the fire loop settle the row when it reaches it, so the write rate follows how much is happening rather than how many people are on calls. The trade-off is recorded rather than implied — a crash loses the bumps and a delay fires early, never late, which is the direction a dead-man's switch should fail in. MSC4309 reports finished delays on /sync under the unstable name, capped per user and evicted oldest-first. #36's three benchmarks are collected and published (docs/benchmarks.md): restart is flat from 10 to 1,000 live delays and writes nothing, firing jitter is set by the tick rather than by the size, and the third — the reload at 10k — found the fire loop reading every pending row on every idle tick (#348, fixed in #350: 3.12 ms to 854 ns at ten thousand pending, flat where it was linear). The comparison against Synapse with MSC4140 enabled is done on #42's rig (scripts/delayed-events-benchmark.py, Synapse 1.160 on Postgres, same host): restart is flat at ~0.3 ms from 10 to 1,000 live delays against Synapse's 2.8-5.6 ms, and at a thousand Spindle lands every leave within a third of a second while Synapse had delivered 382 of 1,000 two minutes after the last deadline. Its first sitting lost -- delays landed 504 ms late at the median against Synapse's 59 -- because the fire loop was deployed with a one-second tick where the benchmarks described 100 ms; it ticks at 100 ms now, and Synapse's per-delay timers still keep a tighter p99 at ten and a hundred, which docs/benchmarks.md records as the loss it is. #37 is served too: MatrixRTC transport discovery (MSC4143) on both the stable and the unstable path, and the same backends named unauthenticated in .well-known — one renderer behind both, because a client reads well-known before it has a token and the endpoint after it, and a deployment whose two answers disagree is one where a call works or does not depending on which the client believed. A server with no backend answers an empty list rather than a 404: the endpoint's presence is the claim to implement the MSC, and the list is what it currently has. MSC4158 needed nothing separate — it was folded into MSC4143 and closed, so the well-known key is org.matrix.msc4143.rtc_foci. #39's server half is served: pushers are driven — a delivery loop walks the stream, asks every reader's rules, and posts the spec's notification body to the gateway each device registered, with the gateway address vetted like a preview's and a rejected pushkey forgotten. MSC4075 in its current form defines no push rule of its own: a ring is routed by m.mentions, so the default mention rules are what make a fresh account's phone ring, at high priority, and an MSC4310 decline carries no mention and pushes nobody. The ring has a budget of its own ([ratelimit] rings_per_minute, ten by default), because it is the one event that makes every phone in a room sound and no other send is limited at all. The ring dispatch latency benchmark (--bench ring_latency) is published in docs/benchmarks.md: the first phone rings within the push loop's 100 ms tick up to a hundred members and within a quarter second at a thousand, and the last within one gateway round-trip per member, which is what one gateway URL serving every device costs. Its first run found the loop compiling every rule's glob per reader per event, and a per-gateway queue cap one ring in a large room could fill; both are fixed and written up there. #40's server half is served, and it is smaller than the issue supposed: MatrixRTC membership is room state and to-device traffic, and both were already carried. What the server owed was what the reference clients rely on to get a call off the ground. power_level_content_override on /createRoom is honoured -- Element X names org.matrix.msc3401.call.member at 0 on every room it creates, because a fresh room's state_default of 50 otherwise keeps every ordinary member out of the call -- and trusted_private_chat gives the invitee the creator's power, as a users entry before v12 and as an additional creator (MSC4289) from it, which is what lets a DM call be answered. The state-key rule is the spec's own, run by ruma: a key starting with @ belongs to that user, which is exactly why Element Call's per-device key starts with _ -- and the server invents no owner for that key, since MSC3757 (which would have) is closed and MSC4354 is where the problem is being solved. The lifecycle is pinned end to end in the order Element Call drives it: the delayed leave is scheduled *before* the join and survives it, heartbeats keep the membership, silence fires the leave, everyone else sees it on /sync, and the scheduler reads it back under MSC4309. To-device signalling (MSC3401) needed nothing: a burst of call invites rides the per-device stream in order and the room's own timeline arrives beside it. MSC4354 sticky events, which MSC4143 now makes m.rtc.member, are served: org.matrix.msc4354.sticky_duration_ms on /send and /state (and on a delayed send, so the pair Element Call drives works together), the msc4354_sticky key on the PDU outside the redaction algorithm and capped at the hour the MSC allows, expiry from the earlier of the event's own timestamp and its arrival so a peer cannot stretch it, an index keyed by expiry so what has lapsed is a bounded prefix, and the msc4354_sticky section of /sync -- everything unexpired on an initial sync or a join, only what is new since the token otherwise, never an event the timeline beside it already carries, each stamped with the time it has left. Across federation a sticky event rides /send like any PDU, and a server that joins later gets the room's unexpired ones both pushed through the outbox, as the MSC says, and carried in the send_join response, because a Spindle seeds the join response and backfills nothing, so a pushed event older than what it knows would have no predecessor to hang on. crates/spindle-server/tests/sticky_events.rs pins all of it, the three-server case included. #40's 5/20/100-participant churn benchmarks are published (--bench call_churn): a hundred-party join is in everyone's call in 180 ms and its 9,900 key messages delivered in 282 ms, churn writes stay at 4.7 ms p50 under everyone's heartbeat, and the finding is that a timeline message sent into the key burst arrives in 193 ms against 16 ms idle -- delayed by the shared sync responses, not stalled. #38 is served on both of its halves, and ADR 0004 records the decision between them. The homeserver's half of LiveKit authorisation is the OpenID round trip: /openid/request_token mints a short-lived credential that opens nothing on this server, and the federation /openid/userinfo redeems it -- with the user's ID while it lives, with M_UNKNOWN_TOKEN once it has expired, and the two refusals indistinguishable from a forged one. Tokens are keyed by expiry, the way delayed events are keyed by deadline, so every mint sweeps what has expired in a bounded read and the keyspace never needs a loop of its own. That is everything lk-jwt-service needs, and the external path is what [rtc] foci advertises. The other half is the built-in JWT service behind [rtc.livekit], off by default: it serves lk-jwt-service's own /sfu/get contract at /_spindle/rtc/livekit, so Element Call cannot tell which minter it reached, and mints only for a room the user is joined to *at that moment* -- the one check the external service has no state to make, and a single membership-index read here. A user who has left is refused; an invited one is refused; a room that does not exist is refused identically. The window is fifteen minutes by default and exactly token_ttl_seconds wide, the secret is LiveKit's and not the signing key, minting is rate limited per user (the first authenticated rates this server enforces, docs/rate-limits.md), and roomCreate is withheld because in LiveKit it is also roomDelete. What a stateless token cannot do is be revoked when its holder leaves, and docs/matrix-rtc.md says so in those words rather than implying a guarantee the mechanism cannot make; it also lays out both deployments end to end. #269's rig is on main (contrib/element-call): Element Call's own Playwright stack, upstream and pinned, with Spindle in both of Synapse's seats through a compose override, and a ratchet over their specs in the shape of the Complement one (scripts/element-call-check.py), run nightly and on demand. Thirteen of their specs pass and are protected: the landing page and sign-up; a guest creating a call, sharing the link and a second guest joining with video tiles on both sides; create-call with a clean leave; the JWT error paths; the two SFU-reconnect specs; and spa-call-sticky, which is MatrixRTC 2.0 -- this server's sticky events driven by the real client -- including the rejoin after an improper leave that is the kill scenario #41 names. That is LiveKit, lk-jwt-service and this server composing in a real browser, which is the composition #41 says no unit test reaches. The widget and restricted-SFU specs register users through Synapse's admin API with a shared secret, which this server does not serve, and stay out of scope. What #41 owed beyond upstream's suite is now driven by Spindle's own specs in the same rig (contrib/element-call/specs/) and protected: ringing and decline through Element Web's widget (upstream's voice-call-dm, promoted after passing nightly), a ring the caller abandons, five-party churn with a participant killed mid-call, a homeserver restart mid-call in both membership modes (the call survives and a later crash still expires -- which needed graceful shutdown to keep restarted deadlines, or every live call's leave fired the moment the server came back), and a federated call across the rig's two Spindles in both modes: twenty-two of twenty-two in run 37853447544. Spec drift since: MSC4140 merged on 2026-10-06 and is served in its merged shape beside the unstable one; MSC4075 now carries its own ring push rules, served and merged into rulesets stored before they existed; MSC4310 is folded into MSC4075; and lk-jwt-service 0.7+ runs as the homeserver's sidecar through MSC4502 (is_joined) and MSC4512 (request proxying, fed_proxy), both served (docs/matrix-rtc.md option C). And the call with no SFU at all, which a mesh with no uplink has to make: Element Call's frozen full-mesh branch, the peer-to-peer client, meets in a call against this server with media on a host-to-host candidate pair, on one Spindle and then across the mesh seam with the creator on a Neutrino node (contrib/element-call-full-mesh, docs/p2p-calls.md). This server needed one thing for it, the deprecated r0 API prefix a 2023 matrix-js-sdk still asks for, now served as v3; the node needed contrib/neutrino/0003-browser-clients.patch to be a browser's homeserver at all.

Every endpoint

The served surface in full, by area, as parsed from routes.rs.

Admin & moderation (89)
GET /_spindle/admin/ui
GET /_spindle/admin/ui/app.js
GET /_spindle/admin/ui/styles.css
GET /_spindle/admin/v1/audit
GET /_spindle/admin/v1/event_reports
GET/DELETE /_spindle/admin/v1/event_reports/{report_id}
GET /_spindle/admin/v1/federation/destinations
GET /_spindle/admin/v1/federation/destinations/{destination}
POST /_spindle/admin/v1/federation/destinations/{destination}/reset_connection
GET /_spindle/admin/v1/federation/destinations/{destination}/rooms
GET/DELETE /_spindle/admin/v1/media/{server_name}/{media_id}
GET /_spindle/admin/v1/registration_tokens
POST /_spindle/admin/v1/registration_tokens/new
GET/PUT/DELETE /_spindle/admin/v1/registration_tokens/{token}
GET /_spindle/admin/v1/rooms
GET/DELETE /_spindle/admin/v1/rooms/{room_id}
GET/PUT /_spindle/admin/v1/rooms/{room_id}/block
POST /_spindle/admin/v1/rooms/{room_id}/make_room_admin
GET /_spindle/admin/v1/rooms/{room_id}/members
POST /_spindle/admin/v1/rooms/{room_id}/purge_history
GET /_spindle/admin/v1/rooms/{room_id}/state
GET /_spindle/admin/v1/rooms/{room_id}/state_at
GET /_spindle/admin/v1/rooms/{room_id}/timeline
GET/PUT /_spindle/admin/v1/rtc/sfu
GET /_spindle/admin/v1/scheduled_tasks
POST /_spindle/admin/v1/send_server_notice
GET /_spindle/admin/v1/server_version
GET /_spindle/admin/v1/username_available
GET /_spindle/admin/v1/users
GET/PUT /_spindle/admin/v1/users/{user_id}
GET/PUT /_spindle/admin/v1/users/{user_id}/admin
POST /_spindle/admin/v1/users/{user_id}/deactivate
GET /_spindle/admin/v1/users/{user_id}/devices
GET/PUT/DELETE /_spindle/admin/v1/users/{user_id}/devices/{device_id}
GET /_spindle/admin/v1/users/{user_id}/joined_rooms
GET/DELETE /_spindle/admin/v1/users/{user_id}/media
POST /_spindle/admin/v1/users/{user_id}/password_hash
POST /_spindle/admin/v1/users/{user_id}/reset_link
POST /_spindle/admin/v1/users/{user_id}/reset_password
GET /_spindle/admin/v1/whois/{user_id}
GET /_synapse/admin/v1/audit
POST /_synapse/admin/v1/deactivate/{user_id}
GET /_synapse/admin/v1/event_reports
GET/DELETE /_synapse/admin/v1/event_reports/{report_id}
GET /_synapse/admin/v1/federation/destinations
GET /_synapse/admin/v1/federation/destinations/{destination}
POST /_synapse/admin/v1/federation/destinations/{destination}/reset_connection
GET /_synapse/admin/v1/federation/destinations/{destination}/rooms
GET/DELETE /_synapse/admin/v1/media/{server_name}/{media_id}
POST /_synapse/admin/v1/purge_history/{room_id}
GET/POST /_synapse/admin/v1/register
GET /_synapse/admin/v1/registration_tokens
POST /_synapse/admin/v1/registration_tokens/new
GET/PUT/DELETE /_synapse/admin/v1/registration_tokens/{token}
POST /_synapse/admin/v1/reset_password/{user_id}
GET /_synapse/admin/v1/rooms
GET/DELETE /_synapse/admin/v1/rooms/{room_id}
GET/PUT /_synapse/admin/v1/rooms/{room_id}/block
POST /_synapse/admin/v1/rooms/{room_id}/make_room_admin
GET /_synapse/admin/v1/rooms/{room_id}/members
POST /_synapse/admin/v1/rooms/{room_id}/purge_history
GET /_synapse/admin/v1/rooms/{room_id}/state
GET /_synapse/admin/v1/rooms/{room_id}/state_at
GET /_synapse/admin/v1/rooms/{room_id}/timeline
GET/PUT /_synapse/admin/v1/rtc/sfu
GET /_synapse/admin/v1/scheduled_tasks
POST /_synapse/admin/v1/send_server_notice
GET /_synapse/admin/v1/server_version
GET /_synapse/admin/v1/username_available
GET /_synapse/admin/v1/users
GET/PUT /_synapse/admin/v1/users/{user_id}
GET/PUT /_synapse/admin/v1/users/{user_id}/admin
POST /_synapse/admin/v1/users/{user_id}/deactivate
GET /_synapse/admin/v1/users/{user_id}/devices
GET/PUT/DELETE /_synapse/admin/v1/users/{user_id}/devices/{device_id}
GET /_synapse/admin/v1/users/{user_id}/joined_rooms
GET/DELETE /_synapse/admin/v1/users/{user_id}/media
POST /_synapse/admin/v1/users/{user_id}/password_hash
POST /_synapse/admin/v1/users/{user_id}/reset_link
POST /_synapse/admin/v1/users/{user_id}/reset_password
GET /_synapse/admin/v1/whois/{user_id}
GET /_synapse/admin/v2/rooms/delete_status/{delete_id}
DELETE /_synapse/admin/v2/rooms/{room_id}
GET /_synapse/admin/v2/rooms/{room_id}/delete_status
GET /_synapse/admin/v2/users
GET/PUT /_synapse/admin/v2/users/{user_id}
POST /_synapse/admin/v2/users/{user_id}/delete_devices
GET /_synapse/admin/v2/users/{user_id}/devices
GET/PUT/DELETE /_synapse/admin/v2/users/{user_id}/devices/{device_id}
Delegated auth & OIDC (19)
GET /.well-known/openid-configuration
GET /_matrix/client/unstable/org.matrix.msc2965/auth_metadata
GET /_matrix/client/v1/auth_metadata
POST /_synapse/mas/allow_cross_signing_reset
POST /_synapse/mas/delete_device
POST /_synapse/mas/delete_user
GET /_synapse/mas/is_localpart_available
POST /_synapse/mas/provision_user
GET /_synapse/mas/query_user
POST /_synapse/mas/reactivate_user
POST /_synapse/mas/set_displayname
POST /_synapse/mas/sync_devices
POST /_synapse/mas/unset_displayname
POST /_synapse/mas/update_device_display_name
POST /_synapse/mas/upsert_device
GET/POST /oauth2/authorize
POST /oauth2/registration
POST /oauth2/revoke
POST /oauth2/token
Appservices (2)
POST /_matrix/client/v1/appservice/fed_proxy
POST /_matrix/client/v1/appservice/{appservice_id}/ping
VoIP & MatrixRTC (11)
GET /_matrix/client/unstable/org.matrix.msc4140/delayed_events
POST/GET /_matrix/client/unstable/org.matrix.msc4140/delayed_events/{delay_id}
POST /_matrix/client/unstable/org.matrix.msc4140/delayed_events/{delay_id}/{action}
PUT /_matrix/client/unstable/org.matrix.msc4140/rooms/{room_id}/delayed_event/{event_type}/{txn_id}
GET /_matrix/client/unstable/org.matrix.msc4143/rtc/transports
GET /_matrix/client/v1/rtc/transports
POST /_matrix/client/v3/user/{user_id}/openid/request_token
GET /_matrix/client/v3/voip/turnServer
GET /_matrix/federation/v1/openid/userinfo
POST /_spindle/rtc/livekit/sfu/get
POST /_spindle/rtc/livekit/sfu/webhook
Key backup (5)
PUT/GET/DELETE /_matrix/client/v3/room_keys/keys
PUT/GET/DELETE /_matrix/client/v3/room_keys/keys/{room_id}
PUT/GET/DELETE /_matrix/client/v3/room_keys/keys/{room_id}/{session_id}
POST/GET /_matrix/client/v3/room_keys/version
GET/PUT/DELETE /_matrix/client/v3/room_keys/version/{version}
Federation (29)
POST /_matrix/federation/unstable/io.element.msc4195/rtc/livekit/get_token
GET /_matrix/federation/v1/backfill/{room_id}
GET /_matrix/federation/v1/event/{event_id}
GET /_matrix/federation/v1/event_auth/{room_id}/{event_id}
POST /_matrix/federation/v1/get_missing_events/{room_id}
GET /_matrix/federation/v1/hierarchy/{room_id}
GET /_matrix/federation/v1/make_join/{room_id}/{user_id}
GET /_matrix/federation/v1/make_knock/{room_id}/{user_id}
GET /_matrix/federation/v1/make_leave/{room_id}/{user_id}
GET /_matrix/federation/v1/media/download/{media_id}
GET /_matrix/federation/v1/media/thumbnail/{media_id}
GET/POST /_matrix/federation/v1/publicRooms
GET /_matrix/federation/v1/query/directory
GET /_matrix/federation/v1/query/profile
POST /_matrix/federation/v1/rtc/livekit/get_token
PUT /_matrix/federation/v1/send/{txn_id}
PUT /_matrix/federation/v1/send_join/{room_id}/{event_id}
PUT /_matrix/federation/v1/send_knock/{room_id}/{event_id}
PUT /_matrix/federation/v1/send_leave/{room_id}/{event_id}
GET /_matrix/federation/v1/state/{room_id}
GET /_matrix/federation/v1/state_ids/{room_id}
GET /_matrix/federation/v1/timestamp_to_event/{room_id}
GET /_matrix/federation/v1/user/devices/{user_id}
POST /_matrix/federation/v1/user/keys/claim
POST /_matrix/federation/v1/user/keys/query
GET /_matrix/federation/v1/version
PUT /_matrix/federation/v2/invite/{room_id}/{event_id}
PUT /_matrix/federation/v2/send_join/{room_id}/{event_id}
PUT /_matrix/federation/v2/send_leave/{room_id}/{event_id}
End-to-end encryption (7)
GET /_matrix/client/v3/keys/changes
POST /_matrix/client/v3/keys/claim
POST /_matrix/client/v3/keys/device_signing/upload
POST /_matrix/client/v3/keys/query
POST /_matrix/client/v3/keys/signatures/upload
POST /_matrix/client/v3/keys/upload
PUT /_matrix/client/v3/sendToDevice/{event_type}/{txn_id}
Sync (2)
POST /_matrix/client/unstable/org.matrix.simplified_msc3575/sync
GET /_matrix/client/v3/sync
Account data, filters & push (10)
GET /_matrix/client/v3/pushrules/
GET/PUT/DELETE /_matrix/client/v3/pushrules/{scope}/{kind}/{rule_id}
GET/PUT /_matrix/client/v3/pushrules/{scope}/{kind}/{rule_id}/actions
GET/PUT /_matrix/client/v3/pushrules/{scope}/{kind}/{rule_id}/enabled
GET/PUT /_matrix/client/v3/user/{user_id}/account_data/{event_type}
POST /_matrix/client/v3/user/{user_id}/filter
GET /_matrix/client/v3/user/{user_id}/filter/{filter_id}
GET/PUT /_matrix/client/v3/user/{user_id}/rooms/{room_id}/account_data/{event_type}
GET /_matrix/client/v3/user/{user_id}/rooms/{room_id}/tags
PUT/DELETE /_matrix/client/v3/user/{user_id}/rooms/{room_id}/tags/{tag}
Media (8)
GET /_matrix/client/v1/media/config
GET /_matrix/client/v1/media/download/{server_name}/{media_id}
GET /_matrix/client/v1/media/download/{server_name}/{media_id}/{file_name}
GET /_matrix/client/v1/media/preview_url
GET /_matrix/client/v1/media/thumbnail/{server_name}/{media_id}
GET /_matrix/media/v3/config
POST /_matrix/media/v3/upload
PUT /_matrix/media/v3/upload/{server_name}/{media_id}
Timeline, messaging & search (13)
GET /_matrix/client/v1/rooms/{room_id}/relations/{event_id}
GET /_matrix/client/v1/rooms/{room_id}/relations/{event_id}/{rel_type}
GET /_matrix/client/v1/rooms/{room_id}/relations/{event_id}/{rel_type}/{event_type}
GET /_matrix/client/v3/notifications
GET /_matrix/client/v3/rooms/{room_id}/context/{event_id}
GET /_matrix/client/v3/rooms/{room_id}/event/{event_id}
GET /_matrix/client/v3/rooms/{room_id}/messages
POST /_matrix/client/v3/rooms/{room_id}/read_markers
POST /_matrix/client/v3/rooms/{room_id}/receipt/{receipt_type}/{event_id}
PUT /_matrix/client/v3/rooms/{room_id}/redact/{event_id}/{txn_id}
PUT /_matrix/client/v3/rooms/{room_id}/send/{event_type}/{txn_id}
PUT /_matrix/client/v3/rooms/{room_id}/typing/{user_id}
POST /_matrix/client/v3/search
Rooms & membership (27)
GET /_matrix/client/unstable/im.nheko.summary/rooms/{room_id_or_alias}/summary
GET /_matrix/client/v1/room_summary/{room_id_or_alias}
POST /_matrix/client/v3/createRoom
GET/PUT /_matrix/client/v3/directory/list/room/{room_id}
GET/PUT/DELETE /_matrix/client/v3/directory/room/{room_alias}
POST /_matrix/client/v3/join/{room_id_or_alias}
GET /_matrix/client/v3/joined_rooms
POST /_matrix/client/v3/knock/{room_id_or_alias}
GET /_matrix/client/v3/rooms/{room_id}/aliases
POST /_matrix/client/v3/rooms/{room_id}/ban
PUT /_matrix/client/v3/rooms/{room_id}/delayed_event/{event_type}/{txn_id}
POST /_matrix/client/v3/rooms/{room_id}/forget
POST /_matrix/client/v3/rooms/{room_id}/invite
GET /_matrix/client/v3/rooms/{room_id}/is_joined
POST /_matrix/client/v3/rooms/{room_id}/join
GET /_matrix/client/v3/rooms/{room_id}/joined_members
POST /_matrix/client/v3/rooms/{room_id}/kick
POST /_matrix/client/v3/rooms/{room_id}/leave
GET /_matrix/client/v3/rooms/{room_id}/members
POST /_matrix/client/v3/rooms/{room_id}/report
POST /_matrix/client/v3/rooms/{room_id}/report/{event_id}
GET /_matrix/client/v3/rooms/{room_id}/state
GET/PUT /_matrix/client/v3/rooms/{room_id}/state/{event_type}
GET/PUT /_matrix/client/v3/rooms/{room_id}/state/{event_type}/
GET/PUT /_matrix/client/v3/rooms/{room_id}/state/{event_type}/{state_key}
POST /_matrix/client/v3/rooms/{room_id}/unban
POST /_matrix/client/v3/rooms/{room_id}/upgrade
Profiles & presence (5)
GET/PUT /_matrix/client/v3/presence/{user_id}/status
GET /_matrix/client/v3/profile/{user_id}
GET/PUT /_matrix/client/v3/profile/{user_id}/avatar_url
GET/PUT /_matrix/client/v3/profile/{user_id}/displayname
GET/PUT/DELETE /_matrix/client/v3/profile/{user_id}/{key}
Accounts, devices & auth (13)
GET /_matrix/client/v3/account/3pid
POST /_matrix/client/v3/account/deactivate
POST /_matrix/client/v3/account/password
GET /_matrix/client/v3/account/whoami
POST /_matrix/client/v3/delete_devices
GET /_matrix/client/v3/devices
GET/PUT/DELETE /_matrix/client/v3/devices/{device_id}
GET/POST /_matrix/client/v3/login
POST /_matrix/client/v3/logout
POST /_matrix/client/v3/logout/all
POST /_matrix/client/v3/refresh
POST /_matrix/client/v3/register
GET /_matrix/client/v3/register/available
Server, discovery & operations (52)
GET /.well-known/matrix/client
GET /.well-known/matrix/server
GET /.well-known/matrix/support
POST /_matrix/client/unstable/io.element.msc4195/rtc/livekit/delegate_delayed_leave
POST /_matrix/client/unstable/io.element.msc4195/rtc/livekit/get_token
GET /_matrix/client/unstable/io.element.msc4502/rooms/{room_id}/is_joined
POST /_matrix/client/unstable/io.element.msc4512/appservice/fed_proxy
GET/PUT/DELETE /_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device
POST /_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/{device_id}/events
POST /_matrix/client/unstable/org.matrix.msc4108/rendezvous
GET/PUT /_matrix/client/v1/admin/lock/{user_id}
GET/PUT /_matrix/client/v1/admin/suspend/{user_id}
GET /_matrix/client/v1/delayed_events/{delay_id}
POST /_matrix/client/v1/delayed_events/{delay_id}/{action}
POST /_matrix/client/v1/login/get_token
GET /_matrix/client/v1/mutual_rooms
GET /_matrix/client/v1/register/m.login.registration_token/validity
GET /_matrix/client/v1/rooms/{room_id}/hierarchy
GET /_matrix/client/v1/rooms/{room_id}/threads
GET /_matrix/client/v1/rooms/{room_id}/timestamp_to_event
GET /_matrix/client/v3/admin/whois/{user_id}
GET /_matrix/client/v3/capabilities
GET/POST /_matrix/client/v3/publicRooms
GET /_matrix/client/v3/pushers
POST /_matrix/client/v3/pushers/set
POST /_matrix/client/v3/rtc/livekit/delegate_delayed_leave
POST /_matrix/client/v3/rtc/livekit/get_token
POST /_matrix/client/v3/user_directory/search
POST /_matrix/client/v3/users/{user_id}/report
GET /_matrix/client/versions
POST /_matrix/key/v2/query
GET /_matrix/key/v2/query/{server_name}
GET /_matrix/key/v2/server
POST /_matrix/media/v1/create
GET/PUT/DELETE /_synapse/client/rendezvous/{session_id}
GET /account
GET /account/
POST /account/deactivate
POST /account/emails/add
POST /account/emails/remove
GET/POST /account/emails/verify
GET/POST /account/login
POST /account/logout
POST /account/password
GET/POST /account/password/forgot
GET/POST /account/password/reset
POST /account/profile
GET/POST /account/recover
POST /account/recovery/generate
POST /account/sessions/end
GET /health
GET /ready