Skip to content

Surfaces

Interactive API Explorer: Explorer

Runtime: Node.js 24. Covers payloads, responses, errors, and best-practice usage. Context passthrough (orgcode, cccode) is never required; direct Lambda actions forward them verbatim when present. Email inputs are canonicalized (trim + lowercase). The public /uas/stat API validates/canonicalizes cccode (body or x-cccode header; mismatch → 400). Bearer session_guid values are treated as secrets and are not emitted in response stats or tenant events/audits.

Surface Types (explicit)

API Gateway

  • Status: Available (public /uas/stat only).
  • Base: https://api.g3nretailstack.com/uas
  • Notes: /uas/stat is the only public API Gateway route; all other UAS actions are direct Lambda.

Direct Lambda

  • Status: Available (default for non-public UAS actions).
  • Notes: See Direct Lambda actions below; uas_stat is also invokable directly for trusted callers.

CLI

  • Status: Available.
  • Command: g3n uas ... (direct Lambda).
  • Notes: Requires --profile/AWS credentials.

MCP

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

Auth + tenancy

  • API Gateway /uas/stat uses email + passcode in the JSON body; no org/session headers are required.
  • Optional cost attribution: cccode in body or x-cccode header (validated/canonicalized).
  • Direct Lambda actions are IAM-gated for trusted callers and forward orgcode/cccode when present.

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 (public /uas/stat)

Method: POST only.

Headers (canonical)

bash
-H "content-type: application/json"
-H "x-cccode: $CCCODE" # optional

Body (JSON)

json
{ "email": "user@example.com", "passcode": "Abcd!234", "include_payment_history": false, "actor": "ops-user", "cccode": "ABCD-1234-EFGH" }

Template

bash
curl -sS -X POST "https://api.g3nretailstack.com/uas/stat" \
  -H "content-type: application/json" \
  -H "x-cccode: $CCCODE" \
  -d '{"email":"user@example.com","passcode":"Abcd!234","include_payment_history":false,"actor":"ops-user"}'

Public API (API Gateway)

POST https://api.g3nretailstack.com/uas/stat

Canonical curl headers

bash
-H "content-type: application/json"
-H "x-cccode: $CCCODE" # optional
  • Use when you need a snapshot of a user (including emails/payment methods) from a public surface.
  • Request
json
{ "email": "user@example.com", "passcode": "Abcd!234", "include_payment_history": false, "actor": "ops-user" }
  • Response
json
{
  "success": true,
  "data": { "user_id": "u123", "emails": [...], "payment_methods": [...] },
  "build": { "...": "..." },
  "revision": "rev-123",
  "stats": { "call": "stat", "service": "uas", "timestamp_utc": "2025-12-14T12:00:00Z" }
}
  • Errors: validation-error (missing credentials), unauthorized (invalid credentials; does not disclose whether the email exists), internal-error (unexpected).
  • Best practice: pass actor for audit, use the custom domain, and omit include_payment_history unless you need historical payment status. Optional cccode is validated/canonicalized (body or x-cccode header).

Optimistic concurrency (revision)

For any state-changing operation on an existing user record, you must pass expected_revision matching the current record revision.

  • Get the current revision from stat (public) or userGet/userSnapshot (direct).
  • On success, update your local expected_revision to the response revision.
  • Missing expected_revision428 expected-revision-required with error.details.{current_revision,current_record}
  • Mismatch → 409 conflict with error.details.{provided_revision,current_revision,current_record}

Direct Lambda actions (invoke payload JSON)

Direct invoke is the default for all non-public UAS actions (CLI/SDK). uas_stat is also invokable directly for trusted callers and supports user_id-based snapshots.

Users & status

  • userCreate: { email, passcode, caption?, reason?, actor? }{ user_id, account_ref }. Errors: duplicate-email, validation-error.
  • userSnapshot / userGet: { user_id, include_payment_history?, actor? } → snapshot. Errors: not-found, validation-error.
  • userStatusSet: { user_id, status, expected_revision, reason?, actor? } (FSM: unverified→verified/doom, verified↔suspended, suspended→doom). Note: the FSM also has an implicit verified → unverified transition triggered as a side-effect of emailSetPrimary when the new primary email is unverified; this emits a userStatusAutoUnverify event. Errors: invalid-transition, not-found.
  • userConfigSet: { user_id, max_active_sessions: number|null, expected_revision, reason?, actor? } (32–8192 when set) → { user_id, max_active_sessions? }. Errors: validation-error.
  • Use cases: onboard a user, fetch a snapshot for billing/ops, gate access by status, tune per-user session caps for USM.

