Skip to content

Surfaces

Interactive API Explorer: Explorer

Body Auth — Not Header Auth

USM uses body auth: session_guid, api_key, and credentials are passed in the JSON body. Header auth (x-session-guid) is not used, except that POST /usm/api_key/validate accepts x-api-key. This differs from most other services which use header auth. See /common/headers-identity.html.

API Gateway base paths:

  • Sessions: https://api.g3nretailstack.com/usm/session
  • Service accounts: https://api.g3nretailstack.com/usm/service_account
  • API keys: https://api.g3nretailstack.com/usm/api_key

All requests/JSON responses share the envelope { success, data?, error?, build, stats? } with build ID + UTC timestamp in the footer. Errors carry tags/messages; payloads redact secrets.

Surface Types (explicit)

API Gateway

  • Status: Available.
  • Base: https://api.g3nretailstack.com/usm
  • Notes: All documented USM routes are API Gateway (session/service_account/api_key).

Direct Lambda

  • Status: Not offered.
  • Notes: No direct Lambda surface is documented for USM.

CLI

  • Status: Available.
  • Command: g3n usm ... (API Gateway).
  • Notes: --profile is required by policy even though endpoints are public.

MCP

  • Status: Available.
  • Canonical protocol: https://mcp.g3nretailstack.com/usm/PROTOCOL.md
  • Mirror: https://doc.g3nretailstack.com/usm/PROTOCOL.md

Auth + tenancy

  • USM is user/session scoped (no orgcode). Auth fields live in the JSON body (session_guid, api_key) except POST /usm/api_key/validate, which accepts x-api-key in headers.
  • Header auth is otherwise not required; always send content-type: application/json.

Identifier policy

  • Direct get/update/status calls require GUID/ID fields (*_id or legacy *_guid where that is the canonical field name). Code-based lookups are resolve/search only.
  • Responses never include both *_id and *_guid for the same record (no dual-field output).
  • Exceptions (email-based UAS, PVM resolve, MRS container+record_id) are listed in /common/ids-codes.html.

Request builder (API Gateway)

Method posture: POST for all routes (including reads/lists).

Headers (canonical)

bash
-H "content-type: application/json"

Auth placement

  • Session calls: session_guid in the JSON body.
  • API-key management: api_key in the JSON body.
  • Only POST /usm/api_key/validate accepts x-api-key in headers.

Template (session create)

bash
curl -sS -X POST "https://api.g3nretailstack.com/usm/session/create" \
  -H "content-type: application/json" \
  -d '{"email":"user@example.com","passcode":"Abcd!234","caption":"cli","session_label":"cli"}'

Why POST for reads?

USM uses POST for reads/lists to keep credentials out of URLs, support structured JSON filters, and keep auth placement consistent with body-only fields. Treat reads as POST-only (no GET).

Retry guidance (endpoint class)

  • Read-ish POSTs (get/list/validate/api_key/validate) are safe to retry with identical inputs.
  • Write-ish POSTs (create/close/logout/revoke/policy_set) should only be retried when you can tolerate duplicates or the endpoint documents idempotency.

Public API (API Gateway)

Canonical curl headers

bash
-H "content-type: application/json"

USM auth fields live in the JSON body (for example session_guid); the only auth header on this surface is x-api-key for api_key/validate. Method posture: USM uses POST for all routes (including reads/lists). Treat POST as canonical and pass inputs in the JSON body. See /common/http-methods.html.

POST /usm/session/create

  • Use when issuing a new session for a verified user/email. Enforces per-user cap (default 1024 or UAS override 32–8192).
  • Notes: email inputs are canonicalized (trim + lowercase) before UAS lookups.
  • Request
json
{ "email": "user@example.com", "passcode": "Abcd!234", "caption": "iPhone", "session_label": "mobile", "ttl_seconds": 3600, "ttl_refresh_enabled": true, "actor": "ops-user", "reason": "login" }
  • Success 200
json
{
  "success": true,
  "data": {
    "session_guid": "S123",
    "user_id": "U1",
    "status": "active",
    "expires_at_utc": "2025-12-11T12:00:00.000Z",
    "ttl_seconds": 3600,
    "ttl_refresh_enabled": true,
    "caption": "iPhone",
    "label": "mobile"
  },
  "build": { "...": "..." },
  "stats": { "...": "..." }
}
  • Errors: validation-error (missing fields), invalid-passcode (401; also used for unknown emails), user-not-verified/email-not-verified (403), too-many-sessions (429), session-cap-invalid (500).

