Skip to main content
Technical Preview

Overview

Client-mode connector for a self-hosted Nextcloud server that moves plant files and messages between the broker and Nextcloud. A typical flow writes a shift report, batch record or alarm snapshot as a JSON or CSV file into a plant folder (the folder is created on the fly), writes today’s setpoint table over yesterday’s while Nextcloud keeps the old one as a version, reads a recipe back when a line changes over, comments on a batch record when QA releases it, shares a weekly report with a public link that expires, and sends an alarm to the maintenance team as a Nextcloud notification or a message in a Talk conversation. New files can be picked up from the activity stream or with a webhook listener that calls the broker. The template file NextcloudRestApi.lot holds one connector, NextcloudRestApi, with 43 events (29 GET, 9 POST, 5 PUT; 13 writes, no delete). Files go through WebDAV (/remote.php/dav/files/...), everything else through the OCS API (/ocs/v2.php/...) of the server and its apps: provisioning, sharing, notifications, activity, user status, calendar (dav), Talk (spreed) and webhook listeners. Topics use storage/nextcloud/<object>/<verb>; each response is published on <source topic>/response.
The connector was checked against the Nextcloud OpenAPI specs (server core, provisioning, files, sharing, dav, user status and webhook listeners; notifications and Talk) for method, path, path parameters, required headers and query parameters and every example body, against the Nextcloud developer manual for WebDAV, comments and activity, and against a local mock. It was then run live against a local Nextcloud 35.0.1 server (official Docker image) with Talk 25.0.5: all 43 events answered as expected, including a file created, read back, overwritten as a new version and shared by public link, a notification, a Talk conversation with a message and a webhook listener. Every authenticated event answered 401 to a wrong app password. The local test used plain HTTP on localhost and called the server directly, not through a broker.

