Overview
Seeq is an advanced analytics application for process manufacturing data. It connects to historians and other sources, and it can also store signals and conditions itself. The Seeq web application uses the Seeq Server REST API for everything, so anything you do in Workbench can be done throughhttps://<server>/api/.
The SeeqRestApi connector covers login, server status, item search, stored signals (create, push samples, replace samples, read samples or one sample), stored conditions (create, add capsules, read capsules), Seeq Formula runs, and archiving. Typical uses: send MQTT readings that are not in any historian into a Seeq signal, store alarms or batch events from MQTT as capsules, and pull Seeq results (for example an aggregate) back onto the broker. Each event publishes the server’s reply on <topic>/response.
Prerequisites
- A Seeq server the broker host can reach. Seeq SaaS sites look like
https://<company>.seeq.site. An on-premises server listens onhttp://<host>:34216by default, or on HTTPS behind 443 / 8443. - A Seeq access key and its password (profile menu → Access Keys). Access keys work with every directory, including OAuth 2.0 / OpenID Connect single sign-on. Access key creation is off by default for non-admin users (
Authentication/AccessKey/Creation/Enabled). An admin can turn it on or create the key for you. A Seeq directory user name and password also work. - Write access to the signals and conditions you push to. A signal or condition created through this connector belongs to the access key’s user and has global scope unless you set
scopedToto a workbook ID.
Authentication
Seeq uses a session token in thex-sq-auth header:
- Log in: publish
{ "body": { "username": "<access key>", "password": "<access key password>" } }tohistorian/seeq/session/create. LeaveauthProviderClassandauthProviderIdout to use the Seeq directory, which access keys require. For a directory user (for example LDAP), set both to the directory’s datasource class and ID fromGET /api/auth/providers. - Seeq returns the token in the
x-sq-authresponse header. The response body (historian/seeq/session/create/response) is the user record, not the token. The connector publishes the body, so get the token another way, for example with a one-off call from the broker host, and store it as a Hub secret:
- Send
"auth": "<token>"with every other event. The connector puts it in thex-sq-authheader. - Seeq ends a session after a period of inactivity (the user’s
sessionDuration). APingevery few minutes keeps it alive. A401on any response means the token has expired: log in again. Access keys also stop working when their user has not logged in to Seeq withinAuthentication/AccessKey/ValidityWithoutUserLogin(14 days by default).
GetServerStatus needs no token and is a good connectivity check.
Configuration
- Replace
YOUR_SEEQ_SERVERinBASE_ADDRESSwith your Seeq host. For an on-premises server without TLS usehttp://<host>:34216and setUSE_SSLto"false". - Every request sends
Accept: application/vnd.seeq.v1+json, and every body usesContent-Type: application/vnd.seeq.v1+json. Seeq rejects other values:406for a differentAccept,415for plainapplication/json. Keep these headers if you add your own events. - Keys (timestamps) are ISO 8601, for example
2026-10-05T07:00:00Z. UseZ. A+hh:mmoffset in a query string must be URL-encoded (%2B). - Signal, condition and item IDs are Seeq GUIDs.
CreateSignalandCreateConditionreturn them inid. You can also find them withSearchItems(filters=Name==Line1 Temperature&types=StoredSignal) or copy them from Workbench (Item Properties). GetSamplesandGetCapsulesreturn at mostlimitentries. When more exist, the response carries acontinuationToken.- Errors are JSON
{ "statusMessage": "..." }.403means the user lacks write access to the item, and404means the ID is unknown or archived. - Seeq SaaS sits behind Cloudflare. Requests with the default Python
urllibUser-Agent are refused with Cloudflare error 1010. Requests with no User-Agent or a normal client User-Agent are accepted.
Examples
Create a signal stored in Seeq for an MQTT value:start and end are required):
historian/seeq/condition/create and { "name": "Line1 Alarms", "maximumDuration": "1d" }):
parameters binds $t to a signal ID):
TIMESTAMP "UTC" must give an ISO 8601 time for Seeq to accept the sample key. Check the format on your broker version before you rely on it.
Testing
Technical preview, not yet live-tested. The app package’s smoke script checks every event against the official Seeq Python SDK 66.208 (method, path, path and query parameters, body model, media types) and runs every event against a local mock Seeq Server. The mock run covers login with the token in thex-sq-auth response header, signal create → samples add / replace → read-back → latest sample, condition create → capsule add → read-back, formula run, archive and logout. Negative controls cover no, bad or logged-out tokens and a wrong password (401), wrong Accept (406), plain JSON (415), an unknown ID (404), a missing start (400), a write without permission (403), a capsule that ends before it starts (400) and an unbound formula variable (400). Unauthenticated calls against a real Seeq R66 server returned the expected results: open ping and server status 200, 406 and 415 for the wrong media types, 401 for a bogus login, and 401 for every token event with a fake or empty token. A run with a real access key and a broker MQTT round-trip are still open. See TEST.md in the app package.
Not covered
- Getting the session token inside the broker. Seeq returns it in the
x-sq-authresponse header, and the connector publishes only the response body (see Authentication). - Workbooks, worksheets, Organizer topics and reports, assets and asset trees, signal / condition / scalar batch upserts, datasource-ID endpoints (
/signals/{datasourceClass}/{datasourceId}/{dataId}) and calculated items. Use the same URL pattern and headers with your own event if you need them. - Seeq Data Lab, SPy, Data Lab Functions, Add-ons and the Seeq Connector SDK.
- OData export (
/odata.svc), which authenticates with the access key and its password directly.