POST /usm/session/validate

  • Use when touching a session to refresh sliding TTL.
  • Request
json
{ "session_guid": "S123", "actor": "ops-user", "reason": "touch" }
  • Success 200: returns session; refreshes expiry when ttl_refresh_enabled=true.
  • Errors: session-not-found (404), session-doomed (410), ttl-expired/user-suspended/user-doomed/email-unverified/email-doomed (401).

POST /usm/session/close

  • Use when logging out or revoking a session.
  • Request
json
{ "session_guid": "S123", "actor": "ops-user", "reason": "logout" }
  • Success 200: { status: "doomed", doom_reason: "closed", doomed_at_utc }
  • Errors: session-not-found (404), session-doomed (410).

POST /usm/session/get

  • Use when retrieving a specific session, optionally from archive.
  • POST read: this is a read endpoint; use POST (no GET).
  • Request
json
{ "session_guid": "S123", "include_archived": true, "actor": "ops-user" }
  • Success 200: returns active/doomed session; if not present and include_archived=true, returns archived copy when available.
  • Errors: validation-error (missing guid), session-not-found (404).

POST /usm/session/list

  • Use when paging sessions for the caller (requires an active session_guid), optionally including archived copies.
  • POST read: this is a read endpoint; use POST (no GET).
  • Request
json
{
  "session_guid": "S123",
  "status": "active",
  "limit": 8,
  "next_token": null,
  "include_archived": false,
  "label_prefix": "mob",
  "label_contains": "mobile",
  "caption_contains": "iphone",
  "since_expires_at_utc": "2025-12-11T00:00:00.000Z",
  "until_expires_at_utc": "2025-12-12T00:00:00.000Z",
  "actor": "ops-user"
}
  • Success 200
json
{
  "success": true,
  "data": {
    "sessions": [{ "session_guid": "S123", "user_id": "U1", "status": "active", "expires_at_utc": "2025-12-11T12:00:00.000Z", "ttl_seconds": 3600, "ttl_refresh_enabled": true, "caption": "iPhone", "label": "mobile" }],
    "next_token": "eyJHU0kxUEsiOiJVU0VSIy4uLiJ9",
    "archived_sessions": [],
    "archive_next_token": null
  },
  "build": { "...": "..." },
  "stats": { "...": "..." }
}

Role requirements (by endpoint family)

  • Session create/validate/get/list: no org roles; credentialed by email+passcode or session.
  • Service account + API key management: owner or service_account_admin (org-bound).
  • Operator-only: internal audits and admin flows (if documented).

Idempotency & retries

  • Session create is not idempotent; retry only after verifying the session was not created.
  • Logout/revoke operations are idempotent (repeating yields the same terminal state).
  • API key revoke and revoke_all are idempotent (safe to retry).

Common pitfalls

  • USM is POST-only, including reads and lists.
  • Auth is in the body (not headers) except api_key/validate.
  • Sessions are short-lived; handle ttl-expired and revoked as expected outcomes.

Examples (core families)

Create a session

json
{ "email": "user@example.com", "passcode": "Abcd!234", "caption": "web", "session_label": "browser" }

Response (shape):

json
{ "success": true, "data": { "session_guid": "S123" }, "build": { "...": "..." }, "stats": { "...": "..." } }

Create an API key (service account)

json
{ "service_account_guid": "SVC_GUID", "caption": "Shopify connector", "actor": "owner", "reason": "integration" }

Response (shape):

json
{ "success": true, "data": { "api_key": "REDACTED", "api_key_id": "KEY_ID" }, "build": { "...": "..." }, "stats": { "...": "..." } }
  • Notes: lists only sessions owned by the caller session’s user. statusactive | doomed | all (default active). limit clamped 1–256. next_token (or next_token_active/next_token_doomed when status=all) is opaque; echo verbatim. Filters on label/caption are best-effort. include_archived=true returns archived sessions with archive_next_token and optional archived_since/archived_until bounds.
  • Errors: missing-session/invalid-status (400), session-not-found (404), session-doomed (410), ttl-expired/user-suspended/user-doomed/email-unverified/email-doomed (401).

POST /usm/session/logout_other_devices

  • Use when revoking all other sessions for the same user (keep the current session).
  • Request
json
{ "session_guid": "S123", "actor": "ops-user", "reason": "security" }
  • Success 200: sets a per-user logout_other_devices_before_utc marker and best-effort dooms other active sessions; sessions created before the marker are rejected on validate/list with reason revoked. Returns counts only (no other users’ session GUIDs).
  • Errors: same session validity errors as session/list/session/validate (including revoked when the caller session predates the user revoke marker).

