phantom
Documentation menu

Admin API

/_phantom/admin/v1 is JSON over HTTP. Every route takes an access token in Authorization: Bearer …, and its owner must be an admin — a member of #admins. A missing or unknown token answers M_MISSING_TOKEN or M_UNKNOWN_TOKEN; anyone else gets M_FORBIDDEN.

TOKEN=$(curl -s -X POST localhost:8008/_matrix/client/v3/login \
  -d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"ada"},"password":"…"}' \
  | jq -r .access_token)
 
curl -H "Authorization: Bearer $TOKEN" localhost:8008/_phantom/admin/v1/whoami

Reading

RouteReturns
GET /whoamithe admin and server name
GET /statsuptime, user, room, media and database figures, registration, login methods, the last backup
GET /userslocal accounts, deactivated ones included
GET /devicesevery local device
GET /registration_tokenstokens; the config file's is masked
GET /roomsevery room the server knows
GET /appservicesregistrations, never their tokens
GET /settingsthe running config, secrets masked
GET /tasksthe week's long jobs, newest first
GET /servicesservices and their workers
GET /federationservers sharing a room, backoff, last contact
GET /mediathe media store
GET /logs?limit=recent log lines, newest first
GET /reportsopen abuse reports
GET /federation/blocksthe config's and the runtime server block patterns
GET /media/quarantinequarantined media

Changing

RouteDoes
POST /users/{user}/deactivatedeactivate; body {"erase": true} also wipes its data
PUT /users/{user}/password{"password": "…", "logout_devices": true}
PUT / DELETE /users/{user}/admingrant / revoke admin
DELETE /devices/{user}/{device}sign a device out
POST /registration_tokens{"token"?, "uses_allowed"?, "expires_in_secs"?}, answers the token
DELETE /registration_tokens/{token}revoke a database token
PUT / DELETE /rooms/{room}/banban / unban
POST /rooms/{room}/shutdownevict local members; answers {"task_id"}
DELETE /rooms/{room}shut down and purge; answers {"task_id"}
DELETE /media/{server}/{media_id}delete a file
DELETE /federation/{server}/mediadelete a remote server's cached media
DELETE /reports/{id}dismiss a report
POST / DELETE /federation/blocks{"server"} or {"pattern"} (a regex), optional "reason": block / unblock
PUT / DELETE /media/{server}/{media_id}/quarantinequarantine / lift; optional {"reason"}
POST /rooms/{room}/media/quarantinequarantine every file the room names; answers {"task_id"}
POST /users/{user}/media/quarantinequarantine every file a local user uploaded
POST /rooms/{room}/purge_history{"before_ts_ms"} or {"before_event_id"}, "include_local"?; answers {"task_id"}
POST /media/purge{"origin": "remote"|"local", "older_than_days"}; answers {"task_id"}
POST /config/reloadreload the config
POST /backupback up into database_backup_path; answers {"task_id"}

An empty body counts as {}. Path segments are URL-encoded, so a room ID's ! is %21.

Unauthenticated

GET /_phantom/server_version names the software and version, and GET /_phantom/local_user_count counts local users when federation is on.