AnyaSelf Docs

API Gateway

Edge routing, authentication, purchases, voice proxy, and service orchestration.

The api-gateway is the singular ingress point into the AnyaSelf cluster. It handles external authentication, proxies requests to downstream services, manages the purchase approval flow, and bridges Gemini Live WebSocket connections for voice.

Architecture

graph LR
  CLIENT["Client"] --> GW["API Gateway :8080"]
  GW --> AUTH["JWT + OIDC"]
  GW --> ORCH["orchestrator :8003"]
  GW --> WARD["wardrobe :8081"]
  GW --> VTO_S["vto :8004"]
  GW --> HB["hyperbeam :8006"]
  GW --> AA["artifacts-audit :8007"]
  GW --> GEMINI["Gemini Live WS"]
  GW --> UNSPLASH["Unsplash API"]

Endpoints

Authentication & Identity

MethodPathDescription
POST/api/v1/auth/loginVerify external OIDC idToken and mint internal bearer token
GET/api/v1/meReturn authenticated principal (userId, email)

Login Response:

{
  "accessToken": "eyJhbG...",
  "tokenType": "Bearer",
  "expiresInSeconds": 3600,
  "user": {
    "userId": "usr_abc123",
    "email": "user@example.com"
  }
}

Me Response:

{
  "userId": "usr_abc123",
  "email": "user@example.com"
}

Public Discover Feed

MethodPathDescription
GET/api/v1/discover/feedUnsplash-backed public fashion inspiration feed. Query params: page, perPage, category

Feed Response:

{
  "items": [
    {
      "id": "unsplash_abc",
      "title": "Spring Essentials",
      "image": "https://images.unsplash.com/...",
      "label": "SPRING",
      "tone": "warm",
      "photographerName": "Jane Doe",
      "photographerLink": "https://unsplash.com/@janedoe",
      "unsplashLink": "https://unsplash.com/photos/abc"
    }
  ],
  "page": 1,
  "perPage": 24,
  "hasMore": true,
  "nextPage": 2
}

Household Management

MethodPathDescription
POST/api/v1/householdsCreate a new household
GET/api/v1/householdsList households for the authenticated user
GET/api/v1/households/{id}Get household detail with members and purchase requests
POST/api/v1/households/{id}/membersAdd a member to the household
DELETE/api/v1/households/{id}Delete household and all associated data

Household Response:

{
  "householdId": "h_abc123",
  "name": "The Smiths",
  "members": [
    {
      "memberId": "usr_abc123",
      "role": "PARENT/GUARDIAN",
      "displayName": "Alex",
      "addedAt": "2026-03-08T10:00:00+00:00",
      "addedBy": "usr_abc123"
    }
  ],
  "purchaseRequests": [],
  "createdAt": "2026-03-08T10:00:00+00:00",
  "updatedAt": "2026-03-08T10:00:00+00:00"
}

Delete Response:

{
  "householdId": "h_abc123",
  "deleted": true,
  "deletedMembersCount": 3,
  "deletedPurchaseRequestsCount": 2,
  "deletedAuditLogsCount": 15
}

Purchase Request Flow

MethodPathDescription
POST/api/v1/households/{id}/requestsCreate a purchase request
POST/api/v1/households/{id}/requests/{reqId}/approveGuardian approves or rejects
POST/api/v1/households/{id}/requests/{reqId}/purchase-intentsCreate purchase intent with ephemeral confirmation token
POST/api/v1/households/{id}/requests/{reqId}/cart-readyMark cart prepared (internal, requires X-Internal-Token)
POST/api/v1/households/{id}/requests/{reqId}/failedMark request failed (internal, requires X-Internal-Token)
POST/api/v1/households/{id}/requests/{reqId}/confirm-checkoutFinal checkout with intentId + confirmationToken

Purchase Request Response:

{
  "requestId": "req_xyz789",
  "requestedByMemberId": "usr_abc123",
  "forMemberId": "usr_child456",
  "constraints": { "maxPrice": 200, "category": "SHOES" },
  "status": "SUBMITTED",
  "approvals": [
    {
      "byMemberId": "usr_abc123",
      "decision": "APPROVE",
      "at": "2026-03-08T11:00:00+00:00",
      "note": "Looks good, go ahead"
    }
  ],
  "createdAt": "2026-03-08T10:00:00+00:00",
  "updatedAt": "2026-03-08T11:00:00+00:00"
}

