# SEARICHING SDK Agent Index Use this file when implementing SEARICHING SDK features with Codex, Claude, or another coding agent. Primary docs: - docs/sdk/README.md - app/developers/page.tsx - app/developers/docs-data.ts - public/sdk/portal-sdk.d.ts - packages/sdk/README.md Public agent URLs: - https://seariching.com/developers#agents - https://seariching.com/agents/seariching-sdk.md - https://seariching.com/sdk/llms.txt Recommended agent workflow: - Send https://seariching.com/developers#agents to Codex or another coding agent first. - If the agent can install skills from a URL, install https://seariching.com/agents/seariching-sdk.md. - If the agent only supports fetching context, fetch https://seariching.com/sdk/llms.txt and then the public type definitions at https://seariching.com/sdk/portal-sdk.d.ts. - OpenAPI is not the primary contract for uploaded games because the Portal SDK uses browser postMessage, not direct HTTP calls. - MCP can be added later for authenticated upload/update automation, but game code should still integrate through the Portal SDK. Source of truth: - Browser SDK source: sdk/portal/browser-sdk.ts - Browser SDK public types: sdk/portal/browser-sdk.d.ts - Browser SDK generated assets: public/sdk/portal-sdk.v1.js, public/sdk/portal-sdk.d.ts - Portal protocol: sdk/portal/protocol.ts - Portal broker: sdk/portal/broker.ts - Package public Portal types: sdk/portal/index.ts - Leaderboard SDK: sdk/index.ts, sdk/client.ts, sdk/types.ts - Cloud Saves SDK: sdk/saves/index.ts - Audit Logs SDK: sdk/audit-logs/index.ts - Stats SDK: sdk/stats/index.ts - Admin Debug SDK: sdk/admin-debug/index.ts - Achievements SDK: sdk/achievements/index.ts - Analytics SDK: sdk/analytics/index.ts - Chat SDK: sdk/chat/index.ts - Cloud Code SDK: sdk/cloud-code/index.ts - Content Delivery SDK: sdk/content-delivery/index.ts - Economy SDK: sdk/economy/index.ts - Entitlements SDK: sdk/entitlements/index.ts - Game Overrides SDK: sdk/game-overrides/index.ts - Guilds SDK: sdk/guilds/index.ts - Matchmaking SDK: sdk/matchmaking/index.ts - Player Data SDK: sdk/player-data/index.ts - Player Names SDK: sdk/player-names/index.ts - Remote Config SDK: sdk/remote-config/index.ts - Server Hosting SDK: sdk/server-hosting/index.ts - Social SDK: sdk/social/index.ts - Realtime SDK: sdk/realtime/index.ts, sdk/realtime/types.ts - Webhooks SDK: sdk/webhooks/index.ts Use these public APIs inside uploaded games: - window.SeaGames.init() - sea.ready() - sea.getUser() - sea.listBoards() - sea.submitScore(board, value, metadata?) - sea.getLeaderboard(board, { limit }?) - sea.getMyRank(board) - sea.save(slot, data) - sea.load(slot) - sea.clearSave(slot) - sea.getProfile() - sea.updateProfile({ name?, avatarUrl? }) - sea.getProfileById(userId) - sea.submitMatchResult({ mode?, stats?, ranked? }) - sea.on("pause" | "resume", callback) Do not do these in uploaded games: - Do not import Supabase or Clerk. - Do not call app internals. - Do not write progression fields like xp, level, tr, rd, tier, rankPosition. - Use submitMatchResult for XP/ranked outcomes; the platform computes progression through one atomic service-role RPC, and idempotent retries return the stored result without double-awarding XP/TR. - Do not negate values for fastest-time boards. Use game.json mode order "asc". - Do not bypass the Portal broker. - Portal profile and cloud-save calls use mediated RPCs. Do not query profiles, public_profiles, or saves directly from game code. - Public arcade homepage data uses mediated RPCs. Do not query games, scores, leaderboard_rankings, or public_profiles directly for homepage cabinets or live-score UI. - Public arcade catalog data uses mediated RPCs. Use get_public_game for /play metadata and list_public_games for uploaded-game cabinets; do not query games directly from public UI for published game catalog metadata. - Creator game management uses owner-scoped RPCs. Use list_owner_games and set_owner_game_status for account dashboards; do not query or update games directly from account UI. - Private account profile fields use mediated RPCs. Use get_account_profile and set_account_profile for account email/display name/avatar_config; do not query or update profiles directly from account UI. - Outbound webhook dispatch uses service-role mediated RPCs. Use list_webhook_dispatch_targets and record_webhook_delivery from the Edge Function; do not query webhook_endpoints, webhook_deliveries, leaderboards, or games directly from webhook dispatch code. Use these npm exports outside game iframe code: - @seariching/sdk/portal for public Portal types and protocol constants. - @seariching/sdk/webhooks for trusted server webhook signing/verification. Outbound dispatch internals resolve targets and log attempts through service-role RPCs. - @seariching/sdk/admin-debug for owner dashboards, support tools, QA panels, and moderation consoles that need a cross-service player snapshot. - @seariching/sdk/audit-logs for trusted game-owner administrative audit event recording and filtered inspection. - @seariching/sdk/saves for trusted host Cloud Save v2 slots, mediated load/list reads, atomic versions, and conflict-detected save/delete mutations. - @seariching/sdk/stats for trusted host typed player stats, mediated reads, client write policies, and owner-authoritative writes. - @seariching/sdk/achievements for trusted host achievement definitions, mediated player reads, hidden owner definitions, progress/unlocks, and owner-authoritative awards. - @seariching/sdk/analytics for trusted host gameplay analytics, crash/error reports, and owner telemetry inspection. - @seariching/sdk/chat for trusted host text channels, RPC-mediated channel/message/member reads, direct-message block enforcement, player reports, and owner moderation actions. Do not query chat_channels, chat_channel_members, chat_messages, or moderation_reports directly from host tools. - @seariching/sdk/cloud-code for trusted host owner-registered HTTP scripts, owner-managed secrets, mediated script/invocation reads, queued invocations, and Worker-backed executeHttp calls. Do not query cloud_code_scripts, cloud_code_invocations, or cloud_code_secrets directly from host tools. - @seariching/sdk/content-delivery for trusted host upload/embed/asset URLs, game.json validation, and mediated versioned release metadata. Use listReleases() and getActiveRelease(); do not query game_releases or games directly from host tools. - @seariching/sdk/economy for trusted host wallets, inventory, mediated reads, idempotent mutations, and owner-authoritative mutations. - @seariching/sdk/entitlements for trusted host mediated definitions, ownership reads, durable unlocks, subscriptions, and owner-authoritative grants. - @seariching/sdk/game-overrides for trusted host scheduled overrides, mediated active reads, segments, percentage rollout bucketing, and owner publishing/deactivation. - @seariching/sdk/guilds for trusted host guild/clan creation, public discovery, member rosters, invites, open join, and role-gated invite authority through mediated RPCs. - @seariching/sdk/matchmaking for trusted host mediated public lobby listing, public/private lobbies, idempotent room creation, atomic capacity-checked joins, leaves, and host closes. - @seariching/sdk/player-data for trusted host mediated reads, small per-player key/value state, optimistic versions, and owner-authoritative access. - @seariching/sdk/player-names for trusted host mediated globally unique display names, public lookup, and availability checks. - @seariching/sdk/remote-config for trusted host live config, mediated active reads, segment overrides, and owner publishing/deactivation. - @seariching/sdk/server-hosting for trusted host mediated server build/fleet/session reads, queued authoritative sessions, and runner claim/ready/heartbeat/finish lifecycle. Do not query server_builds, server_fleets, or authoritative_sessions directly from host tools. - @seariching/sdk/social for trusted host friends, unfriend/remove, blocks, invites, and friend-visible presence through player-scoped RPCs. - @seariching/sdk/realtime for alpha realtime rooms, presence, and broadcasts. - @seariching/sdk/leaderboards only for platform-host integrations. Board listing, score submit, leaderboard pages, and my-rank reads use mediated RPCs; do not query games, leaderboards, scores, or leaderboard_rankings directly from host tools. Trusted host owner APIs: - Use createSeaAuditLogs({ supabase, gameSlug, getActorId }) to record append-only owner administrative events with record({ action, targetType, targetId, metadata }) and inspect them with list({ action, actorId, targetType, targetId, createdBefore, createdAfter, limit }). Listing uses a mediated owner RPC; do not query audit_logs directly from host tools. - Use createSeaAdminDebug({ supabase, gameSlug, getOwnerId }) to load owner-authorized player debug snapshots with getPlayerSnapshot(playerId). Snapshots include profile, presence, stats, achievements, wallets, inventory, entitlements, player data, save slot metadata, and moderation counts. Do not expose this SDK to uploaded game iframes. - Use createSeaAnalytics({ supabase, gameSlug, getUserId, getOwnerId }) to record gameplay analytics with track(...), record crash reports with reportError(...), list owner-visible analytics with listEvents({ name, playerId, sessionId, limit }), and list owner-visible crashes with listCrashReports({ name, playerId, sessionId, limit }). - Use createSeaStats({ supabase, gameSlug, getUserId, getOwnerId }) for typed counters and numeric progression fields. Players call listDefinitions(), get(key), list(), increment(key, by), and set(key, value) according to stat write policy. Owners call setForPlayer(playerId, key, value) and incrementForPlayer(playerId, key, by). Definition reads, player reads, player mutations, and owner mutations use mediated RPCs; do not query stat_definitions or player_stats directly from host tools. - Use createSeaAchievements({ supabase, gameSlug, getUserId, getOwnerId }) for visible/hidden achievements, milestone progress, direct unlocks, and owner awards. Players call listDefinitions(), get(key), list(), progress(key, amount), and unlock(key) according to achievement write policy. Owners call listDefinitions({ includeHidden: true }), progressForPlayer(playerId, key, amount), and unlockForPlayer(playerId, key). Definition reads, player reads, player mutations, and owner awards use mediated RPCs; hidden definition listing is owner-gated. - Use createSeaEconomy({ supabase, gameSlug, getUserId, getOwnerId }) for currencies, wallets, inventory items, consumables, shops, quest rewards, and server-authoritative grants. Players call listCurrencies(), listItemDefinitions(), getBalance(currencyKey), listBalances(), getItem(itemKey), listInventory(), grantCurrency(...), spendCurrency(...), grantItem(...), and consumeItem(...). Owners call grantCurrencyForPlayer(), spendCurrencyForPlayer(), grantItemForPlayer(), and consumeItemForPlayer(). Definition reads, player wallet reads, player inventory reads, player mutations, and owner mutations use mediated RPCs; mutations require idempotencyKey. - Use createSeaEntitlements({ supabase, gameSlug, getUserId, getOwnerId }) for durable unlocks, subscriptions, battle passes, cosmetics, DLC ownership, purchase-derived rights, and server-authoritative access checks. Players call listDefinitions(), get(key), has(key), list(), grant(key, { idempotencyKey }), and revoke(key, { idempotencyKey }). Owners call listForPlayer(playerId), getForPlayer(playerId, key), hasForPlayer(playerId, key), grantForPlayer(playerId, key, { idempotencyKey }), and revokeForPlayer(playerId, key, { idempotencyKey }). Definition reads, player ownership reads, player mutations, and owner mutations use mediated RPCs; mutations require idempotencyKey. - Use createSeaCloudSaves({ supabase, gameSlug, getUserId }) for full save slots such as campaign state, character progress, inventory snapshots, and device-to-device resume. Players call list(), load(slot), save(slot, data, { expectedVersion }), and delete(slot, { expectedVersion }). Load, list, save, and delete use mediated RPCs; do not query the saves table directly from host tools. Uploaded game iframes should normally use Portal SDK sea.save(), sea.load(), and sea.clearSave(). - Use createSeaPlayerData({ supabase, gameSlug, getUserId, getOwnerId }) for small per-player key/value state such as loadouts, quest flags, tutorial progress, preferences, and non-slot gameplay flags. Players call get(key), list(), set(key, value, { expectedVersion }), and delete(key, { expectedVersion }). Owners call getForPlayer(playerId, key), listForPlayer(playerId), setForPlayer(playerId, key, value, { expectedVersion }), and deleteForPlayer(playerId, key, { expectedVersion }). Player reads, player writes, owner reads, and owner writes use mediated RPCs. Use Cloud Saves for full save slots. - Use createSeaPlayerNames({ supabase, getUserId }) for globally unique display names shared by profiles, social, guilds, and moderation tools. Public callers use get(playerId) and isAvailable(displayName). Signed-in players use set(displayName). Lookup, availability, and updates use mediated RPCs; do not query player_names or public_player_names directly from host tools. - Use createSeaChat({ supabase, gameSlug, getUserId, getOwnerId }) for chat plus moderation. Players create/list channels, list messages/members, send messages, report players, and list their own reports through mediated RPCs. Owners list reports with listModerationReports({ status, reportedPlayerId, limit }), change queue status with updateModerationReportStatus(reportId, status), and hide abusive messages with deleteMessageAsOwner(messageId). Do not query chat tables directly. - Use createSeaSocial({ supabase, gameSlug, getUserId }) for social graph flows. Players call listFriends(), listFriendRequests(), sendFriendRequest(playerId), removeFriend(playerId), listBlocks(), blockPlayer(playerId), unblockPlayer(playerId), listInvites(), sendInvite(playerId, { kind, context, expiresAt }), invite response methods, updatePresence({ status, activity, metadata }), and getPresence(playerId). Reads use player-scoped RPCs; getPresence requires the signed-in viewer to be self or a friend of the target. - Use createSeaGuilds({ supabase, gameSlug, getUserId }) for guild/clan flows. Players call create(slug, name, { description, openJoin, maxMembers, metadata }), listGuilds(), getGuild(guildId), listMyGuilds(), listMembers(guildId), sendInvite(guildId, playerId), listInvites(), invite response methods, joinOpenGuild(guildId), and leaveGuild(guildId). Public discovery uses public read RPCs; rosters and invites use player-scoped RPCs. - Use createMatchmaking({ supabase, gameSlug }) for lobby lifecycle. Create rooms with createRoom({ name, maxPlayers, visibility, idempotencyKey }); private rooms are not public-listed but can be joined by code. Use listRooms() for mediated open public room listing, joinRoom(code) for capacity-checked joins, leaveRoom(code) for caller membership removal, and closeRoom(code) for host-authorized room closure. Listing and lifecycle operations use mediated RPCs; do not query rooms or room_members directly from host tools. - Use createSeaRemoteConfig({ supabase, gameSlug, getOwnerId }) for live config defaults and segment overrides. Read with get/list, publish immutable versions with publish(key, value, { segment, priority, active, startsAt, endsAt }), and deactivate versions with deactivate(key, { segment }). Active reads and owner mutations use mediated RPCs; do not query remote_config_entries directly from host tools. - Use createSeaGameOverrides({ supabase, gameSlug, getOwnerId, getRolloutId }) for scheduled overrides, segment targeting, priority/version resolution, and deterministic rollout buckets. Read with get/list, publish immutable versions with publish(key, value, { segment, rolloutPercentage, priority, active, startsAt, endsAt }), and deactivate versions with deactivate(key, { segment }). Active reads and owner mutations use mediated RPCs; do not query game_overrides directly from host tools. - Do not call owner APIs from uploaded game iframes. Use them from trusted dashboards, server jobs, launchers, or owner tooling with a Supabase client whose signed-in subject matches getOwnerId(). Required verification after SDK changes: - npx tsc --noEmit - npm run lint - npm test - npm run sdk:portal:check - npm run sdk:skill:check - npm run sdk:pack - npm run build