rtClient.apps
SDK methods for apps - the registry, signup posture, access checks, and per-app discovery reads.
An App is a registered client of the protocol - grammata, Bottle Drop, your app. The
registry is what powers the cross-app rail, and two of these reads gate real UX: getConfig
answers "does signup here require an invite", and getAccess answers "may the current user
enter". Most client apps call both on load through the shared providers without touching
this service directly.
rtClient.apps.getConfig(appId)
The app's signup posture: requireInviteForSignup, byowEnabled, and the app's
declared create fee. Public - any valid app key - and safe to call on load. This is the
single source of truth the invite gate reads; do not cache your own copy of it.
const { data: config } = await rtClient.apps.getConfig(APP_ID);
if (config.requireInviteForSignup) showInviteStep();rtClient.apps.getAccess(appId)
The entry-guard read: PUBLIC apps are always enterable; GRANTED apps answer from the
current user's access grant. Returns ApiResponse<AppAccessCheck>. Render-side only -
every action is independently enforced server-side.
rtClient.apps.listApps(params?) / listPublicApps(contentType?)
List registered apps. listApps accepts publicOnly, activeOnly, contentType;
listPublicApps is the convenience form with the first two set. Returns
ApiResponse<App[]>.
rtClient.apps.getAppTrending(appId, params?) / getRandom(appId, params?)
Per-app discovery reads: the trending products within one app, and a random sample for a
browse shelf. Both paginate via their params types (AppTrendingQueryParams,
AppRandomQueryParams).
rtClient.apps.getStats(appId)
Per-app aggregate stats (AppStats), written by the analytics projector off the event
stream. An operator read - rt-admin renders it - rather than something a client app needs.
rtClient.apps.updateApp(id, patch)
Operator write for registry rows (name, URLs, policy fields like acceptedCurrencies).
Admin-gated server-side; client apps have no reason to call it.