Setup

  1. Point the connector at your server: replace BASE_ADDRESS (https://nextcloud.example.com in the template) with your Nextcloud address, including the web root if Nextcloud does not run at the domain root (for example https://cloud.example.com or https://example.com/nextcloud), without a trailing slash. Keep this value as NEXTCLOUD_BASE_URL in your deployment notes. For plain HTTP on a plant LAN use http://... and set USE_SSL "false". The host name must be in the server’s trusted_domains.
  2. Create a dedicated account for the broker, for example plant-bot, and give it a storage quota. Share the plant folders with it, or let it own them.
  3. Log in as that account and create an app password under Personal settings > Security > Devices & sessions > Create new app password. Use the app password, never the login password: accounts with two-factor authentication refuse login passwords, and you can revoke an app password on its own.
  4. Admin-only events (UsersList, GroupsList, GroupUsersList, AdminNotificationSend and the webhook events) need an app password of an administrator. Group sub-admins can list the users and groups they manage. Webhook listeners can also be delegated to a group through the Webhooks admin privilege.
  5. Talk events need the Talk app, webhook events the Webhook listeners app (Nextcloud 30 and later, shipped but check that it is enabled), and activity events the Activity app.
  6. Keep NEXTCLOUD_USER, NEXTCLOUD_APP_PASSWORD and the derived NEXTCLOUD_BASIC_AUTH (see below) in broker secrets and inject them with GET SECRET.

Authentication

Every event except StatusGet sends Authorization: Basic <credentials>, built from the basic_auth field of the payload. basic_auth is the Base64 of <NEXTCLOUD_USER>:<NEXTCLOUD_APP_PASSWORD>, for example plant-bot:Ab12C-dE34f-.... Store that value as the secret NEXTCLOUD_BASIC_AUTH:
OCS events also send OCS-APIRequest: true (without it Nextcloud answers 412 CSRF check failed) and ask for JSON with ?format=json. OCS answers in an envelope: the result is in ocs.data, the status in ocs.meta. As an alternative, the connector can carry the credentials itself with WITH USERNAME and WITH PASSWORD in REST_API_CONFIG. In that case, remove the Authorization header lines from the events.
basic_auth grants full access to the account’s files. Never retain topics that carry it, restrict storage/nextcloud/# with ACLs, and give the broker its own account instead of a personal one. Nextcloud’s brute-force protection slows down and then blocks (429) the broker’s IP address after repeated wrong passwords, also for correct requests. Fix the secret first, then reset the block with occ security:bruteforce:reset <ip>.

Payloads

Send query as an empty string when you need no parameters; the request then ends with &, which Nextcloud ignores.

Uploading files

FileUpload writes a new file with WebDAV PUT. It sends If-None-Match: *, so an existing file is never overwritten: Nextcloud answers 412 Precondition Failed instead. It also sends X-NC-WebDAV-Auto-Mkcol: 1, so Nextcloud 32 and later create missing parent folders. Older servers answer 404 or 409 when the folder does not exist yet; create it by hand once.
Nextcloud answers 201 Created with an empty body. The new file id is in the OC-FileId response header (00000091oc...: the number before the instance suffix is the file id). Use Search (provider files) or ActivityList to find file ids later. FileVersionUpload writes a file whether it exists or not (201 for a new file, 204 when it replaced one). With the Versions app, the previous content stays in the file’s version history, so writing today’s setpoint table over yesterday’s keeps yesterday’s as a version. FileDownload returns the raw file content. Keep files to text, CSV or JSON that fits an MQTT message. Build the payload in a LoT action:

Examples

Health check without credentials (storage/nextcloud/status/get), for example from a timer:
The answer carries installed, maintenance, needsDbUpgrade and versionstring. Read a recipe back on changeover (storage/nextcloud/files/download):
List the sub-folders of the plant folder (storage/nextcloud/folders/tree/get):
Find files by name (storage/nextcloud/search/query); each entry carries the path in subline and the file id in attributes.fileId:
Share a shift report with a public, read-only link that expires (storage/nextcloud/shares/create); the answer carries url, token and id:
shareType is 0 for a user, 1 for a group, 3 for a public link and 4 for email; permissions adds up 1 read, 2 update, 4 create, 8 delete and 16 share. End a link early with ShareUpdate and an expireDate of today instead of deleting it. Comment on a batch record when QA releases it (storage/nextcloud/files/comments/create):
Send an alarm to a user’s Nextcloud notifications, which also reach the desktop and mobile apps (storage/nextcloud/notifications/admin/send, admin only):
Post an alarm into a Talk conversation (storage/nextcloud/talk/messages/send). Create the conversation once with TalkRoomCreate ({"roomType": 2, "roomName": "Line 2 alarms"}), add people with TalkParticipantAdd, and keep its token:
Show that a line account is busy (storage/nextcloud/user-status/set, then storage/nextcloud/user-status/message/set):
Pick up new files without a public endpoint by polling the activity stream (storage/nextcloud/activity/list): ask for filter files with query since=<last activity_id>&sort=asc&limit=50, store the X-Activity-Last-Given id (or the last activity_id), and treat 304 as nothing new. Use filter filter with object_type=files&object_id=<id> for the history of one file. Or let Nextcloud call the broker when a file is created in the plant folder (storage/nextcloud/webhooks/create, admin only). The uri is a broker REST_API server connector that Nextcloud can reach; authData sets a header the receiver checks:
Nextcloud sends webhooks from background jobs, so deliveries depend on its cron and can lag behind.

Events

Limits

  • WebDAV PUT has no size limit of its own, but the web server and PHP limits apply (upload_max_filesize, post_max_size, proxy body size). Keep MQTT payloads small. Larger files need chunked uploads, which are not packaged.
  • X-NC-WebDAV-Auto-Mkcol needs Nextcloud 32 or later. Admin notifications use the v3 API: subject up to 255 characters, message up to 4000. Talk messages are limited to 32000 characters.
  • Nextcloud’s brute-force protection delays and then blocks (429) an IP address after repeated failed logins. In the local test it blocked the client after 11 wrong passwords.
  • Shares can have an enforced maximum expiry and password policy (see CapabilitiesGet, files_sharing). A share that breaks the policy answers 400 or 403.
  • FolderTreeGet lists folders only, and Search only matches names. File listings with sizes and dates need WebDAV PROPFIND, which is not a REST_API method.

Not packaged

  • Delete events on purpose: files, folders, shares, notifications, Talk conversations and participants, status messages and webhook listeners.
  • WebDAV methods that REST_API does not offer (it supports GET, POST, PUT, DELETE and PATCH): PROPFIND (folder listing and file properties), MKCOL (create folder; FileUpload creates parents instead), MOVE and COPY (rename, archive, copy), PROPPATCH (favorites, tags), REPORT and SEARCH (filtered listings, comment lists), and the MOVE-based trash and version restore.
  • Chunked uploads (v2) and bulk upload, public share (/public.php) uploads, folder downloads as ZIP or TAR, previews and thumbnails.
  • User and group administration (create, edit, disable, wipe), app passwords and login flow, app config, Talk calls, polls, bots and breakout rooms, calendar and contacts writes (CalDAV and CardDAV), Deck, Forms and Tables.
  • The webhook receiver. A receiver would be a separate ENABLE_SERVER REST_API connector that checks the authData header.

Suggested branches

feat/rest-api-route-nextcloud for the broker template and feat/docs-rest-api-nextcloud for this page.
Last modified on October 21, 2026