Emails (unverified ↔ verified → doomed)

  • emailAdd / emailList: add/list emails (paginated). emailAdd requires expected_revision. Rejects duplicates across users. emailList supports limit/next_token.
  • emailIssueToken → emailConfirmToken: verification flow. Both require expected_revision. Last token wins; tokens expire (48h). Confirm marks email verified. Errors: invalid-token, token-expired, duplicate-email, validation-error.
  • emailSetPrimary: enforce single primary; primary cannot be doomed. Requires expected_revision. Side-effect: when emailSetPrimary changes the primary to an unverified email and the user status is verified, the user status is automatically downgraded to unverified. This side-effect emits a userStatusAutoUnverify event. Errors: invalid-transition, not-found.
  • emailDoom: terminal. Requires expected_revision. Errors: invalid-transition, not-found.
  • Example (list):
json
{ "user_id": "u123", "limit": 8, "next_token": null, "actor": "ops-user" }

Response: { "success": true, "data": { "emails": [...], "next_token": null }, "build": {...}, "stats": {...} }

Passcodes

  • passcodeSet / passcodeReset: { user_id, passcode, expected_revision, reason?, actor? }{ ok: true }. Enforces policy (length ≥8 with upper/lower/number/special) and reuse guard. Errors: passcode-policy-failed, passcode-reuse, validation-error, not-found.
  • Use cases: initial set after email verification, rotation, resets after compromise.

Payment methods (pending → active | suspended | doomed; active ↔ suspended; active → doomed; doomed is terminal)

  • pmCreate / pmList: add/list payment methods; pmCreate requires expected_revision. List paginated with limit/next_token. Uniqueness on processor + token_type + token. Default ordering: active → pending → suspended → doomed.
  • pmSetStatus / pmPromote / pmDemote / pmDoom: require expected_revision. Manage lifecycle; doomed removes token and is terminal. Errors: payment-uniqueness-conflict, invalid-transition, not-found.
  • pmVacateToken: requires expected_revision. Nulls stored token for a doomed/retired PM. Errors: not-found, invalid-transition.
  • Example (list with pagination):
json
{ "user_id": "u123", "limit": 5, "next_token": "eyJHU0kxUEsiOiJVU0VSIy4uLiJ9" }

Response: { "success": true, "data": { "payment_methods": [...], "next_token": "..." }, "build": {...}, "stats": {...} }

Pagination

  • limit default 8, clamped 1–256. next_token is opaque (base64 JSON); echo exactly.
  • Returned when more pages remain. Lists never return partial items within a page.

CLI (direct Lambda invokes)

Script: cli/bin/g3n.js (requires --profile, optional --region; --base-url override for API surfaces such as stat).

Examples:

  • g3n uas stat --user-id u123 --profile g3nretailstack
  • g3n uas user-create --email a@b.com --passcode 'Abcd!234' --caption 'Staff' --profile g3nretailstack
  • g3n uas email-issue-token --user-id u123 --email a@b.com --expected-revision rev-123 --actor ops --profile g3nretailstack
  • g3n uas pm-list --user-id u123 --limit 5 --profile g3nretailstack
  • Pagination (CLI cursor): g3n uas pm-list --user-id u123 --limit 2 --profile g3nretailstack → copy base64 next_token, then g3n uas pm-list --user-id u123 --next-token "$NEXT_TOKEN" --profile g3nretailstack
  • g3n uas user-config-set --user-id u123 --max-active-sessions 2048 --expected-revision rev-123 --profile g3nretailstack

Best practices: always pass --profile, reuse --actor/--reason for audit clarity, and copy next_token verbatim between paged calls.

Error envelope example (canonical)

json
{
  "success": false,
  "error": {
    "error_code": "uas.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": "uas", "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. uas.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.

Role requirements (by endpoint family)

  • Public stat: no roles; credentialed by email+passcode.
  • Direct Lambda (operator/trusted): uas_operator or operator IAM (internal onboarding admin tool).
  • Owner/member roles do not apply to UAS (identity service).

Idempotency & retries

  • Use expected_revision for any update to a revisioned user record.
  • userCreate is not idempotent; verify by email before retrying.
  • emailIssueToken replaces the prior token; retries are safe with the same expected_revision.

Common pitfalls

  • /uas/stat does not accept user_id for public callers.
  • Email is canonicalized (trim + lowercase); duplicates are case-insensitive.
  • expected_revision is required for status/email/passcode/payment updates.

Examples (core families)

User create (direct Lambda)

json
{ "email": "user@example.com", "passcode": "Abcd!234", "caption": "Retail staff", "actor": "ops-user" }

Response (shape):

json
{ "success": true, "data": { "user_id": "u123" }, "build": { "...": "..." }, "stats": { "...": "..." } }

Email verification (direct Lambda)

json
{ "user_id": "u123", "email": "user@example.com", "expected_revision": "rev-123", "actor": "ops-user" }

Response (shape):

json
{ "success": true, "data": { "token": "base64token" }, "build": { "...": "..." }, "stats": { "...": "..." } }