dynamic_configuration renaming
[akkoma] / docs / API / admin_api.md
index ee9e68cb1456c79c3231fa9a259e9dddbdfbbacb..f2a0906b8eb832b4479aee4228b3db7fc7c08f76 100644 (file)
@@ -2,11 +2,17 @@
 
 Authentication is required and the user must be an admin.
 
-## `/api/pleroma/admin/users`
+Configuration options:
+
+* `[:auth, :enforce_oauth_admin_scope_usage]` — OAuth admin scope requirement toggle.
+    If `true`, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes).
+    If `false` and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions.
+    Note that client app needs to explicitly support admin scopes and request them when obtaining auth token.
+
+## `GET /api/pleroma/admin/users`
 
 ### List users
 
-- Method `GET`
 - Query Params:
   - *optional* `query`: **string** search term (e.g. nickname, domain, nickname@domain)
   - *optional* `filters`: **string** comma-separated string of filters:
@@ -47,15 +53,22 @@ Authentication is required and the user must be an admin.
 }
 ```
 
-## `/api/pleroma/admin/users`
+## DEPRECATED `DELETE /api/pleroma/admin/users`
 
 ### Remove a user
 
-- Method `DELETE`
 - Params:
   - `nickname`
 - Response: User’s nickname
 
+## `DELETE /api/pleroma/admin/users`
+
+### Remove a user
+
+- Params:
+  - `nicknames`
+- Response: Array of user nicknames
+
 ### Create a user
 
 - Method: `POST`
@@ -69,31 +82,30 @@ Authentication is required and the user must be an admin.
   ]
 - Response: User’s nickname
 
-## `/api/pleroma/admin/users/follow`
+## `POST /api/pleroma/admin/users/follow`
+
 ### Make a user follow another user
 
-- Methods: `POST`
 - Params:
- - `follower`: The nickname of the follower
- - `followed`: The nickname of the followed
 - `follower`: The nickname of the follower
 - `followed`: The nickname of the followed
 - Response:
- - "ok"
+  - "ok"
+
+## `POST /api/pleroma/admin/users/unfollow`
 
-## `/api/pleroma/admin/users/unfollow`
 ### Make a user unfollow another user
 
-- Methods: `POST`
 - Params:
- - `follower`: The nickname of the follower
- - `followed`: The nickname of the followed
 - `follower`: The nickname of the follower
 - `followed`: The nickname of the followed
 - Response:
- - "ok"
 - "ok"
 
-## `/api/pleroma/admin/users/:nickname/toggle_activation`
+## `PATCH /api/pleroma/admin/users/:nickname/toggle_activation`
 
 ### Toggle user activation
 
-- Method: `PATCH`
 - Params:
   - `nickname`
 - Response: User’s object
@@ -106,27 +118,26 @@ Authentication is required and the user must be an admin.
 }
 ```
 
-## `/api/pleroma/admin/users/tag`
+## `PUT /api/pleroma/admin/users/tag`
 
 ### Tag a list of users
 
-- Method: `PUT`
 - Params:
   - `nicknames` (array)
   - `tags` (array)
 
+## `DELETE /api/pleroma/admin/users/tag`
+
 ### Untag a list of users
 
-- Method: `DELETE`
 - Params:
   - `nicknames` (array)
   - `tags` (array)
 
-## `/api/pleroma/admin/users/:nickname/permission_group`
+## `GET /api/pleroma/admin/users/:nickname/permission_group`
 
 ### Get user user permission groups membership
 
-- Method: `GET`
 - Params: none
 - Response:
 
@@ -137,13 +148,12 @@ Authentication is required and the user must be an admin.
 }
 ```
 
-## `/api/pleroma/admin/users/:nickname/permission_group/:permission_group`
+## `GET /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
 
 Note: Available `:permission_group` is currently moderator and admin. 404 is returned when the permission group doesn’t exist.
 
 ### Get user user permission groups membership per permission group
 
-- Method: `GET`
 - Params: none
 - Response:
 
@@ -154,48 +164,98 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 }
 ```
 
-### Add user in permission group
+## DEPRECATED `POST /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
+
+### Add user to permission group
 
-- Method: `POST`
 - Params: none
 - Response:
   - On failure: `{"error": "…"}`
