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>" }— noteuserName(camelCase) and the requiredapplicationId; 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 readsexpirationSeconds/id. Use the real names. - Refresh: Python
sdk.refresh_token, which callsPOST /account/refresh-token. - After login the UI calls
GET /api/account/user(current user) and periodicallyPOST /api/account/pingwith{ "applicationId", "userSessionId" }to keep the session warm. The SDK handles its own session, so tests rarely call these directly — but a staleuserSessionId/expired token surfaces as401, 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.loga config object that contains a password or token. - Set
disableLogging: true(Python) / muteconsole.log(JS) so the SDK does not echo the username.
Config keys (shared)
| key | values | notes |
|---|---|---|
serviceApiUrl | base API URL | admin surface; e.g. https://nomad-admin-api.yourdomain.com |
portalApiUrl | base API URL | optional. 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) |
username | string | from gitignored config |
password | string | from gitignored config |
disableLogging (py) / debugMode (js) | bool | suppress/limit SDK logging |
Portal vs Admin (apiType) — Portal-first
apiType) — Portal-firstEvery 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.
