Architecture
What the token carries, how a call reaches a plugin, how the server decides whether you may make it, and what comes back when something goes wrong.
The shape of a deployment
eConnect Core is one server holding users, permissions and settings, with plugins installed into it. Each plugin is a module — point of sale, casino, object analytics — with its own database and its own data. Your integration talks to Core, and Core routes to the plugin instance named in the path.
Signing in
A token pair is minted from a real eConnect session — the same session the desktop client gets. That is why permissions, logical groups and group switching behave identically whichever client is calling.
What the access token carries
| Claim | Meaning |
|---|---|
sub | The user id the session belongs to |
sid | The session id — the server resolves your rights from this |
gid | The user group the session is currently in |
pv | A security stamp: bumped when permissions change, which invalidates outstanding tokens |
That last one matters for long-running integrations. If an administrator changes the account's
permissions or switches its group, outstanding access tokens are rejected with 401 and an error of
token_stale — refresh, do not re-login, and carry on.
Tokens are ES256-signed. If you want to verify them yourself rather than trusting the transport,
public keys are at /.well-known/econnect/jwks.json.
Finding a plugin, then calling it
Routes follow one of two shapes:
/api/v2/{module}/... global — users, settings, plugin discovery
/api/v2/{module}/plugins/{pluginInstalledId}/... plugin-scoped — everything with operational data
Of the 688 endpoints, all but a handful are plugin-scoped. If a path has {pluginInstalledId}
in it, that segment is not optional and not guessable: it comes from installed-plugins.
Permissions
The server authorises every call against the signed-in user's permission keys — the same keys that govern the desktop client. There is no API-only permission model and no bypass.
Two things follow from that, and they surprise people:
- A permitted call can return less than you expect. A logical group narrows what the account can see, so a query that is allowed may legitimately come back with fewer rows than an administrator would get. That is the scope working, not a bug.
- Granting the key is only half of it. For plugin data, the account also needs the plugin instance to be in its scope.
Which keys a module uses is on each reference page, and the full catalogue is the Permission Keys reference.
Responses and errors
Successful calls return the payload directly — no envelope to unwrap.
Failures are RFC 9457 problem documents:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
"title": "Unauthorized",
"status": 401,
"detail": "Token is stale; refresh required.",
"errorCode": "token_stale"
}
| Status | Means | What to do |
|---|---|---|
400 | The request did not validate | Fix the payload; the detail says what was wrong |
401 | No token, an expired one, or a stale stamp | Refresh; if that fails, sign in again |
403 | Authenticated, but not permitted | Grant the key, or widen the account's logical group |
404 | No such record — or none you may see | Check the id and the account's scope |
500 | Server fault | Retry with backoff; the server logs carry the detail |
Paging and ordering
Query endpoints share one convention:
| Parameter | Purpose |
|---|---|
page | 1-based page number |
recordsPerPage | Page size |
maxRecords | Hard ceiling on rows considered |
orderBy | Sort expression, e.g. DataTimeStamp desc |
timeOldest / timeNewest | The window to query |
Always set a time window on event-shaped data. A query with no window is a table scan against a database holding years of detections, and the server will let you ask for it.
Pushing data in
Ingress endpoints are ordinary POSTs, and most modules offer a batch form beside the single one.
Batch where you can: one request with five hundred rows is dramatically cheaper than five hundred
requests, for you and for the server.
Data you push is ordinary eConnect data the moment it lands: it appears in grids, feeds dashboards, raises alerts if a rule matches, and is covered by the same retention and audit rules as data the product collected itself.
See Pushing Data In for the per-module payloads.
Versioning
v1 — the SOAP services and the older REST surface — is unchanged and still served. v2 is generated from the same contracts, so the two cannot disagree about behaviour; v2 differs in being REST-shaped, JWT-authenticated and JSON-only. New integrations should use v2.