-  - On success: JSON of the `user.info`
+  - On success: JSON of the user
+
+## `POST /api/pleroma/admin/users/permission_group/:permission_group`
+
+### Add users to permission group
+
+- Params:
+  - `nicknames`: nicknames array
+- Response:
+  - On failure: `{"error": "…"}`
+  - On success: JSON of the user
+
+## DEPRECATED `DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
+
+## `DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
 
 ### Remove user from permission group
 
-- Method: `DELETE`
 - Params: none
 - Response:
   - On failure: `{"error": "…"}`
-  - On success: JSON of the `user.info`
+  - On success: JSON of the user
 - Note: An admin cannot revoke their own admin status.
 
-## `/api/pleroma/admin/users/:nickname/activation_status`
+## `DELETE /api/pleroma/admin/users/permission_group/:permission_group`
 
-### Active or deactivate a user
+### Remove users from permission group
 
-- Method: `PUT`
 - Params:
-  - `nickname`
-  - `status` BOOLEAN field, false value means deactivation.
+  - `nicknames`: nicknames array
+- Response:
+  - On failure: `{"error": "…"}`
+  - On success: JSON of the user
+- Note: An admin cannot revoke their own admin status.
+
+## `PATCH /api/pleroma/admin/users/activate`
+
+### Activate user
+
+- Params:
+  - `nicknames`: nicknames array
+- Response:
+
+```json
+{
+  users: [
+    {
+      // user object
+    }
+  ]
+}
+```
+
+## `PATCH /api/pleroma/admin/users/deactivate`
 
-## `/api/pleroma/admin/users/:nickname_or_id`
+### Deactivate user
+
+- Params:
+  - `nicknames`: nicknames array
+- Response:
+
+```json
+{
+  users: [
+    {
+      // user object
+    }
+  ]
+}
+```
+
+## `GET /api/pleroma/admin/users/:nickname_or_id`
 
 ### Retrive the details of a user
 
-- Method: `GET`
 - Params:
   - `nickname` or `id`
 - Response:
   - On failure: `Not found`
   - On success: JSON of the user
 
-## `/api/pleroma/admin/users/:nickname_or_id/statuses`
+## `GET /api/pleroma/admin/users/:nickname_or_id/statuses`
 
 ### Retrive user's latest statuses
 
-- Method: `GET`
 - Params:
   - `nickname` or `id`
   - *optional* `page_size`: number of statuses to return (default is `20`)
@@ -204,29 +264,36 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
   - On failure: `Not found`
   - On success: JSON array of user's latest statuses
 
-## `/api/pleroma/admin/relay`
+## `POST /api/pleroma/admin/relay`
 
 ### Follow a Relay
 
-- Methods: `POST`
 - Params:
   - `relay_url`
 - Response:
   - On success: URL of the followed relay
 
+## `DELETE /api/pleroma/admin/relay`
+
 ### Unfollow a Relay
 
-- Methods: `DELETE`
 - Params:
   - `relay_url`
 - Response:
   - On success: URL of the unfollowed relay
 
-## `/api/pleroma/admin/users/invite_token`
+## `GET /api/pleroma/admin/relay`
+
+### List Relays
+
+- Params: none
+- Response:
+  - On success: JSON array of relays
+
+## `POST /api/pleroma/admin/users/invite_token`
 
 ### Create an account registration invite token
 
-- Methods: `POST`
 - Params:
   - *optional* `max_use` (integer)
   - *optional* `expires_at` (date string e.g. "2019-04-07")
@@ -244,11 +311,10 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 }
 ```
 
-## `/api/pleroma/admin/users/invites`
+## `GET /api/pleroma/admin/users/invites`
 
 ### Get a list of generated invites
 
-- Methods: `GET`
 - Params: none
 - Response:
 
@@ -270,11 +336,10 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 }
 ```
 
-## `/api/pleroma/admin/users/revoke_invite`
+## `POST /api/pleroma/admin/users/revoke_invite`
 
 ### Revoke invite by token
 
-- Methods: `POST`
 - Params:
   - `token`
 - Response:
