App API reference
Every HTTP route in the audited app, grouped by purpose and authority.
These are the app's current HTTP routes, not a separately versioned public trading API. Call them on the application origin, not this documentation site. Most wallet trades and contract actions are submitted directly through the market package rather than an HTTP trade endpoint.
Reading responses correctly
Amounts in base units travel as decimal strings. Preserve them as integers; do not turn them into floating-point currency values before applying the collateral's decimals. Timestamp fields ending Ms use milliseconds; Sec fields use seconds.
Many routes return configured: false when a dependency is absent. That is not an empty account. A quote or submitted receipt is not a confirmed fill. Check HTTP status and the route's result field rather than assuming any JSON response means success.
The inventory below covers all 39 route files, including the onboarding faucet added on 7 September 2026.
Market information
| Method and path | Request | Result |
|---|---|---|
GET /api/status | None | Fresh RPC/indexer/feed/store status, lag and model-configuration check. |
GET /api/leaderboard | None | Venue-wide rankings derived from the fill/settlement record. |
GET /api/traction | None | Usage measures derived from the venue scan. |
GET /api/news | None | Up to eight recent RSS headlines from configured feeds. |
News sentiment tags are keyword heuristics, not model analysis or trading signals. Status's model row checks configuration; it does not establish that a billed model request would succeed.
Sensei and strategies
| Method and path | Request | Result or authority |
|---|---|---|
POST /api/sensei | messages, nullable snapshot, restless | AI reply; no trade is placed. Requires server model credential. |
GET /api/strategies | None | Registry catalogue joined with readable fills, heartbeats and decisions. |
GET /api/strategies/health | Optional comma-separated ids query | Per-strategy heartbeat-derived state. |
POST /api/strategies/preview | persona, posture, cadences, stakeBase | One real model read and gate result. Rate-limited; no trade or stored decision. |
POST /api/strategies/playbook | strategyId, creator, issuedAtMs, body, signature | Saves plain-text playbook after creator signature and on-chain creator check. |
Sensei accepts up to 12 user/assistant messages, each up to 4,000 characters. Its snapshot has priceUsd and up to eight market entries with asset, cadence, time left, opening line and separate side quotes. It is caller-supplied context, not a server claim of independent price verification.
Agent preview Persona is capped at 600 characters. Posture is guarded, balanced or active; supported cadences are 300, 900, 3,600, 14,400 and 86,400 seconds. Its response separates verdict from gate, includes model/prompt hash, and may show that the preview ran outside the normal decision slot.
Strategy publication, grant creation and subscription are contract transactions. They are not hidden effects of these read APIs.
Market Rooms and Takes
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/room/status | None | Whether the social store is configured. |
POST /api/room/join | marketId, address, issuedAtMs, signature | Wallet signature and bettor/position eligibility check; returns room token. |
GET /api/room | marketId, token query | Up to 100 comments; requires matching live room token. |
POST /api/room | marketId, token, body | Posts comment as token's author; body up to 280 characters. |
GET /api/room/bet | marketId, address query | Whether the bettor registry has a record for that wallet/Window. |
POST /api/room/bet | marketId, address, txHash, route | Checks successful receipt and wallet participation, then records the bettor. |
GET /api/takes | Optional limit query | Public feed; default 30, maximum 100. |
POST /api/takes | marketId, side, caption, address, issuedAtMs, signature | Signed public Take, with market facts and a server-derived eligibility badge. |
Room join signatures and Take signatures expire after five minutes. A room token lasts one hour. Market Rooms use API access control; the server can read the comments.
The bettor route accepts wallet, vault, leverage or private. Its receipt participation check is not a general-purpose proof that an arbitrary transaction established every supplied market fact. Use the application's intended receipt-reporting flow.
Normalize a Take caption before signing with the shared helper; it must match the submitted bytes and is capped at 240 characters. A Take is a public social record in the database, not itself an on-chain trade.
X account routes
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/x/start | Optional relative return query | Starts OAuth 1.0a and redirects to X. |
GET /api/x/callback | X supplies oauth_token, oauth_verifier | Verifies browser flow, obtains identity and sets signed session cookie. |
GET /api/x/status | Optional wallet query | Sign-in identity, durable binding, configuration and executor address. |
POST /api/x/bind | wallet, issuedAtMs, signature | Links signed-in X author to proven wallet. |
POST /api/x/unlink | Same signed-wallet fields | Removes matching binding and clears session cookie. |
GET /api/x/receipts | Required wallet query | Public wallet mention receipts, newest first, limit 30. |
The account id used by bind/unlink comes from the signed server cookie, never the body. A wallet already bound to an account must be unlinked by its bound wallet before that account can move elsewhere. Use the shared link-message builders; do not handwrite a similar-looking signature string.
The separate ops relay processes mentions. There is no HTTP endpoint here that replaces the required on-chain Executor grant.
Test funds
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/faucet | Optional wallet address query | Public funding address, readiness, fresh balances, remaining rolling allocation and latest wallet claim. Does not broadcast a transfer. |
POST /api/faucet/challenge | { wallet } | Returns { id, message, expiresAtMs } for a five-minute, origin/network/wallet-bound ownership signature. |
POST /api/faucet | { id, signature } | Verifies the stored message, enforces eligibility and durably reserves an STT transfer before broadcasting. Returns { claim }. |
A claim exposes id, amountWei, txHash, status and nextClaimAtMs. Status is prepared, confirmed, reverted or conflict. Prepared means reserved/possibly submitted, not paid with certainty. Amounts are 18-decimal STT base-unit strings. The API never includes the funding key, raw signed transaction or connection identifier.
Retry a saved request with its original id and signature to reconcile the same transfer, even after the challenge expires. A new request must still be within five minutes and from the connection that obtained the challenge. Wallet ownership alone does not bypass cooldown, balance, global allocation or shared-connection caps. See configuration.
Invalid input uses HTTP 400, invalid ownership/origin 403, eligibility or pending-transfer holds 409, request/cooldown/allocation limits 429 and unavailable dependencies/refill 503. Read both status and code/error; an HTTP timeout may follow a persisted transfer. These routes do not mint tUSDC: the wallet signs that separate SDK transaction.
Sponsorship
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/sponsor | None | Sponsor address, balance, forwarder and function allowlist. |
POST /api/sponsor | { request } signed forward request | Policy checks and verified forwarding of an allowed EventVault call. |
GET /api/games/sponsor | None | Duel gas sponsor configuration, balance and readiness. |
POST /api/games/sponsor | matchId, player, agent | Tops up the arena-approved seat key after chain checks. |
Both write routes use the x-masayume-device header for rate gating. It is a rate-limit identifier, not proof of wallet ownership.
A forward request contains from, to, value, gas, deadlineSec, data and signature. The sponsor checks EventVault target, allowlisted function, zero native value, gas ceiling and deadline, then asks the forwarder to verify the signature. Capital intake is excluded.
Duel sponsorship sends STT to a named live seat key; it does not forward the player's pick through ERC2771. Funded-seat and request counters are process-local.
Private desk
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/private/status | None | Desk readiness, named contract/key, pause state and stake limits. |
POST /api/private/open | owner, marketId, side, stakeBase, minQuantityRaw, issuedAtMs, signature | Verifies owner instruction, then runs charge/fund/mint and returns signed ticket or refusal/unknown state. |
POST /api/private/cashout | claim, signature | Verifies desk-signed claim and resumes settlement/sweep/credit. |
A claim contains owner, slotId, creditKey, marketId, outcomeIdx, stakeBase and issuedAtMs. The owner's address comes from signed claim bytes. Cash-out returns to private balance, not directly to a supplied destination wallet.
Private opens require a canonical signature. A new charge requires fresh authorization; resuming an already landed charge may reuse the older authorization so funds are not stranded. See Private mode before integrating this trust model.
Duel discovery, room identity and history
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/games/room-token | None | Public arena, chain and room URL. |
POST /api/games/room-token | First: wallet, key, issuedAtMs, signature; renew: token | Signed room credential, expiry, session end and URL. |
GET /api/games/occupancy | None | Queue counts/pairing state through the room service; no player list. |
GET /api/games/history | Required address query | Latest 50 projected duels for a wallet. |
GET /api/games/rank | Optional address query | Top 50 ladder rows, optional personal row and season eligibility. |
GET /api/games/season | None | Configured season/prize rules and separate on-chain escrow read. |
The first room signature belongs to the browser key. Its claimed wallet association is checked against the arena's registered seat key after entry; the room token alone is not proof the wallet owner signed it. Renewals stay inside the same session and arena binding.
The WebSocket room uses messages defined in packages/core/src/games/protocol.ts: versioned hello, queue.join, queue.leave, seed.reveal, resync, pick.pending, chat and reaction. It supplies snapshots, presence and chain-derived updates. Arena create/join/pick/claim remain contract actions.
Arcade
| Method and path | Request | Result or authority |
|---|---|---|
GET /api/games/arcade/board | game; optional address query | Current-engine top scores, personal best/rank and fresh seed. |
POST /api/games/arcade/score | game, token, seed, engineVersion, durationMs, score, calm, trace | Replays inputs and accepts only reproduced score/duration. |
Game is line-rider or candle-hop. Score posting needs x-masayume-device, a valid room token and a configured store. The response includes rank, personal-best status and current board. Scores are off-chain and do not prove human play.
Lucky
| Method and path | Request | Result or authority |
|---|---|---|
POST /api/games/lucky/commit | wallet, stakeBase | Persists server seed and returns draw id, commitment, nonce and policy. |
POST /api/games/lucky/reveal | drawId, clientSeed | Discloses deterministic draw plus candidate record and a current market opportunity; places nothing. |
POST /api/games/lucky/placed | drawId, status, optional txHash | Verifies a confirmed fill against the wallet's tape or records a refusal/unknown result. |
GET /api/games/lucky/history | Required address query | History with lazy reconciliation against actual fills and settlement. |
GET /api/games/lucky/board | None | Verified Lucky streak records. |
Commit uses the device header for rate gating. The supplied wallet at commit is not a wallet-signature login. Placement confirmation relies on actual fill evidence, and user trade confirmation still happens separately through the ordinary ticket lane.
Placement status is confirmed, nothingFilled, refused, reverted, unknown or declined. A confirmed report without a hash is rejected. A hash not yet found on the tape remains unknown instead of becoming a fabricated fill.
Integration discipline
Use the shared protocol/schema and signature-message builders from the application source. These endpoints have no common bearer-key scheme, no published external API version and no uniform retry contract. Preserve the route-specific unknown state, and never automatically replay an action capable of spending funds merely because a request timed out.
Source notes
This guide follows the application code reviewed on 2026-09-07. Links point to that reviewed commit and require repository access. GitHub may show 404 if you are signed out or do not have access.
- packages/core/src/faucet/index.ts
- web/src/features/funding/faucet-service.server.ts
- web/src/app/api
- web/src/features/strategies/protocol.ts
- web/src/features/sensei/protocol.ts
- web/src/features/x/protocol.ts
- web/src/features/room/protocol.ts
- web/src/features/takes/protocol.ts
- packages/core/src/private/protocol.ts
- packages/core/src/games/protocol.ts