POST /usm/session/logout_everywhere

  • Use when revoking all sessions for the same user (including the current session).
  • Request
json
{ "session_guid": "S123", "actor": "ops-user", "reason": "compromise suspected" }
  • Success 200: sets a per-user revoke marker and best-effort dooms active sessions; subsequent validate/list calls for older sessions fail with revoked.
  • Errors: same session validity errors as session/list/session/validate.

Service accounts (API Gateway)

Service accounts are org-bound non-human identities (e.g., connectors/automation). They carry a set of roles and own one or more API keys.

Canonical curl headers

bash
-H "content-type: application/json"

POST /usm/service_account/create

  • Use when creating a service account for an org (requires a valid owner session_guid; org must be verified).
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "caption": "Shopify connector", "roles": ["pvv","vca"], "actor": "ops-user", "reason": "bootstrap" }
  • Success 200: returns service_account_guid, org_guid, roles, timestamps.
  • Roles: allowed values are pvv, pma, vca, owner (synonyms are accepted and canonicalized). Unknown roles are rejected.

POST /usm/service_account/list

  • Use when listing service accounts for an org (requires owner session).
  • POST read: this is a read endpoint; use POST (no GET).
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "status": "active", "limit": 8, "next_token": null }

POST /usm/service_account/status

  • Use when dooming a service account (terminal; revokes all API keys).
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "service_account_guid": "SA1", "status": "doomed", "reason": "revoke" }

API keys (API Gateway)

API keys are long-lived credentials owned by a service account. Secrets are returned only once on create; store securely.

Canonical curl headers

bash
-H "content-type: application/json"
-H "x-api-key: $API_KEY" # required for api_key/validate only

POST /usm/api_key/create

  • Use when creating a new API key for a service account (requires owner session; org must be verified).
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "service_account_guid": "SA1", "caption": "prod key" }
  • Success 200: returns api_key (secret), api_key_id, api_key_fingerprint, timestamps.

POST /usm/api_key/list

  • Use when listing API keys for a service account (requires owner session).
  • POST read: this is a read endpoint; use POST (no GET).
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "service_account_guid": "SA1", "status": "active", "limit": 8, "next_token": null }

POST /usm/api_key/revoke

  • Use when revoking (dooming) a single API key (requires owner session).
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "api_key_id": "K1", "reason": "rotate" }

POST /usm/api_key/revoke_all

  • Use when revoking all keys for a service account without dooming the service account (requires owner session).
  • Semantics: sets a service-account revoke_before_utc marker; keys with created_at < revoke_before_utc will fail api_key/validate with 401 even if their status is still active.
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "service_account_guid": "SA1", "reason": "compromise suspected" }

POST /usm/api_key/revoke_all_org

  • Use when revoking all API keys across the org (emergency kill switch; requires owner session).
  • Semantics: sets an org-level revoke_before_utc marker; all keys in the org with created_at < revoke_before_utc will fail api_key/validate with 401 even if their status is still active.
  • Request
json
{ "session_guid": "S123", "orgcode": "ACME", "reason": "org-wide compromise suspected" }

POST /usm/api_key/policy_set

  • Use when setting org-level API-key expiry policy (requires owner session; org must be verified). Default is no expiry.
  • Semantics: when api_key_max_age_seconds is set, keys with created_at older than now - api_key_max_age_seconds will fail api_key/validate with 401 (invalid-api-key, reason expired) even if their status is still active.
  • Request (enable expiry)
json
{ "session_guid": "S123", "orgcode": "ACME", "api_key_max_age_seconds": 7776000, "reason": "90d rotation policy" }
  • Request (disable expiry)
json
{ "session_guid": "S123", "orgcode": "ACME", "api_key_max_age_seconds": null, "reason": "no-expiry" }

POST /usm/api_key/validate

  • Use when authenticating as a service account (callers send the secret as header x-api-key).
  • POST read: this is a read endpoint; use POST (no GET).
  • Request
json
{ "actor": "connector", "reason": "healthcheck" }
  • Success 200: returns orgcode, org_status, roles, service_account_guid, and api_key_fingerprint.

