Authentication

Authentication

Authentication

Real login only

Both SDKs perform a real username/password login automatically on the first call when username + password are present in the config:

  • Endpoint: POST {serviceApiUrl}/api/account/login. Request body: { "applicationId": "<app-guid>", "userName": "<user>", "password": "<secret>" } — note userName (camelCase) and the required applicationId; the SDK supplies both.
  • The response is stored on the SDK instance. Field names: token, refreshToken, expirationSeconds, id.
  • ⚠️ The SDK spec/docstrings mention expiresIn / userId; the code reads expirationSeconds / id. Use the real names.
  • Refresh: Python sdk.refresh_token, which calls POST /account/refresh-token.
  • After login the UI calls GET /api/account/user (current user) and periodically POST /api/account/ping with { "applicationId", "userSessionId" } to keep the session warm. The SDK handles its own session, so tests rarely call these directly — but a stale userSessionId/expired token surfaces as 401, so re-login (a fresh SDK instance) on 401.

There is no out-of-band token minting, impersonation, or backdoor. If a token is needed, it comes from a normal login.

Secret hygiene (non-negotiable)

  • Credentials live only in gitignored config (e.g. config/<env>.json), never in code, output, logs, commit messages, or tool calls.
  • Never print/console.log a config object that contains a password or token.
  • Set disableLogging: true (Python) / mute console.log (JS) so the SDK does not echo the username.

Config keys (shared)

keyvaluesnotes
serviceApiUrlbase API URLadmin surface; e.g. https://nomad-admin-api.yourdomain.com
portalApiUrlbase API URLoptional. Portal surface when it's a different host than serviceApiUrl. Omit when one host serves both by path. A portal session falls back to serviceApiUrl when unset.
apiType"admin" | "portal"selects the API surface; each op is guarded to one type (see below)
usernamestringfrom gitignored config
passwordstringfrom gitignored config
disableLogging (py) / debugMode (js)boolsuppress/limit SDK logging

Portal vs Admin (apiType) — Portal-first

Every SDK method is guarded to exactly one apiType and raises InvalidAPITypeException if called on the wrong session (no auto-fallback). Always prefer the Portal API; use an Admin endpoint only when you need an admin-specific capability that has no Portal equivalent (indexing, workflows, ad-breaks, server/content administration).

As built, the core asset-management surface (create/upload/get/update/move/delete) is guarded Admin-only, while the consumer surface (sharing, saved searches, annotations, tracking) is Portal-only, so a workflow that creates a confined asset and then shares it needs both session types. The full op-by-op split (and the handful of unguarded ops that work on either) is in ../reference/api-types.md; each component also records its requirement as requires_api_type in front-matter.