@@ -292,21 +357,18 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 }
 ```
 
-
-## `/api/pleroma/admin/users/email_invite`
+## `POST /api/pleroma/admin/users/email_invite`
 
 ### Sends registration invite via email
 
-- Methods: `POST`
 - Params:
   - `email`
   - `name`, optional
 
-## `/api/pleroma/admin/users/:nickname/password_reset`
+## `GET /api/pleroma/admin/users/:nickname/password_reset`
 
 ### Get a password reset token for a given nickname
 
-- Methods: `GET`
 - Params: none
 - Response:
 
@@ -317,18 +379,18 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 }
 ```
 
-
-## `/api/pleroma/admin/users/:nickname/force_password_reset`
+## `PATCH /api/pleroma/admin/users/force_password_reset`
 
 ### Force passord reset for a user with a given nickname
 
-- Methods: `PATCH`
-- Params: none
+- Params:
+  - `nicknames`
 - Response: none (code `204`)
 
-## `/api/pleroma/admin/reports`
+## `GET /api/pleroma/admin/reports`
+
 ### Get a list of reports
-- Method `GET`
+
 - Params:
   - *optional* `state`: **string** the state of reports. Valid values are `open`, `closed` and `resolved`
   - *optional* `limit`: **integer** the number of records to retrieve
@@ -343,7 +405,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 
 ```json
 {
-  "total" : 1,
+  "totalReports" : 1,
   "reports": [
     {
       "account": {
@@ -485,9 +547,34 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 }
 ```
 
-## `/api/pleroma/admin/reports/:id`
+## `GET /api/pleroma/admin/grouped_reports`
+
+### Get a list of reports, grouped by status
+
+- Params: none
+- On success: JSON, returns a list of reports, where:
+  - `date`: date of the latest report
+  - `account`: the user who has been reported (see `/api/pleroma/admin/reports` for reference)
+  - `status`: reported status (see `/api/pleroma/admin/reports` for reference)
+  - `actors`: users who had reported this status (see `/api/pleroma/admin/reports` for reference)
+  - `reports`: reports (see `/api/pleroma/admin/reports` for reference)
+
+```json
+  "reports": [
+    {
+      "date": "2019-10-07T12:31:39.615149Z",
+      "account": { ... },
+      "status": { ... },
+      "actors": [{ ... }, { ... }],
+      "reports": [{ ... }]
+    }
+  ]
+```
+
+## `GET /api/pleroma/admin/reports/:id`
+
 ### Get an individual report
-- Method `GET`
+
 - Params:
   - `id`
 - Response:
@@ -496,94 +583,65 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
     - 404 Not Found `"Not found"`
   - On success: JSON, Report object (see above)
 
-## `/api/pleroma/admin/reports/:id`
-### Change the state of the report
-- Method `PUT`
+## `PATCH /api/pleroma/admin/reports`
+
+### Change the state of one or multiple reports
+
 - Params:
-  - `id`
-  - `state`: required, the new state. Valid values are `open`, `closed` and `resolved`
+
+```json
+  `reports`: [
+    {
+      `id`, // required, report id
+      `state` // required, the new state. Valid values are `open`, `closed` and `resolved`
+    },
+    ...
+  ]
+```
+
 - Response:
   - On failure:
-    - 400 Bad Request `"Unsupported state"`
-    - 403 Forbidden `{"error": "error_msg"}`
-    - 404 Not Found `"Not found"`
-  - On success: JSON, Report object (see above)
+    - 400 Bad Request, JSON:
+
+    ```json
+      [
+        {
+          `id`, // report id
+          `error` // error message
+        }
+      ]
+    ```
+
+  - On success: `204`, empty response
+
+## `POST /api/pleroma/admin/reports/:id/notes`
+
+### Create report note
 
-## `/api/pleroma/admin/reports/:id/respond`
-### Respond to a report
-- Method `POST`
 - Params:
-  - `id`
-  - `status`: required, the message
+  - `id`: required, report id
+  - `content`: required, the message
 - Response:
   - On failure:
     - 400 Bad Request `"Invalid parameters"` when `status` is missing
-    - 403 Forbidden `{"error": "error_msg"}`
-    - 404 Not Found `"Not found"`
-  - On success: JSON, created Mastodon Status entity
+  - On success: `204`, empty response
 