Rules (behavioral)

  • Only verified users logging in with a verified email can create sessions.
  • Sliding expiry: validate/touch refreshes when ttl_refresh_enabled=true; otherwise expiry is fixed. Expired sessions doom with ttl-expired.
  • Doom reasons: ttl-expired, closed, logout-other-devices, logout-everywhere, revoked, user-suspended, user-doomed, email-unverified, email-doomed, manual. doomed_at_utc always set.
  • Session cap: default 1024 active per user; per-user override 32–8192 via UAS userConfigSet. Cap reached → too-many-sessions.
  • Archival: doomed sessions retained briefly, then archived; include_archived=true enables retrieval/listing by guid/user with date bounds.

CLI (API Gateway wrapper)

g3n usm commands call the same API Gateway routes. --profile is required (even though endpoints are public); --base-url overrides the default per command.

Common commands:

  • g3n usm session-create --email ... --passcode ... [--caption ...] [--session-label ...] [--ttl-seconds ...] [--ttl-refresh-enabled true|false] [--actor ...] [--reason ...] --profile ...
  • g3n usm session-validate --session-guid ... [--actor ...] [--reason ...] --profile ...
  • g3n usm session-close --session-guid ... [--actor ...] [--reason ...] --profile ...
  • g3n usm session-get --session-guid ... [--include-archived] [--actor ...] --profile ...
  • g3n usm session-list --session-guid ... [--status active|doomed|all] [--limit 8] [--next-token ...|--next-token-active ...|--next-token-doomed ...] [--include-archived] [--archive-next-token ...] [--label-prefix ...] [--label-contains ...] [--caption-contains ...] [--since-expires-at-utc ...] [--until-expires-at-utc ...] [--archived-since ...] [--archived-until ...] [--actor ...] --profile ...
  • g3n usm session-logout-other-devices --session-guid ... [--actor ...] [--reason ...] --profile ...
  • g3n usm session-logout-everywhere --session-guid ... [--actor ...] [--reason ...] --profile ...
  • Service accounts + API keys:
    • g3n usm service-account-create --orgcode ... --roles pvv vca --session-guid ... [--caption ...] [--actor ...] [--reason ...] --profile ...
    • g3n usm service-account-list --orgcode ... --session-guid ... [--status active|doomed|all] [--limit 8] [--next-token ...] --profile ...
    • g3n usm service-account-doom --orgcode ... --service-account-guid ... --session-guid ... [--reason ...] --profile ...
    • g3n usm api-key-create --orgcode ... --service-account-guid ... --session-guid ... [--caption ...] --profile ...
    • g3n usm api-key-list --orgcode ... --service-account-guid ... --session-guid ... [--status active|doomed|all] [--limit 8] [--next-token ...] --profile ...
    • g3n usm api-key-revoke --orgcode ... --api-key-id ... --session-guid ... [--reason ...] --profile ...
    • g3n usm api-key-revoke-all --orgcode ... --service-account-guid ... --session-guid ... [--reason ...] --profile ...
    • g3n usm api-key-revoke-all-org --orgcode ... --session-guid ... [--reason ...] --profile ...
    • g3n usm api-key-policy-set --orgcode ... --session-guid ... (--api-key-max-age-seconds ... | --clear) [--reason ...] --profile ...
    • g3n usm api-key-validate --api-key ... [--actor ...] [--reason ...] --profile ...

Best practices: reuse the same session_guid downstream, include actor/reason for audit clarity, and copy pagination cursors exactly as returned.

Service-account guidance: create one service account per integration instance, grant only the minimal roles needed (pvv/pma/vca), avoid owner unless it is tightly-controlled internal automation, and use api_key/revoke_all_org (org marker), api_key/revoke_all (service-account marker), or service-account doom as the emergency kill switch.

Error envelope example (canonical)

json
{
  "success": false,
  "error": {
    "error_code": "usm.conflict_revision",
    "http_status": 409,
    "retryable": false,
    "request_id": "req-123",
    "trace_id": "trace-abc",
    "major": { "tag": "conflict", "message": { "en_US": "Expected revision does not match the current record." } },
    "details": { "expected_revision": "3", "current_revision": "4" },
    "conflict_snapshot": { "revision": 4 }
  },
  "build": { "...": "..." },
  "stats": { "call": "example", "service": "usm", "timestamp_utc": "2026-01-21T00:00:00Z", "request_id": "req-123" }
}

The error block includes the following optional fields (matching the ICS/PPM/SCM canonical pattern):

  • error_code (string, optional) — machine-readable error code (e.g. usm.conflict_revision).
  • http_status (number, optional) — HTTP status code.
  • retryable (boolean, optional) — whether the caller should retry.
  • request_id (string, optional) — correlation request ID.
  • trace_id (string, optional) — distributed tracing ID.

These fields are present when available; callers should not depend on their presence.