{"openapi":"3.1.0","info":{"title":"xRWA API","version":"0.1.0","description":"Live market data, email accounts and workspace sync for xRWA, plus issuer price observations and public registry metadata. No custody, signing, on-chain execution, settlement authority, or verified oracle authority is provided. Accounts settle in test USDC on the xRWA ledger."},"servers":[{"url":"/","description":"The current xRWA deployment"}],"tags":[{"name":"status","description":"Liveness and observation-log and account-store readiness"},{"name":"observations","description":"Allowlisted, indicative-only market observations"},{"name":"metadata","description":"Public registry metadata, not verified oracle updates"},{"name":"liquidity","description":"Optional authenticated soft-quote measurements, never executable"},{"name":"devnet","description":"User-initiated, read-only Devnet wallet observations; never signing or settlement"},{"name":"admin","description":"Single-operator email/password login with cookie-authenticated monitoring and site-notice controls; never execution or settlement authority"},{"name":"telemetry","description":"Aggregate page beacons and the public site notice"},{"name":"markets","description":"Live Solana market prices and recorded price history for listed vault tokens"},{"name":"accounts","description":"Email sign-in, session cookies and per-account workspace sync"}],"paths":{"/api/markets":{"get":{"operationId":"getMarkets","tags":["markets"],"summary":"Live prices for listed vault tokens","description":"Latest Jupiter Price API quotes for each listed vault token, with 24-hour change, a 24-hour spark series and the issuer multiplier when known. Polled server-side every 60 seconds; stale rows are flagged, never substituted.","responses":{"200":{"description":"Live market snapshot","content":{"application/json":{"schema":{"type":"object","required":["source","markets"],"properties":{"source":{"const":"jupiter-price-v3"},"updatedAt":{"type":["string","null"],"format":"date-time"},"markets":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"assetId":{"type":"string"},"mint":{"type":"string"},"price":{"type":["number","null"]},"change24hPct":{"type":["number","null"]},"liquidityUsd":{"type":["number","null"]},"multiplier":{"type":["number","null"]},"observedAt":{"type":["string","null"]},"stale":{"type":"boolean"},"spark":{"type":["array","null"],"items":{"type":"number"}}}}}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/markets/{symbol}/history":{"get":{"operationId":"getMarketHistory","tags":["markets"],"summary":"Recorded price history for one listed token","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["1D","1W","1M","ALL"],"default":"1D"}}],"responses":{"200":{"description":"Time-ordered [epochMs, usdPrice] points recorded by the server","content":{"application/json":{"schema":{"type":"object","properties":{"symbol":{"type":"string"},"range":{"type":"string"},"firstAt":{"type":["string","null"]},"points":{"type":"array","items":{"type":"array","prefixItems":[{"type":"integer"},{"type":"number"}]}}}}}}},"400":{"description":"Unknown range"},"404":{"description":"Unknown market"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/devnet/balance":{"post":{"operationId":"getDevnetWalletBalance","tags":["devnet"],"summary":"Read one public wallet SOL balance on Devnet","description":"Same-origin and rate-limited. Called only after the user explicitly requests a balance check. Uses the encrypted operator Devnet RPC profile when configured, otherwise Solana public Devnet RPC; asserts the official Devnet genesis hash before getBalance. The public key is not persisted, the short in-memory cache expires, and no signature or transaction is created.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address"],"additionalProperties":false,"properties":{"address":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$"}}}}}},"responses":{"200":{"description":"Confirmed Devnet SOL balance in lamports; provider label is sanitized"},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/auth/register":{"post":{"operationId":"register","tags":["accounts"],"summary":"Create an account with email and password","description":"No verification code is required. Sets an HttpOnly, SameSite=Lax session cookie. JSON bodies only; cross-site requests are refused.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","minLength":8,"maxLength":128},"name":{"type":"string","maxLength":60}}}}}},"responses":{"201":{"description":"Account created and signed in"},"400":{"description":"Invalid email, password or name"},"409":{"description":"Email already registered"},"415":{"description":"Body was not JSON"},"429":{"description":"Too many attempts"}}}},"/api/auth/login":{"post":{"operationId":"login","tags":["accounts"],"summary":"Sign in with email and password","description":"Sets an HttpOnly, SameSite=Lax session cookie valid for 30 days. Failures never reveal whether an email is registered.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Signed in"},"401":{"description":"Email or password is incorrect"},"429":{"description":"Too many attempts"}}}},"/api/auth/logout":{"post":{"operationId":"logout","tags":["accounts"],"summary":"Revoke the current session","responses":{"204":{"description":"Session revoked and cookie cleared"}}}},"/api/auth/session":{"get":{"operationId":"getSession","tags":["accounts"],"summary":"Report whether the request is signed in","responses":{"200":{"description":"authenticated flag, plus the signed-in user when present"}}}},"/api/account/workspace":{"get":{"operationId":"getWorkspace","tags":["accounts"],"summary":"Load the signed-in account workspace","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"The saved ledger and Risk Lab scenarios, or null for a new account"},"401":{"description":"Not signed in"}}},"put":{"operationId":"saveWorkspace","tags":["accounts"],"summary":"Save the signed-in account workspace","description":"Accepts an xRWA workspace export. The ledger is validated structurally before it is stored; one account can never read or write another account workspace.","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Saved"},"400":{"description":"Workspace failed validation"},"401":{"description":"Not signed in"},"413":{"description":"Workspace exceeds 1.5 MB"}}}},"/api/health":{"get":{"operationId":"getHealth","tags":["status"],"summary":"Describe runtime boundaries","responses":{"200":{"$ref":"#/components/responses/Health"}}}},"/api/version":{"get":{"operationId":"getVersion","tags":["status"],"summary":"Return build and runtime identity","description":"Returns sanitized release metadata and immutable test-USDC ledger boundary flags. It never exposes environment variables, credentials, or execution capabilities.","responses":{"200":{"$ref":"#/components/responses/Version"}}}},"/api/ready":{"get":{"operationId":"getReadiness","tags":["status"],"summary":"Check observation-log and account-store readiness","responses":{"200":{"$ref":"#/components/responses/Ready"},"503":{"$ref":"#/components/responses/Ready"}}}},"/api/metrics":{"get":{"operationId":"getMetrics","tags":["status"],"summary":"Return privacy-safe process-local counters","description":"This public read-only diagnostic generates a server-side request ID, is not an authentication boundary, and exposes only bounded counters. Counters reset when the process restarts; no IP addresses, credentials, quote payloads, or user data are retained.","responses":{"200":{"$ref":"#/components/responses/Metrics"}}}},"/api/openapi.json":{"get":{"operationId":"getOpenApi","tags":["status"],"summary":"Return this API description","responses":{"200":{"description":"OpenAPI 3.1 document","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocument"}}}}}}},"/api/indicative/{symbol}":{"get":{"operationId":"getIndicative","tags":["observations"],"summary":"Fetch one public indicative observation","description":"The returned quote is not a settlement input. A missing or invalid upstream response remains an error; no synthetic fallback is created.","parameters":[{"$ref":"#/components/parameters/Symbol"}],"responses":{"200":{"$ref":"#/components/responses/Indicative"},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/Error"}}}},"/api/observations/{symbol}":{"get":{"operationId":"listObservations","tags":["observations"],"summary":"List persisted indicative observations","description":"History is bounded and schema-validated. Every record is marked settlementEligible=false.","parameters":[{"$ref":"#/components/parameters/Symbol"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"$ref":"#/components/responses/Observations"},"400":{"$ref":"#/components/responses/Error"}}}},"/api/oracles/{symbol}":{"get":{"operationId":"getOracleMetadata","tags":["metadata"],"summary":"Fetch public oracle registry metadata","description":"This endpoint discovers provider and feed identifiers only. It does not fetch, verify, or authorize an on-chain oracle update.","parameters":[{"$ref":"#/components/parameters/Symbol"},{"$ref":"#/components/parameters/Network"},{"$ref":"#/components/parameters/ManagedBy"}],"responses":{"200":{"$ref":"#/components/responses/OracleMetadata"},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/Error"}}}},"/api/liquidity/{symbol}":{"get":{"operationId":"probeLiquidity","tags":["liquidity"],"summary":"Request bounded non-executable soft quotes","description":"Requires an operator-supplied XSTOCKS_API_KEY. Results are measurements, not an order book, execution authorization, or a settlement input; they are never a settlement input. The route is limited to 10 requests per client IP per fixed 60-second window.","parameters":[{"$ref":"#/components/parameters/Symbol"},{"$ref":"#/components/parameters/Network"},{"$ref":"#/components/parameters/Side"},{"$ref":"#/components/parameters/Quantities"}],"responses":{"200":{"$ref":"#/components/responses/Liquidity"},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/LiquidityUnavailable"}}}},"/api/site-notice":{"get":{"operationId":"getSiteNotice","tags":["telemetry"],"summary":"Return the operator-controlled public site notice","description":"Public read of the operator site notice. It is display copy only and never a protocol state or authorization.","responses":{"200":{"description":"Site notice state","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"},"text":{"type":"string","maxLength":280}}}}}}}}},"/api/telemetry/page":{"post":{"operationId":"recordPageBeacon","tags":["telemetry"],"summary":"Record one aggregate single-page-app page view","description":"Accepts only an allowlisted route name. No addresses, identifiers, query strings, or payloads are stored. Responds 204 with no body either way.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["route"],"properties":{"route":{"type":"string","enum":["markets","learn","calculator","earn","boost","portfolio","risk","liquidity","activity","architecture","settings","admin"]}}}}}},"responses":{"204":{"description":"Beacon accepted or ignored"},"400":{"$ref":"#/components/responses/Error"},"405":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/admin/login":{"post":{"operationId":"loginAdmin","tags":["admin"],"summary":"Create the one configured operator session","description":"No signup is available. Forgot-password recovery uses a one-time code issued by a production server operator; no email is sent. Requires the configured email/password, an HTTPS origin in production, and returns a CSRF token while placing an HttpOnly session cookie. A bootstrap password requires change before any operator data or controls are available.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","minLength":8,"maxLength":256,"writeOnly":true}}}}}},"responses":{"200":{"description":"Operator session and CSRF token","content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","const":"operator"},"authenticated":{"type":"boolean","const":true},"csrfToken":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"passwordChangeRequired":{"type":"boolean","description":"True for the initial environment-provisioned password until changed."}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/admin/logout":{"post":{"operationId":"logoutAdmin","tags":["admin"],"summary":"Revoke the operator session","security":[{"adminSession":[]}],"parameters":[{"name":"X-CSRF-Token","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Session revoked and cookie cleared"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/admin/password":{"post":{"operationId":"changeAdminPassword","tags":["admin"],"summary":"Change the single operator password","description":"Requires the current password, a new password of at least eight characters, a valid session cookie, same-origin Origin, and X-CSRF-Token. Stores a scrypt hash in the persistent server data volume and revokes all sessions. Recovery uses the separate same-origin HTTPS route with a one-time server-issued code.","security":[{"adminSession":[]}],"parameters":[{"name":"X-CSRF-Token","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["currentPassword","newPassword"],"properties":{"currentPassword":{"type":"string","writeOnly":true},"newPassword":{"type":"string","minLength":8,"maxLength":256,"writeOnly":true}}}}}},"responses":{"200":{"description":"Password changed; session revoked"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/admin/password/recover":{"post":{"operationId":"recoverAdminPassword","tags":["admin"],"summary":"Redeem a server-issued one-time admin recovery code","description":"Not email recovery. An operator with production shell access issues a 30-minute code; only its SHA-256 digest is stored. Redemption requires same-origin HTTPS, consumes the code once, stores a scrypt password hash, and revokes sessions.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","newPassword"],"properties":{"token":{"type":"string","minLength":64,"maxLength":64,"writeOnly":true},"newPassword":{"type":"string","minLength":8,"maxLength":256,"writeOnly":true}}}}}},"responses":{"200":{"description":"Password recovered; all sessions revoked"},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/admin/solana-rpc":{"get":{"operationId":"getAdminSolanaRpc","tags":["admin"],"summary":"Read Solana RPC configuration status","description":"Returns only configured/keyConfigured booleans. Endpoint and key values are never returned. This endpoint accesses encrypted local configuration only; it performs no RPC request, signing, or transaction execution. Mainnet config does not enable mainnet.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Redacted configuration status"},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}},"put":{"operationId":"updateAdminSolanaRpc","tags":["admin"],"summary":"Save one network RPC configuration","description":"Encrypted local configuration only; no outbound RPC calls, signing, or transaction execution. Exactly one network may be updated per request. Devnet accepts https://api.devnet.solana.com/ without a key, https://devnet.helius-rpc.com/ with the key in the separate field, or https://solana-devnet.g.alchemy.com/v2 with the Alchemy key in the separate apiKey field. A full Alchemy endpoint pasted in url is normalized and its path key is encrypted separately. Other hosts, query strings, and paths are rejected. API keys are write-only and never returned. Mainnet settings do not enable mainnet execution.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"maxProperties":1,"properties":{"devnet":{"type":"object","properties":{"url":{"type":"string","maxLength":2048},"apiKey":{"type":"string","maxLength":512,"writeOnly":true},"clearKey":{"type":"boolean"}}},"mainnet":{"type":"object","properties":{"url":{"type":"string","maxLength":2048},"apiKey":{"type":"string","maxLength":512,"writeOnly":true},"clearKey":{"type":"boolean"}}}}}}}},"responses":{"200":{"description":"Redacted configuration status"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/admin/solana-rpc/test":{"post":{"operationId":"testDevnetSolanaRpc","tags":["admin"],"summary":"Inspect Devnet RPC, deployed program, and ProgramData metadata","description":"Authenticated read-only probe of Devnet getGenesisHash/getVersion and the executable program plus its upgradeable-loader ProgramData account at confirmed commitment. Returns ProgramData authority, deployment slot, byte length, and SHA-256 of the raw data tail after loader metadata. The digest is not compared with a source build and does not establish verification. Does not inspect initialized protocol config or sign/send transactions.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","maxProperties":0,"additionalProperties":false}}}},"responses":{"200":{"description":"Devnet connectivity and sanitized program-account metadata (credentials and account data excluded)","content":{"application/json":{"schema":{"type":"object","required":["network","reachable","genesisHash","solanaCore","program","latencyMs"],"properties":{"network":{"type":"string","const":"devnet"},"reachable":{"type":"boolean","const":true},"genesisHash":{"type":"string"},"solanaCore":{"type":"string"},"program":{"oneOf":[{"type":"object","required":["deployed","slot"],"properties":{"deployed":{"type":"boolean","const":false},"slot":{"type":"integer","minimum":0}}},{"type":"object","required":["deployed","owner","executable","lamports","slot","programData"],"properties":{"deployed":{"type":"boolean","const":true},"owner":{"type":"string","const":"BPFLoaderUpgradeab1e11111111111111111111111"},"executable":{"type":"boolean","const":true},"lamports":{"type":"integer","minimum":0},"slot":{"type":"integer","minimum":0},"programData":{"type":"object","required":["address","slot","contextSlot","upgradeAuthority","rawPayloadBytes","rawPayloadSha256"],"properties":{"address":{"type":"string"},"slot":{"type":"integer","minimum":0},"contextSlot":{"type":"integer","minimum":0},"upgradeAuthority":{"type":["string","null"]},"rawPayloadBytes":{"type":"integer","minimum":1,"maximum":1000000},"rawPayloadSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}}}}}]},"latencyMs":{"type":"integer","minimum":0}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/admin/session":{"get":{"operationId":"getAdminSession","tags":["admin"],"summary":"Verify the operator session","description":"HttpOnly session-cookie authentication. Missing server account configuration returns 503; unauthenticated sessions return 401. passwordChangeRequired gates admin data and controls until bootstrap password rotation.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Operator session accepted","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"type":"object","required":["role","authenticated","passwordChangeRequired"],"properties":{"role":{"type":"string","const":"operator"},"authenticated":{"type":"boolean","const":true},"startedAt":{"type":"string","format":"date-time"},"csrfToken":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"passwordChangeRequired":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/admin/analytics":{"get":{"operationId":"getAdminAnalytics","tags":["admin"],"summary":"Return aggregate traffic analytics","description":"Daily aggregate counts, anonymous session counts, redacted recent entries, and the privacy statement. No IP addresses, user agents, accounts, or personal identifiers are included.","security":[{"adminSession":[]}],"parameters":[{"name":"days","in":"query","description":"Days of history (1-90, default 14)","schema":{"type":"integer","minimum":1,"maximum":90}}],"responses":{"200":{"description":"Aggregate analytics snapshot","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}}},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/admin/settings":{"get":{"operationId":"getAdminSettings","tags":["admin"],"summary":"Return the safe operator settings view","security":[{"adminSession":[]}],"responses":{"200":{"description":"Operator settings view","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}}},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}},"put":{"operationId":"updateAdminSettings","tags":["admin"],"summary":"Update analytics collection and the site notice. Settings are committed before success is returned; file persistence failures return 503 without applying the change. The settings read view exposes boolean load/save health only.","description":"The only writable fields are the analytics toggle and the bounded site notice. No custody, signing, execution, or settlement capability exists behind this route.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"analyticsEnabled":{"type":"boolean"},"notice":{"type":"object","properties":{"enabled":{"type":"boolean"},"text":{"type":"string","maxLength":280}}}}}}}},"responses":{"200":{"description":"Updated operator settings view","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"adminSession":{"type":"apiKey","in":"cookie","name":"__Host-xrwa-admin","description":"HttpOnly, single-operator session cookie; writes require same-origin Origin and X-CSRF-Token."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"xrwa_session","description":"Session cookie set by register or login."}},"headers":{"SchemaVersion":{"description":"Stable additive payload schema version for this read-only API. A breaking payload change increments the integer.","schema":{"type":"integer","const":1},"example":1},"RateLimitLimit":{"description":"Maximum requests permitted for this route in the fixed 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimitRemaining":{"description":"Requests remaining in the current window; never negative.","schema":{"type":"integer","minimum":0}},"RateLimitReset":{"description":"Unix epoch seconds when the current fixed window resets.","schema":{"type":"integer","format":"int64"}},"RetryAfter":{"description":"Seconds to wait before retrying; present only on a 429 response.","schema":{"type":"integer","minimum":1,"maximum":60}}},"parameters":{"Symbol":{"name":"symbol","in":"path","required":true,"description":"Allowlisted xStocks symbol, for example SPYx.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]+$"}},"Limit":{"name":"limit","in":"query","required":false,"description":"Number of persisted records to return (1–200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":200}},"Network":{"name":"network","in":"query","required":false,"description":"Provider network filter.","schema":{"type":"string","maxLength":64}},"ManagedBy":{"name":"managedBy","in":"query","required":false,"description":"Oracle metadata manager filter.","schema":{"type":"string","enum":["Internal","Chainlink","Pyth"]}},"Side":{"name":"side","in":"query","required":false,"description":"Soft-quote direction.","schema":{"type":"string","enum":["Buy","Sell"],"default":"Sell"}},"Quantities":{"name":"quantities","in":"query","required":false,"description":"Comma-separated quantities; each is a bounded positive decimal.","schema":{"type":"string","default":"1,5,10"}}},"schemas":{"Error":{"type":"object","required":["schemaVersion","error"],"properties":{"schemaVersion":{"const":1},"error":{"type":"string"},"detail":{"type":"string"}}},"Health":{"type":"object","required":["schemaVersion","mode","custody","onchainExecution","oracleVerification","marketNumbers"],"properties":{"schemaVersion":{"const":1},"mode":{"const":"test-usdc-ledger"},"custody":{"const":false},"onchainExecution":{"const":false},"oracleVerification":{"const":false},"marketNumbers":{"const":"synthetic"}}},"Version":{"type":"object","required":["schemaVersion","app","version","mode","releaseSha","startedAt","custody","onchainExecution","oracleVerification"],"properties":{"schemaVersion":{"const":1},"app":{"const":"xrwa"},"version":{"const":"0.1.0"},"mode":{"const":"test-usdc-ledger"},"releaseSha":{"type":"string","pattern":"^(unknown|[0-9a-f]{40})$"},"startedAt":{"type":"string","format":"date-time"},"custody":{"const":false},"onchainExecution":{"const":false},"oracleVerification":{"const":false}}},"Ready":{"type":"object","required":["schemaVersion","ready","observationLogReady","accountsStoreReady"],"properties":{"schemaVersion":{"const":1},"ready":{"type":"boolean"},"observationLogReady":{"type":"boolean"},"accountsStoreReady":{"type":"boolean"},"error":{"type":["string","null"]}}},"Metrics":{"type":"object","required":["kind","schemaVersion","app","bootId","startedAt","uptimeSeconds","resetOnRestart","sensitiveDataExcluded","exposure","routeLabels","eventNames","requests","events"],"properties":{"kind":{"const":"process-local-metrics"},"schemaVersion":{"const":1},"app":{"const":"xrwa"},"bootId":{"type":"string","format":"uuid"},"startedAt":{"type":"string","format":"date-time"},"uptimeSeconds":{"type":"integer","minimum":0},"resetOnRestart":{"const":true},"sensitiveDataExcluded":{"const":true},"exposure":{"const":"public-read-only"},"routeLabels":{"type":"array","items":{"type":"string"}},"eventNames":{"type":"array","items":{"type":"string"}},"requests":{"type":"object"},"events":{"type":"object"}}},"IndicativeRecord":{"type":"object","required":["kind","settlementEligible","onchainVerified"],"properties":{"kind":{"const":"indicative-http"},"settlementEligible":{"const":false},"onchainVerified":{"const":false},"quote":{"type":"number"},"fetchedAt":{"type":"string","format":"date-time"}}},"Indicative":{"type":"object","required":["schemaVersion","kind","settlementEligible","onchainVerified"],"properties":{"schemaVersion":{"const":1},"kind":{"const":"indicative-http"},"settlementEligible":{"const":false},"onchainVerified":{"const":false},"quote":{"type":"number"},"fetchedAt":{"type":"string","format":"date-time"}}},"Observations":{"type":"object","required":["schemaVersion","symbol","kind","settlementEligible","integrity","observations"],"properties":{"schemaVersion":{"const":1},"symbol":{"type":"string"},"kind":{"const":"indicative-http"},"settlementEligible":{"const":false},"limit":{"type":"integer"},"count":{"type":"integer"},"truncated":{"type":"boolean"},"integrity":{"type":"object","required":["algorithm","scope","digest"],"properties":{"algorithm":{"const":"sha-256"},"scope":{"const":"ordered-observations-array"},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$"}}},"observations":{"type":"array","items":{"$ref":"#/components/schemas/IndicativeRecord"}}}},"OracleMetadata":{"type":"object","required":["schemaVersion","metadataOnly","onchainVerified","settlementEligible"],"properties":{"schemaVersion":{"const":1},"metadataOnly":{"const":true},"onchainVerified":{"const":false},"settlementEligible":{"const":false},"records":{"type":"array","items":{"type":"object"}}}},"Liquidity":{"type":"object","required":["schemaVersion","kind","metadataOnly","executable","onchainVerified","settlementEligible"],"properties":{"schemaVersion":{"const":1},"kind":{"const":"liquidity-soft-quote"},"metadataOnly":{"const":true},"executable":{"const":false},"onchainVerified":{"const":false},"settlementEligible":{"const":false},"quotes":{"type":"array","items":{"type":"object"}}}},"OpenApiDocument":{"type":"object","required":["openapi","info","paths"],"properties":{"openapi":{"const":"3.1.0"},"info":{"type":"object"},"paths":{"type":"object"}}}},"responses":{"Error":{"description":"Client or upstream error; no fallback value was substituted. Upstream detail is a bounded public category and never includes provider URLs, headers, bodies, credentials, or stack traces.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"The per-client-IP request limit was exceeded for the fixed 60-second window. Response headers contain the reset time and retry delay; they never contain the client IP or limiter key.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Health":{"description":"Runtime boundary report.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"Version":{"description":"Sanitized build and runtime identity. Release metadata is informational and does not authorize deployment or settlement.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Version"}}}},"Ready":{"description":"Observation-log and account-store readiness report.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ready"}}}},"Metrics":{"description":"Privacy-safe process-local counters; reset on restart.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Metrics"}}}},"Indicative":{"description":"Indicative-only observation. The response includes fixed-window rate-limit headers.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Indicative"}}}},"Observations":{"description":"Bounded indicative history.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Observations"}}}},"OracleMetadata":{"description":"Public registry metadata only. The response includes fixed-window rate-limit headers.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OracleMetadata"}}}},"Liquidity":{"description":"Controlled soft quotes, never executable. The response includes fixed-window rate-limit headers.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Liquidity"}}}},"LiquidityUnavailable":{"description":"No authorized provider credential is configured. Fixed-window rate-limit headers are included.","headers":{"X-XRWA-Schema-Version":{"$ref":"#/components/headers/SchemaVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Liquidity"}}}}}}}