-```json
-{
-  "account": { ... },
-  "application": {
-    "name": "Web",
-    "website": null
-  },
-  "bookmarked": false,
-  "card": null,
-  "content": "Your claim is going to be closed",
-  "created_at": "2019-05-11T17:13:03.000Z",
-  "emojis": [],
-  "favourited": false,
-  "favourites_count": 0,
-  "id": "9ihuiSL1405I65TmEq",
-  "in_reply_to_account_id": null,
-  "in_reply_to_id": null,
-  "language": null,
-  "media_attachments": [],
-  "mentions": [
-    {
-      "acct": "user",
-      "id": "9i6dAJqSGSKMzLG2Lo",
-      "url": "https://pleroma.example.org/users/user",
-      "username": "user"
-    },
-    {
-      "acct": "admin",
-      "id": "9hEkA5JsvAdlSrocam",
-      "url": "https://pleroma.example.org/users/admin",
-      "username": "admin"
-    }
-  ],
-  "muted": false,
-  "pinned": false,
-  "pleroma": {
-    "content": {
-      "text/plain": "Your claim is going to be closed"
-    },
-    "conversation_id": 35,
-    "in_reply_to_account_acct": null,
-    "local": true,
-    "spoiler_text": {
-      "text/plain": ""
-    }
-  },
-  "reblog": null,
-  "reblogged": false,
-  "reblogs_count": 0,
-  "replies_count": 0,
-  "sensitive": false,
-  "spoiler_text": "",
-  "tags": [],
-  "uri": "https://pleroma.example.org/objects/cab0836d-9814-46cd-a0ea-529da9db5fcb",
-  "url": "https://pleroma.example.org/notice/9ihuiSL1405I65TmEq",
-  "visibility": "direct"
-}
-```
+## `POST /api/pleroma/admin/reports/:report_id/notes/:id`
+
+### Delete report note
+
+- Params:
+  - `report_id`: required, report id
+  - `id`: required, note id
+- Response:
+  - On failure:
+    - 400 Bad Request `"Invalid parameters"` when `status` is missing
+  - On success: `204`, empty response
+
+## `PUT /api/pleroma/admin/statuses/:id`
 
-## `/api/pleroma/admin/statuses/:id`
 ### Change the scope of an individual reported status
-- Method `PUT`
+
 - Params:
   - `id`
   - `sensitive`: optional, valid values are `true` or `false`
@@ -595,9 +653,10 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
     - 404 Not Found `"Not found"`
   - On success: JSON, Mastodon Status entity
 
-## `/api/pleroma/admin/statuses/:id`
+## `DELETE /api/pleroma/admin/statuses/:id`
+
 ### Delete an individual reported status
-- Method `DELETE`
+
 - Params:
   - `id`
 - Response:
@@ -606,89 +665,141 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
     - 404 Not Found `"Not found"`
   - On success: 200 OK `{}`
 
+## `GET /api/pleroma/admin/config/migrate_from_db`
 
-## `/api/pleroma/admin/config/migrate_to_db`
-### Run mix task pleroma.config migrate_to_db
-Copy settings on key `:pleroma` to DB.
-- Method `GET`
-- Params: none
-- Response:
+### Run mix task pleroma.config migrate_from_db
 
-```json
-{}
-```
+Copies all settings from database to `config/{env}.exported_from_db.secret.exs` with deletion from the table. Where `{env}` is the environment in which `pleroma` is running.
 
-## `/api/pleroma/admin/config/migrate_from_db`
-### Run mix task pleroma.config migrate_from_db
-Copy all settings from DB to `config/prod.exported_from_db.secret.exs` with deletion from DB.
-- Method `GET`
 - Params: none
 - Response:
+  - On failure:
+    - 400 Bad Request `"To use this endpoint you need to enable dynamic configuration."`
 
 ```json
 {}
 ```
 
-## `/api/pleroma/admin/config`
-### List config settings
-List config settings only works with `:pleroma => :instance => :dynamic_configuration` setting to `true`.
-- Method `GET`
+## `GET /api/pleroma/admin/config`
+
+### Get saved config settings
+
+**Only works when configuration from database is enabled.**
+
 - Params: none
 - Response:
