Parcourir la source

docs(api): align API docs with the protobuf definitions (#1156)

James Read il y a 16 heures
Parent
commit
5f6ef1953f

+ 3 - 2
docs/modules/ROOT/pages/api/intro.adoc

@@ -6,7 +6,7 @@ This section of the documentation is intended for developers, and those who want
 **Short version**: 
 
 * http://olivetinServer:1337/api on your OliveTin server to get the REST API. 
-* link:http://docs.olivetin.app/api/swagger/[Swagger] documents the API.
+* link:https://docs.olivetin.app/api/swagger/3k/[Swagger] documents the API.
 
 **Longer version**: The OliveTin API is formally defined using the Protobuf IDL, in link:https://github.com/OliveTin/OliveTin/tree/main/proto[the `proto/` directory of the OliveTin repository]. Server and client code is generated from that definition, and the API is served using link:https://connectrpc.com[Connect RPC].
 
@@ -20,7 +20,8 @@ The OliveTin API is completely machine readable - every method, request and resp
 * **Source of truth**: link:https://github.com/OliveTin/OliveTin/tree/main/proto[`proto/`] on GitHub - the service is `olivetin.api.v1.OliveTinApiService` in link:https://github.com/OliveTin/OliveTin/blob/main/proto/olivetin/api/v1/olivetin.proto[`olivetin/api/v1/olivetin.proto`].
 * **Generate a client**: use link:https://buf.build[buf] or `protoc` with the Connect, gRPC, or gRPC-Web plugins for your language of choice (Go, TypeScript, Python, Java, etc).
 * **Call it directly**: each RPC is available as `POST /api/<MethodName>` with a JSON body matching the request message, using protobuf JSON field names (lowerCamelCase, eg: `bindingId`).
-* **OpenAPI**: the Swagger / OpenAPI links below are also available for tools that prefer OpenAPI.
+* **HTTP method**: every RPC is called with `POST` - a `GET` request returns `405 Method Not Allowed`.
+* **OpenAPI**: the Swagger / OpenAPI links below are generated from the Protobuf files, and are also available for tools that prefer OpenAPI.
 
 == Links
 

+ 3 - 3
docs/modules/ROOT/pages/api/login.adoc

@@ -2,7 +2,7 @@
 
 OliveTin supports serveral different ways to login, and most installations will probably login via reverse proxy, or via local user login.
 
-To login via local user login, you can use the following API call: `/LocalUserLogin`. This is documented in the API documentation which can be found here; https://docs.olivetin.app/api/ 
+To login via local user login, you can use the following API call: `/LocalUserLogin`. This is documented in the xref:api/intro.adoc[API documentation].
 
 The API call is a POST request, and you need to provide a `username` and `password` as a JSON object in the body of the request. Here is an example of how you can login via a cURL request;
 
@@ -20,9 +20,9 @@ You can also that the body of the response is a JSON object with a simple `succe
 
 == Check login with `WhoAmI`
 
-You can check your current login status by using the `/WhoAmI` API call. This is a GET request, and you need to provide the `olivetin-sid-local` cookie in the request. Here is an example of how you can check your login status via a cURL request;
+You can check your current login status by using the `/WhoAmI` API call. Like all API methods, this is a POST request with a JSON body (an empty object is fine), and you need to provide the `olivetin-sid-local` cookie in the request. Here is an example of how you can check your login status via a cURL request;
 
 ```bash
-user@host: curl -X GET http://localhost:1337/api/WhoAmI -H "accept: application/json" -H 'Content-Type: application/json' -b "olivetin-sid-local=cd33aa9c-c613-473e-8581-2b742716ab8e"
+user@host: curl http://localhost:1337/api/WhoAmI --json '{}' -b "olivetin-sid-local=cd33aa9c-c613-473e-8581-2b742716ab8e"
 {"authenticatedUser":"admin", "usergroup":"", "provider":"local", "acls":[], "sid":""}
 ```

+ 7 - 5
docs/modules/ROOT/pages/api/method_StartAction.adoc

@@ -3,9 +3,11 @@
 This is the method the OliveTin web UI uses to start actions, and is probably the best method to use if you are writing scripts.
 
 * **HTTP Method**: `POST`
-* **Request Type**: OliveTin request object
+* **Request Type**: xref:api/start_action.adoc#api-request-startaction[StartAction request object] (`bindingId`, `arguments`, `uniqueTrackingId`, `justification`)
 * **Response Type**: Execution Tracking ID
 
+NOTE: `StartAction` selects the action with `bindingId`, not `actionId`. For a normal action, the binding ID is the same as the action `id` from your `config.yaml`. See xref:api/start_action.adoc#api-ids[Action IDs vs Binding IDs].
+
 There are several variants of this API call available which might be easier for scripts (or humans) to work with:
 
 include::partial$api/start_action_methods.adoc[]
@@ -15,14 +17,15 @@ include::partial$api/start_action_methods.adoc[]
 [source,bash]
 .curl
 ----
-user@host: curl "http://olivetin.webapps.teratan.lan/api/StartAction" --json '{"bindingId": "nuclear_reactor_shutdown"}'
+user@host: curl "http://olivetin.example.com:1337/api/StartAction" --json '{"bindingId": "nuclear_reactor_shutdown"}'
+{"executionTrackingId":"6ecda25d-b6e1-4621-898c-d4e6f2dbeda5"}
 ----
 
 [source,powershell]
 .Powershell
 ----
 PS C:\Users\xcons> $json = '{"bindingId": "deploy_attack_gnomes"}'
-PS C:\Users\xcons> Invoke-RestMethod -Method "Post" -Uri "http://olivetinServer:1337/api/StartAction" -Body $json 
+PS C:\Users\xcons> Invoke-RestMethod -Method "Post" -Uri "http://olivetinServer:1337/api/StartAction" -ContentType "application/json" -Body $json
 ----
 
 == Example API call: Start an action using `StartAction` with arguments
@@ -30,6 +33,5 @@ PS C:\Users\xcons> Invoke-RestMethod -Method "Post" -Uri "http://olivetinServer:
 [source,bash]
 .curl
 ----
-user:host: curl 'http://olivetin.example.com/api/StartAction' --json '{"bindingId": "Ping_host", "arguments": [{"name": "host", "value": "example.com"},{"name": "count", "value": "1"}]}'
+user@host: curl 'http://olivetin.example.com:1337/api/StartAction' --json '{"bindingId": "Ping_host", "arguments": [{"name": "host", "value": "example.com"},{"name": "count", "value": "1"}]}'
 ----
-

+ 12 - 2
docs/modules/ROOT/pages/api/method_StartActionAndWait.adoc

@@ -3,10 +3,20 @@
 This method is useful is you are writing a script, and want to wait for the action to finish so that you can check the result, or get the output.
 
 * **HTTP Method**: `POST`
-* **Request Type**: OliveTin request object
+* **Request Type**: xref:api/start_action.adoc#api-request-startactionandwait[StartActionAndWait request object] (`actionId`, `arguments`, `justification`)
 * **Response Type**: Log Entry (waits for the action to finish)
 
 There are several variants of this API call available which might be easier for scripts (or humans) to work with:
 
-
 include::partial$api/start_action_methods.adoc[]
+
+== Example API call: Start an action with arguments, and wait for it to finish
+
+[source,bash]
+.curl
+----
+user@host: curl 'http://olivetin.example.com:1337/api/StartActionAndWait' --json '{"actionId": "Ping_host", "arguments": [{"name": "host", "value": "example.com"}]}'
+{"logEntry":{"actionTitle":"Ping host","output":"...","exitCode":0, ... }}
+----
+
+See xref:api/start_action.adoc#api-response-logentry[Response type: LogEntry] for the full response.

+ 12 - 6
docs/modules/ROOT/pages/api/method_StartActionByGet.adoc

@@ -1,19 +1,25 @@
 = API Method: StartActionByGet
 
-This is the method that allows you to specify the action ID in the URL, and is probably the best to do quick integrations - QR Codes, streamdeck, etc. You cannot pass arguments using this method.
+This is the simplest method to start an action - you only need to send the action ID, which makes it a good fit for quick integrations (Stream Deck, Home Assistant, cron jobs, etc). You cannot pass arguments using this method.
 
-* **HTTP Method**: `GET`
-* **Request Type**: Action ID in the URL
+* **HTTP Method**: `POST`
+* **Request Type**: xref:api/start_action.adoc#api-request-actionid[Action ID only] (`actionId`)
 * **Response Type**: Execution Tracking ID
 
+[NOTE]
+====
+Despite the name, in OliveTin 3k this method is called with `POST` and a JSON body, the same as every other API method. The OliveTin 2k style of putting the action ID in the URL (eg: `GET /api/StartActionByGet/pingGithub`) is no longer supported and returns `404`.
+====
+
 include::partial$api/start_action_methods.adoc[]
 
-[#api-eg-startIdUrl]
-== Example API call; Start an action by ID in the URL
+[#api-eg-startActionId]
+== Example API call: Start an action by ID
 
 .curl
 ----
-user@host: curl http://olivetin.example.com/api/StartActionByGet/pingGithub
+user@host: curl http://olivetin.example.com:1337/api/StartActionByGet --json '{"actionId": "pingGithub"}'
+{"executionTrackingId":"ff7d6f13-af8f-4ebe-8174-ad4cc7197b45"}
 ----
 
 The corresponding config.yaml would look like this;

+ 18 - 3
docs/modules/ROOT/pages/api/method_StartActionByGetAndWait.adoc

@@ -1,11 +1,26 @@
 = API Method: StartActionByGetAndWait
 
-This method is also a very easy way to quickly start an action, but it waits for the action to finish before returning the result. This is useful if you want to get the output of the action or check its result without having to poll for it.
+This method is also a very easy way to quickly start an action, but it waits for the action to finish before returning the result. This is useful if you want to get the output of the action or check its result without having to poll for it. You cannot pass arguments using this method.
 
-* **HTTP Method**: `GET`
-* **Request Type**: Action ID in the URL
+* **HTTP Method**: `POST`
+* **Request Type**: xref:api/start_action.adoc#api-request-actionid[Action ID only] (`actionId`)
 * **Response Type**: Log Entry (waits for the action to finish)
 
+[NOTE]
+====
+Despite the name, in OliveTin 3k this method is called with `POST` and a JSON body. The OliveTin 2k style of putting the action ID in the URL (eg: `GET /api/StartActionByGetAndWait/pingGithub`) is no longer supported and returns `404`.
+====
+
 There are several variants of this API call available which might be easier for scripts (or humans) to work with:
 
 include::partial$api/start_action_methods.adoc[]
+
+== Example API call: Start an action by ID, and wait for it to finish
+
+.curl
+----
+user@host: curl http://olivetin.example.com:1337/api/StartActionByGetAndWait --json '{"actionId": "pingGithub"}'
+{"logEntry":{"actionTitle":"Ping GitHub.com","output":"...","exitCode":0, ... }}
+----
+
+See xref:api/start_action.adoc#api-response-logentry[Response type: LogEntry] for the full response.

+ 16 - 6
docs/modules/ROOT/pages/api/misc.adoc

@@ -1,20 +1,30 @@
 = Misc API calls
 
-== Example API call: Get the dashboard buttons ("components")
+== Example API call: Get the dashboard buttons
+
+`GetDashboard` returns the dashboard and its action buttons, including each action's `bindingId`. Send an empty object for the default dashboard, or set `title` to request a specific dashboard.
 
 .curl
 ----
-user@host: curl http://olivetinServer:1337/api/GetDashboardComponents 
+user@host: curl http://olivetinServer:1337/api/GetDashboard --json '{}'
 ----
 
 == Example API call: readyz Healthcheck
 
-This is useful for configuring healthchecks in docker containers, or on Kubernetes.
+This is useful for configuring healthchecks in docker containers, or on Kubernetes. The simplest option is the plain HTTP `/readyz` endpoint (not under `/api/`), which works with a `GET` request;
+
+.curl
+----
+user@host: curl http://olivetinServer:1337/readyz
+OK. Single HTTP Frontend is ready.
+----
+
+There is also an API method, `GetReadyz`;
 
 .curl
 ----
-user@host: curl http://olivetinServer:1337/api/readyz
-{"status": "ok"}
+user@host: curl http://olivetinServer:1337/api/GetReadyz --json '{}'
+{"status":"OK"}
 ----
 
-The response will always be "status: ok" to indicate that the API is up, or it will timeout.
+Either will respond with a `200` status to indicate that OliveTin is up, or it will timeout.

+ 92 - 35
docs/modules/ROOT/pages/api/start_action.adoc

@@ -5,53 +5,99 @@ There are several variants of this API call available which might be easier for
 
 include::partial$api/start_action_methods.adoc[]
 
-[#api-request-idurl]
-== Request type: Action ID in the URL
+All request and response field names below are the protobuf JSON names (lowerCamelCase) from the link:https://github.com/OliveTin/OliveTin/blob/main/proto/olivetin/api/v1/olivetin.proto[OliveTin Protobuf definition], which is the source of truth for the API.
+
+[#api-ids]
+== Action IDs vs Binding IDs
+
+* `actionId` is the `id` you set on the action in your `config.yaml`. To find your Action ID, and understand how Action IDs work, see the xref:action_customization/ids.adoc[Action ID] documentation.
+* `bindingId` identifies one button/instance of an action. For a normal action this is the same as the action ID. For actions generated from xref:entities/intro.adoc[entities], each entity gets its own binding ID. Binding IDs are returned by `GetDashboard` (as `action.bindingId`).
+
+NOTE: Despite its name, the `actionId` field used by `StartActionAndWait`, `StartActionByGet` and `StartActionByGetAndWait` is looked up as a binding ID. For normal actions this makes no difference, but for entity-generated actions you must send the entity's binding ID - sending the configured action `id` returns `not_found`.
+
+[#api-request-actionid]
+== Request type: Action ID only
 
 Used by:
 
 *** xref:api/method_StartActionByGet.adoc[StartActionByGet]
 *** xref:api/method_StartActionByGetAndWait.adoc[StartActionByGetAndWait]
 
-If you are trying to integrate OliveTin with your own scripts or processes, it's probably easiest to start actions by using an ID directly in the URL, xref:api/method_StartActionByGet.adoc#api-eg-startIdUrl[see the example].
+If you are trying to integrate OliveTin with your own scripts or processes, this is probably the easiest way to start actions. You cannot pass arguments with this request type.
 
-[#api-request-obj]
-== Request type: OliveTin request object
+[source,json]
+.`StartActionByGetRequest` / `StartActionByGetAndWaitRequest`
+----
+{
+  "actionId": "string"
+}
+----
+
+See xref:api/method_StartActionByGet.adoc#api-eg-startActionId[the example].
+
+[#api-request-startaction]
+== Request type: StartAction request object
 
 Used by:
 
 *** xref:api/method_StartAction.adoc[StartAction]
-*** xref:api/method_StartActionAndWait.adoc[StartActionAndWait]
+
+This is the request the OliveTin web UI uses, and gives you the most control over the execution.
 
 [source,json]
-.OliveTin request object structure
+.`StartActionRequest`
 ----
 {
-  "actionId": "string",
+  "bindingId": "string",
   "arguments": [
     {
       "name": "string",
       "value": "string"
     }
   ],
-  "uniqueTrackingId": "string"
+  "uniqueTrackingId": "string",
+  "justification": "string"
 }
 ----
 
-To find your Action ID, and understand how Action IDs work, see the xref:action_customization/ids.adoc[Action ID] documentation
+* `bindingId` (required) - see <<api-ids>>.
+* `arguments` (optional) - values for the action's xref:args/intro.adoc[arguments].
+* `uniqueTrackingId` (optional) - if you set this, it is used as the execution tracking ID, otherwise one is generated for you. It must be up to 36 characters of hex digits and dashes (eg: a UUID), and must not already have been used. An invalid or previously used ID is silently replaced with a generated UUID, so always track the execution using the `executionTrackingId` returned in the response.
+* `justification` (optional) - the reason for running the action, for actions that require a justification.
 
-If you need more control over the execution, then the only other option is to submit a `OliveTin reqjest object`, which is just a very simple JSON structure like this;
+[source,json]
+.Example
+----
+{
+  "bindingId": "generate_cryptocurrency",
+  "arguments": [],
+  "uniqueTrackingId": "0f8b1c2e-6d3a-4e5f-9a7b-1c2d3e4f5a6b"
+}
+----
+
+[#api-request-startactionandwait]
+== Request type: StartActionAndWait request object
+
+Used by:
+
+*** xref:api/method_StartActionAndWait.adoc[StartActionAndWait]
 
 [source,json]
+.`StartActionAndWaitRequest`
 ----
 {
-    "actionId": "Generate cryptocurrency",
-    "arguments": [],
-    "uniqueTrackingId": "my-tracking-id",
+  "actionId": "string",
+  "arguments": [
+    {
+      "name": "string",
+      "value": "string"
+    }
+  ],
+  "justification": "string"
 }
 ----
 
-More detailed examples can be seen below.
+Note that this request selects the action with `actionId` (not `bindingId`), and does not accept a `uniqueTrackingId`.
 
 [#api-response-trackingid]
 == Response type: Execution Tracking ID
@@ -75,29 +121,40 @@ Used by:
 *** xref:api/method_StartActionAndWait.adoc[StartActionAndWait]
 *** xref:api/method_StartActionByGetAndWait.adoc[StartActionByGetAndWait]
 
+The `output` field contains the combined stdout and stderr of the action.
+
 .Example log entry
 [source,json]
 ----
 {
-    "logEntry": {
-        "datetimeStarted": "2024-02-27 14:14:49",
-        "actionTitle": "Restart httpd on server1",
-        "stdout": "",
-        "stderr": "",
-        "timedOut": true,
-        "exitCode": -1,
-        "user": "",
-        "userClass": "",
-        "actionIcon": "&#128260;",
-        "tags": [
-
-        ],
-        "executionTrackingId": "b04b1e90-d457-4158-b7dc-da9e81f21568",
-        "datetimeFinished": "2024-02-27 14:14:52",
-        "actionId": "restart_httpd",
-        "executionStarted": true,
-        "executionFinished": true,
-        "blocked": false
-    }
+  "logEntry": {
+    "datetimeStarted": "2026-11-12 11:56:29",
+    "actionTitle": "Restart httpd on server1",
+    "output": "Restarting httpd...\n",
+    "timedOut": false,
+    "exitCode": 0,
+    "user": "guest",
+    "userClass": "",
+    "actionIcon": "&#128260;",
+    "tags": [],
+    "executionTrackingId": "56588051-80da-4b31-8cd8-461a4566e3a9",
+    "datetimeFinished": "2026-11-12 11:56:31",
+    "executionStarted": true,
+    "executionFinished": true,
+    "blocked": false,
+    "datetimeIndex": "4",
+    "canKill": false,
+    "datetimeRateLimitExpires": "",
+    "bindingId": "restart_httpd",
+    "queued": false,
+    "queuedForGroup": "",
+    "justification": "",
+    "arguments": [
+      {
+        "name": "server",
+        "value": "server1"
+      }
+    ]
+  }
 }
 ----

+ 6 - 4
docs/modules/ROOT/pages/integrations/homeassistant.adoc

@@ -19,9 +19,9 @@ actions:
     shell: ssh user@server "sudo systemctl suspend"
 ----
 
-You then need to know the URL to call to trigger this action. This URL is the OliveTin API URL, with the action ID appended to it. For example, if your OliveTin is running at `http://yourserver:1337`, the URL to call to trigger the action above would be `http://yourserver:1337/api/StartActionAndWait/server_sleep`.
+You then need to know the URL to call to trigger this action. This is the OliveTin API URL plus the method name, and the action ID is sent in a JSON body. For example, if your OliveTin is running at `http://yourserver:1337`, you would `POST` `{"actionId": "server_sleep"}` to `http://yourserver:1337/api/StartActionByGetAndWait`.
 
-You can learn more about starting actions via the OliveTin API by reading the link xref:api/start_action.adoc[Starting Actions via the API] page, but the method "StartActionAndWait" is the one you will want to use for Home Assistant.
+You can learn more about starting actions via the OliveTin API by reading the link xref:api/start_action.adoc[Starting Actions via the API] page, but the method "StartActionByGetAndWait" is the one you will want to use for Home Assistant.
 
 == Add the REST API call to Home Assistant
 
@@ -45,8 +45,10 @@ From the file editor now in your sidebar, browse the filesystem to the configura
 ----
 rest_command:
   olivetin_sleep_mindstorm:
-    url: http://olivetin.webapps.teratan.lan/api/StartActionByGetAndWait/server_sleep
-    method: get
+    url: http://olivetin.example.com:1337/api/StartActionByGetAndWait
+    method: post
+    content_type: "application/json"
+    payload: '{"actionId": "server_sleep"}'
 ----
 
 You save the file, and restart Home Assistant to pick up the changes.

+ 1 - 1
docs/modules/ROOT/pages/solutions/on-git-push/index.adoc

@@ -70,7 +70,7 @@ function run_olivetin_action() {
 
         OLIVETIN_REQUEST="$(cat <<EOF
 {
-  "actionId": "$ACTION_NAME",
+  "bindingId": "$ACTION_NAME",
   "arguments": [
         {
                 "name": "commit",

+ 3 - 3
docs/modules/ROOT/pages/troubleshooting/advanced.adoc

@@ -9,15 +9,15 @@ All these configuration options are `false` by default, and should be deleted fr
 
 [#dump-server-diagnostics]
 == Dump server diagnostics
-`insecureAllowDumpServerDiagnostics: true` - will allow dumping xref:troubleshooting/server-diagnostics.adoc[server diagnostics] as plain text when visiting `http://server:1337/api/ServerDiagnostics`
+`insecureAllowDumpServerDiagnostics: true` - will allow dumping xref:troubleshooting/server-diagnostics.adoc[server diagnostics] via the `ServerDiagnostics` API method, eg: `curl http://server:1337/api/ServerDiagnostics --json '{}'`
 
 [#dump-action-map]
 == Dump Action Map
-`InsecureAllowDumpActionMap: true` - will allow dumping all the actions (and those generated with entities) and their public IDs, eg: `http://server:1337/api/DumpActionMap`
+`insecureAllowDumpActionMap: true` - will allow dumping all the actions (and those generated with entities) and their public IDs, eg: `curl http://server:1337/api/DumpPublicIdActionMap --json '{}'`
 
 [#dump-vars]
 == Dump Vars
-`InsecureAllowDumpVars: true` - will allow dumping all the "string variables" from a map that is mainly used for entities, eg: `http://server:1337/api/DumpVars`
+`insecureAllowDumpVars: true` - will allow dumping all the "string variables" from a map that is mainly used for entities, eg: `curl http://server:1337/api/DumpVars --json '{}'`. The variables are written to the OliveTin process standard output (ie: the OliveTin logs); the API response only contains an alert.
 
 [#dump-jwt]
 == Dump JWT Claims

+ 16 - 6
docs/modules/ROOT/pages/troubleshooting/server-diagnostics.adoc

@@ -33,15 +33,18 @@ You can then copy and paste this text into a GitHub issue, discussion, Discord c
 
 == How do I generate server diagnostics?
 
-OliveTin needs to be able to start and its API needs to be functional. Once OliveTin is started, open this URL in a browser (replace the host and port with yours):
+OliveTin needs to be able to start and its API needs to be functional. Once OliveTin is started, call the `ServerDiagnostics` API method (replace the host and port with yours):
 
-`http://myserver:1337/api/ServerDiagnostics`
+[source,bash]
+----
+curl http://myserver:1337/api/ServerDiagnostics --json '{}'
+----
 
-The `/api/ServerDiagnostics` path is the HTTP endpoint OliveTin uses for server diagnostics.
+Like all OliveTin API methods, `/api/ServerDiagnostics` must be called with `POST` - simply opening the URL in a browser sends a `GET`, which returns `405 Method Not Allowed`.
 
-== Optional: Allow insecure (but easy) dumping to the browser
+== Optional: Allow insecure (but easy) dumping in the API response
 
-There is a configuration option you can set in your `config.yaml` that allows you to easily dump server diagnostics to your browser when visiting the API. This is turned off by default, as you should not allow anybody to request diagnostics at any time they like, but you can enable this option temporarily to easily get access to the text in your browser.
+There is a configuration option you can set in your `config.yaml` that allows the API to return server diagnostics directly in the response, instead of only writing them to the logs. This is turned off by default, as you should not allow anybody to request diagnostics at any time they like, but you can enable this option temporarily to easily get access to the text.
 
 [source,yaml]
 .`config.yaml`
@@ -49,6 +52,13 @@ There is a configuration option you can set in your `config.yaml` that allows yo
 insecureAllowDumpServerDiagnostics: true
 ----
 
+With this enabled, the diagnostics text is returned in the `alert` field of the JSON response, with its newlines escaped. Use `jq -r` to print it as readable text you can copy:
+
+[source,bash]
+----
+curl -sS http://myserver:1337/api/ServerDiagnostics --json '{}' | jq -r .alert
+----
+
 == Default: Diagnostics dump to logs
 
 You should get a simple JSON message saying something like;
@@ -59,7 +69,7 @@ alert: "Your Server Diagnostics have been logged to OliveTin logs."
 
 The exact wording may match your OliveTin version.
 
-If you see this, great! The actual contents of the server diagnostics are not returned to your browser for security reasons (guests could get info about your installation, etc).
+If you see this, great! The actual contents of the server diagnostics are not returned in the API response for security reasons (guests could get info about your installation, etc).
 
 To find the diagnostics text depends on how you are running OliveTin. If you are running in a container, then try `docker logs olivetin` (where `olivetin` is your container name). If you are running using systemd, then try `journalctl -eu OliveTin`.
 

+ 16 - 14
docs/modules/ROOT/partials/api/start_action_methods.adoc

@@ -1,30 +1,32 @@
-There are 4 main methods to start an action in OliveTin, which can be used in scripts or other applications. These methods allow you to trigger actions either immediately or wait for them to complete, and they can be accessed via HTTP requests.
+There are 4 main methods to start an action in OliveTin, which can be used in scripts or other applications. These methods allow you to trigger actions either immediately or wait for them to complete. Like every OliveTin API method, they are called with an HTTP `POST` and a JSON request body (eg: `curl --json '{...}'`).
 
 .Webhook/API reference table
 [%header]
 |======================================================
 | Function                     | HTTP Method | Request Type (How to select an action)             | Response Type
 
-| xref:api/method_StartAction.adoc[StartAction]                
-| POST        
-| xref:api/start_action.adoc#api-request-obj[OliveTin request object]        
+| xref:api/method_StartAction.adoc[StartAction]
+| POST
+| xref:api/start_action.adoc#api-request-startaction[`bindingId`, arguments, tracking ID, justification]
 | xref:api/start_action.adoc#api-response-trackingid[Execution Tracking ID]
 
-| xref:api/method_StartActionByGet.adoc[StartActionByGet]           
-| GET         
-| xref:api/start_action.adoc#api-request-idurl[Action ID in the URL]
+| xref:api/method_StartActionByGet.adoc[StartActionByGet]
+| POST
+| xref:api/start_action.adoc#api-request-actionid[`actionId` only]
 | xref:api/start_action.adoc#api-response-trackingid[Execution Tracking ID]
 
-| xref:api/method_StartActionAndWait.adoc[StartActionAndWait]         
-| POST        
-| xref:api/start_action.adoc#api-request-obj[OliveTin request object]
+| xref:api/method_StartActionAndWait.adoc[StartActionAndWait]
+| POST
+| xref:api/start_action.adoc#api-request-startactionandwait[`actionId`, arguments, justification]
 | xref:api/start_action.adoc#api-response-logentry[Log Entry (waits for the action to finish)]
 
-| xref:api/method_StartActionByGetAndWait.adoc[StartActionByGetAndWait]    
-| GET         
-| xref:api/start_action.adoc#api-request-idurl[Action ID in the URL]         
+| xref:api/method_StartActionByGetAndWait.adoc[StartActionByGetAndWait]
+| POST
+| xref:api/start_action.adoc#api-request-actionid[`actionId` only]
 | xref:api/start_action.adoc#api-response-logentry[Log Entry (waits for the action to finish)]
 
 |======================================================
 
-You can also browse these methods in the link:htts://docs.olivetin.app/api/swagger/[OpenAPI/Swagger] docs if you prefer.
+NOTE: The waiting methods (`StartActionAndWait` and `StartActionByGetAndWait`) check that the caller is allowed to view the action's logs *after* the action has finished. A caller that can start an action but cannot view its logs receives a permission error, even though the action has already run - so retrying on that error can run the action again. Use `StartAction` or `StartActionByGet` when you do not need the log entry.
+
+You can also browse these methods in the link:https://docs.olivetin.app/api/swagger/3k/[OpenAPI/Swagger] docs if you prefer. The link:https://github.com/OliveTin/OliveTin/blob/main/proto/olivetin/api/v1/olivetin.proto[Protobuf definition] is the source of truth for all request and response fields.