For all purchase flow error responses, see the Error Reference → API Gateway.

Voice Live Proxy

MethodPathDescription
POST/api/v1/voice/live/sessionMint authenticated WebSocket session token
POST/api/v1/voice/live/public-sessionMint guest WebSocket session token (rate-limited)
WS/api/v1/voice/live/ws?session={token}Bidirectional audio bridge to Gemini Live

Voice Session Response:

{
  "websocketUrl": "wss://api.anyaself.com/api/v1/voice/live/ws?session=tok_...",
  "model": "gemini-live-2.5-flash-native-audio",
  "expiresInSeconds": 300
}

The gateway proxies binary WebSocket frames between clients and Google Cloud's LlmBidiService/BidiGenerateContent endpoint, authenticating via GCP OAuth2 service account credentials.

Service Proxying

All downstream service calls are proxied through path-based routing:

Path PatternTarget Service
/api/v1/households/{id}/wardrobe/...wardrobe :8081
/api/v1/households/{id}/orchestrator/...orchestrator :8003
/api/v1/households/{id}/vto/...vto :8004
/api/v1/households/{id}/hyperbeam/...hyperbeam-bridge :8006

Audit

MethodPathDescription
GET/api/v1/households/{id}/audit-logsRetrieve household audit log entries

Audit Log Response:

{
  "logId": "log_abc123",
  "householdId": "h_abc123",
  "actorUserId": "usr_abc123",
  "action": "PURCHASE_REQUEST_CREATED",
  "targetType": "PurchaseRequest",
  "targetId": "req_xyz789",
  "details": {},
  "createdAt": "2026-03-08T10:00:00+00:00"
}

Configuration

VariableDefaultDescription
APP_ENVdevRuntime environment (dev, staging, prod)
AUTH_JWT_SECRETdev-secret-change-meShared JWT signing secret (rejected in prod)
AUTH_JWT_ALGHS256JWT algorithm
AUTH_ACCESS_TOKEN_TTL_SECONDS3600Internal token lifetime
AUTH_EXTERNAL_LOGIN_ENABLEDfalseEnable OIDC external login flow
AUTH_EXTERNAL_JWKS_URLJWKS endpoint for external token verification
AUTH_EXTERNAL_ISSUERExpected token issuer
AUTH_EXTERNAL_AUDIENCEExpected token audience
AUTH_EXTERNAL_ALGORITHMSRS256External token algorithm
AUTH_EXTERNAL_REQUIRE_EXPtrue (staging/prod)Require expiry claim
CHECKOUT_CONFIRMATION_TTL_SECONDS900Purchase confirmation token TTL
BUYFLOW_INTERNAL_TOKENdev-internal-tokenShared secret for internal buy-flow endpoints
REQUIRE_BUYFLOW_INTERNAL_TOKENtrue (staging/prod)Require X-Internal-Token for cart-ready/failed
PERSISTENCE_BACKENDinmemoryfirestore or inmemory
VOICE_LIVE_ENABLEDtrue (staging/prod)Enable voice proxy
VOICE_LIVE_API_KEYGemini API key for voice proxy
VOICE_LIVE_MODELgemini-live-2.5-flash-native-audioVoice model identifier
VOICE_LIVE_SESSION_TTL_SECONDS300Authenticated voice session lifetime
VOICE_LIVE_PUBLIC_SESSION_ENABLEDtrueEnable guest voice sessions
VOICE_LIVE_PUBLIC_SESSION_TTL_SECONDS300Guest session lifetime
VOICE_LIVE_PUBLIC_RATE_LIMIT_WINDOW_SECONDS60Rate limit window
VOICE_LIVE_PUBLIC_RATE_LIMIT_MAX_REQUESTS12Max public sessions per window
UNSPLASH_ENABLEDautoEnabled when UNSPLASH_ACCESS_KEY is set
UNSPLASH_ACCESS_KEYUnsplash API access key
UNSPLASH_APP_NAMEanyaselfUTM attribution app name
UNSPLASH_TIMEOUT_SECONDS6.0Unsplash API timeout
UNSPLASH_CACHE_TTL_SECONDS900In-memory cache TTL for feed responses
ARTIFACTS_AUDIT_BASE_URLhttp://artifacts-audit:8007/api/v1Audit service URL
ARTIFACTS_AUDIT_ENABLEDtrueEnable audit log writes
ARTIFACTS_AUDIT_REQUIREDfalseFail if audit service is unreachable

On this page