+  - On failure:
+    - 400 Bad Request `"To use this endpoint you need to enable dynamic configuration."`
+    - 400 Bad Request `"To use dynamic configuration migrate your settings to database."`
 
 ```json
 {
   configs: [
     {
-      "group": string,
-      "key": string or string with leading `:` for atoms,
-      "value": string or {} or [] or {"tuple": []}
+      "group": ":pleroma",
+      "key": "Pleroma.Upload",
+      "value": []
      }
   ]
 }
 ```
 
-## `/api/pleroma/admin/config`
+## `POST /api/pleroma/admin/config`
+
 ### Update config settings
-Updating config settings only works with `:pleroma => :instance => :dynamic_configuration` setting to `true`.
-Module name can be passed as string, which starts with `Pleroma`, e.g. `"Pleroma.Upload"`.
-Atom keys and values can be passed with `:` in the beginning, e.g. `":upload"`.
-Tuples can be passed as `{"tuple": ["first_val", Pleroma.Module, []]}`.
-`{"tuple": ["some_string", "Pleroma.Some.Module", []]}` will be converted to `{"some_string", Pleroma.Some.Module, []}`.
-Keywords can be passed as lists with 2 child tuples, e.g.
-`[{"tuple": ["first_val", Pleroma.Module]}, {"tuple": ["second_val", true]}]`.
-
-If value contains list of settings `[subkey: val1, subkey2: val2, subkey3: val3]`, it's possible to remove only subkeys instead of all settings passing `subkeys` parameter. E.g.:
-{"group": "pleroma", "key": "some_key", "delete": "true", "subkeys": [":subkey", ":subkey3"]}.
-
-Compile time settings (need instance reboot):
-- all settings by this keys:
+
+**Only works when configuration from database is enabled.**
+
+Some modifications are necessary to save the config settings correctly:
+
+- strings which start with `Pleroma.`, `Phoenix.`, `Tesla.` or strings like `Oban`, `Ueberauth` will be converted to modules;
+```
+"Pleroma.Upload" -> Pleroma.Upload
+"Oban" -> Oban
+```
+- strings starting with `:` will be converted to atoms;
+```
+":pleroma" -> :pleroma
+```
+- objects with `tuple` key and array value will be converted to atoms;
+```
+{"tuple": ["string", "Pleroma.Upload", []]} -> {"string", Pleroma.Upload, []}
+```
+- arrays with *tuple objects* and 2 childs in array will be converted to keywords;
+```
+[{"tuple": [":key1", "value"]}, {"tuple": [":key2", "value"]}] -> [key1: "value", key2: "value"]
+```
+
+Most of the settings will be applied in `runtime`, this means that you don't need to restart the instance. But some settings are applied in `compile time` and require a reboot of the instance, such as:
+- all settings inside these keys:
   - `:hackney_pools`
   - `:chat`
   - `Pleroma.Web.Endpoint`
-  - `Pleroma.Repo`
-- part settings:
-  - `Pleroma.Captcha` -> `:seconds_valid`
-  - `Pleroma.Upload` -> `:proxy_remote`
-  - `:instance` -> `:upload_limit`
+- partially settings inside these keys:
+  - `:seconds_valid` in `Pleroma.Captcha`
+  - `:proxy_remote` in `Pleroma.Upload`
+  - `:upload_limit` in `:instance`
 
-- Method `POST`
 - Params:
-  - `configs` => [
-    - `group` (string)
-    - `key` (string or string with leading `:` for atoms)
-    - `value` (string, [], {} or {"tuple": []})
-    - `delete` = true (optional, if parameter must be deleted)
-    - `subkeys` [(string with leading `:` for atoms)] (optional, works only if `delete=true` parameter is passed, otherwise will be ignored)
+  - `configs` - array of config objects
+  - config object params:
+    - `group` - string (**required**)
+    - `key` - string (**required**)
+    - `value` - string, [], {} or {"tuple": []} (**required**)
+    - `delete` - true (*optional*, if setting must be deleted)
+    - `subkeys` - array of strings (*optional*, only works when `delete=true` parameter is passed, otherwise will be ignored)
+
+*When a value have several nested settings, you can delete only some nested settings by passing a parameter `subkeys`, without deleting all settings by key.*
+```
+[subkey: val1, subkey2: val2, subkey3: val3] \\ initial value
+{"group": ":pleroma", "key": "some_key", "delete": true, "subkeys": [":subkey", ":subkey3"]} \\ passing json for deletion
+[subkey2: val2] \\ value after deletion
+```
+
+*Most of the settings can be partially updated through merge old values with new values, except settings value of which is list or is not keyword.*
+
+Example of setting without keyword in value:
+```elixir
+config :tesla, :adapter, Tesla.Adapter.Hackney
+```
+
+List of settings which support only full update:
+```elixir
+@full_key_update [
+    {:pleroma, :ecto_repos},
+    {:pleroma, :assets},
+    {:quack, :meta},
+    {:mime, :types},
+    {:cors_plug, [:max_age, :methods, :expose, :headers]},
+    {:auto_linker, :opts},
+    {:swarm, :node_blacklist},
+    {:logger, :backends}
   ]
+```
 
-- Request (example):
+*Settings without explicit key must be sended in separate config object params.*
+```elixir
+config :quack,
+  level: :debug,
+  meta: [:all],
+  ...
+```
+```json
+{
+  configs: [
+    {"group": ":quack", "key": ":level", "value": ":debug"},
+    {"group": ":quack", "key": ":meta", "value": [":all"]},
+    ...
+  ]
+}
+```
+- Request:
 
 ```json
 {
   configs: [
     {
-      "group": "pleroma",
+      "group": ":pleroma",
       "key": "Pleroma.Upload",
       "value": [
         {"tuple": [":uploader", "Pleroma.Uploaders.Local"]},
@@ -698,7 +809,7 @@ Compile time settings (need instance reboot):
         {"tuple": [":proxy_opts", [
           {"tuple": [":redirect_on_failure", false]},
           {"tuple": [":max_body_length", 1048576]},
-          {"tuple": [":http": [
+          {"tuple": [":http", [
             {"tuple": [":follow_redirect", true]},
             {"tuple": [":pool", ":upload"]},
           ]]}
@@ -714,22 +825,57 @@ Compile time settings (need instance reboot):
 ```
 
 - Response:
-
+  - On failure:
+    - 400 Bad Request `"To use this endpoint you need to enable dynamic configuration."`
 ```json
 {
   configs: [
     {
-      "group": string,
-      "key": string or string with leading `:` for atoms,
-      "value": string or {} or [] or {"tuple": []}
+      "group": ":pleroma",
+      "key": "Pleroma.Upload",
+      "value": [...]
      }
   ]
 }
 ```
 
-## `/api/pleroma/admin/moderation_log`
+## ` GET /api/pleroma/admin/config/descriptions`
+
+### Get JSON with config descriptions.
+Loads json generated from `config/descriptions.exs`.
+
+- Params: none
+- Response:
+
+```json
+[{
+    "group": ":pleroma", // string
+    "key": "ModuleName", // string
+    "type": "group", // string or list with possible values,
+    "description": "Upload general settings", // string
+    "children": [
+      {
+        "key": ":uploader", // string or module name `Pleroma.Upload`
+        "type": "module",
+        "description": "Module which will be used for uploads",
+        "suggestions": ["module1", "module2"]
+      },
+      {
+        "key": ":filters",
+        "type": ["list", "module"],
+        "description": "List of filter modules for uploads",
+        "suggestions": [
+          "module1", "module2", "module3"
+        ]
+      }
+    ]
+}]
+```
+
+## `GET /api/pleroma/admin/moderation_log`
+
 ### Get moderation log
-- Method `GET`
+
 - Params:
   - *optional* `page`: **integer** page number
   - *optional* `page_size`: **integer** number of log entries per page (default is `50`)
@@ -756,8 +902,25 @@ Compile time settings (need instance reboot):
 ```
 
 ## `POST /api/pleroma/admin/reload_emoji`
+
 ### Reload the instance's custom emoji
-* Method `POST`
-* Authentication: required
-* Params: None
-* Response: JSON, "ok" and 200 status
+
+- Authentication: required
+- Params: None
+- Response: JSON, "ok" and 200 status
+
+## `PATCH /api/pleroma/admin/users/confirm_email`
+
+### Confirm users' emails
+
+- Params:
+  - `nicknames`
+- Response: Array of user nicknames
+
+## `PATCH /api/pleroma/admin/users/resend_confirmation_email`
+
+### Resend confirmation email
+
+- Params:
+  - `nicknames`
+- Response: Array of user nicknames