Canonical portfolio-first tRPC surface for CLI and agent integrations
v2 tRPC namespace is the canonical API surface for agent and CLI consumers.
POST /v1/trpcv2.*v2.portfolio.create.* and v2.portfolio.permission.refresh.*v2.portfolio.scheduledFunctions.*v2.portfolio.* and v2.operations.*x-glider-owner-address is optional and must match canonical owner when provided.v2.public.* non-owner read surfacesv2.portfolio.*
list, get, statusvaults.listperformance.get, performance.seriesactivity.listrecipients.listdeposit.instructionscreate.prepare, create.confirmpermission.status, permission.refresh.prepare, permission.refresh.confirmarchive, unarchiveactions.submitpolicy.evaluate, policy.scheduleAdvisoryschedule.get, schedule.create, schedule.update, schedule.setFromText, schedule.pause, schedule.archive, schedule.resume, schedule.runNowscheduledFunctions.list, scheduledFunctions.create, scheduledFunctions.delete (beta/private rollout; not exposed in the webapp by default)v2.operations.*
get, list, streamv2.agentAuth.*
createApiKeyv2.public.*
portfolio.list, portfolio.getportfolio.vaults.listportfolio.schedule.getaccount.profile.getaccount.assets.listaccount.performance.seriesaccount.performance.overviewv2.portfolio.actions.submit also includes additive operation guidance:
nextSteps.poll -> v2.operations.getnextSteps.stream -> v2.operations.streamnextRecommendedCommands with ready-to-copy polling/stream commandssessionKeys.getPortfolioSignableMessage -> v2.portfolio.create.preparesessionKeys.createPortfolioWithSignature -> v2.portfolio.create.confirmsessionKeys.refreshSessionKeyMessage* -> v2.portfolio.permission.refresh.preparesessionKeys.refreshSessionKeyWithSignature -> v2.portfolio.permission.refresh.confirmstrategyInstances.getStrategyInstancesOwnedByAddress -> v2.portfolio.liststrategyInstances.getStrategyInstance -> v2.portfolio.getstrategyInstances.archiveStrategyInstance -> v2.portfolio.archivestrategyInstances.unarchiveStrategyInstance -> v2.portfolio.unarchivestrategyInstances.getUnifiedPortfolioHistory -> v2.portfolio.activity.list (kind="history")strategyInstances.getStrategyPerformanceMultipleTimeframes -> v2.portfolio.performance.get (timeframes)strategyInstances.getNetDepositsAndWithdrawals -> v2.portfolio.performance.get (netFlows)strategyInstances.getStrategyPerformanceSeries -> v2.portfolio.performance.seriesstrategyInstances.getStrategyInstanceVaultsOwnedByAddress -> v2.portfolio.recipients.liststrategyInstances.getStrategyInstancesOwnedByAddress (public profile view) -> v2.public.portfolio.liststrategyInstances.getStrategyInstance (unowned read) -> v2.public.portfolio.getvaults.getVaultsPortfolioDataForStrategyInstance (unowned read) -> v2.public.portfolio.vaults.listschedules.getStrategyInstanceSchedule (unowned read) -> v2.public.portfolio.schedule.getv2.public.account.profile.getstrategyInstances.getAllAssetsAcrossWalletStrategies (public profile aggregate) -> v2.public.account.assets.liststrategyInstances.getAccountPerformanceOverview (public profile aggregate) -> v2.public.account.performance.overviewstrategyInstances.getAccountPerformanceSeries (public profile aggregate) -> v2.public.account.performance.seriesrebalance.execute -> v2.portfolio.actions.submit (kind="rebalance")withdrawAndDeposits.process* -> v2.portfolio.actions.submit (kind="withdraw")bridge.processBridgeRequest -> v2.portfolio.actions.submit (kind="bridge")executeLifiQuote.execute -> v2.portfolio.actions.submit (kind="swap")v2.portfolio.actions.submit (kind="swap_backend_quote")schedules.* -> v2.portfolio.schedule.*v2.portfolio.scheduledFunctions.*rebalance.getStatus / workflows.* / temporal.* / bridge.getBridgeStatus / executeLifiQuote.getStatus -> v2.operations.get / v2.operations.streamrebalance.execute and migrated schedules.* write mutations), and should be treated as v2.portfolio.*-only.v2.*.portfolioId), even when internal implementations still use strategy-instance identifiers.v2.operations.list has two modes:
operationIds mode: resolves all supported kinds by explicit ID.operationIds): currently limited to live rebalance source.kind values other than rebalance are rejected with explicit OPERATION_KIND_UNSUPPORTED_LIVE_LIST.v2.portfolio.status is resilient: permission/session data still returns if rebalance status source is unavailable; rebalance is null and degraded.rebalanceUnavailable=true.v2.portfolio.permission.status (session keys + evm agent only) for lighter polling.canonical_strategy_blueprint_id:
v2.portfolio.list returns it on each portfolio row.v2.portfolio.get and v2.public.portfolio.get return it on the nested blueprint object.v2.portfolio.schedule.get adds scheduleStatus (active | paused | disabled | archived | null).scheduleExists=false, scheduleId=null, scheduleData=null) while still reporting scheduleStatus="archived".v2.portfolio.schedule.create, v2.portfolio.schedule.update, and v2.portfolio.schedule.setFromText return SCHEDULE_ARCHIVED and do not reactivate automation.v2.portfolio.schedule.runNow includes additive operation identifiers: accepted, runId, and operationId.v2.portfolio.scheduledFunctions.* is currently in beta/private rollout and is hidden in the webapp unless the recurring-swaps UI feature flag is enabled for the user.v2.portfolio.scheduledFunctions.create supports additive
schedule input for functionKey="recurring_swap":
hourly, or { frequency: "daily" | "weekly", hourUtc, day? }.intervalMs/startAt/endAt.hourUtc and weekly day are interpreted in UTC; local DST shifts are not preserved.v2.portfolio.policy.evaluate is the canonical machine-facing evaluator for rebalance, schedule, swap, and withdraw.v2.portfolio.policy.scheduleAdvisory is a convenience wrapper over the same schedule evaluation path.swap and withdraw policy evaluation uses chainIds to derive request exposure. Raw requestExposure remains accepted temporarily for wire compatibility, but is ignored.rebalance, schedule, and scheduleAdvisory still accept legacy currentExposure / plannedExposure fields for compatibility, but those fields are ignored immediately.withdraw policy evaluation also ignores legacy raw portfolioTotalUsd and isFullWithdraw inputs; the backend derives those facts authoritatively when available.status, allowed, primaryBlockingReason, reasons, remainingConditions, and nextEligibleAt, and now also include:
authoritativefactsruleResultsprimaryBlockingReason and each entry in reasons[] now also include:
policyIdcategorypolicySetId when the reason came from a chain-scoped policy setruleResults[] now includes:
reasonCodespolicyIdsreasonCode remains as the first/primary code for backward compatibility.facts[].status distinguishes present, missing, stale, and synthetic.facts[].origin distinguishes backend-loaded facts (server), backend-derived request facts (derived), and caller-supplied fallback/hypothetical facts (client).authoritative=true only means the triggered policy rules had sufficient trusted backend facts; missing, stale, synthetic-only, or client-sourced required facts downgrade the decision to non-authoritative.fallbackPrimaryChainId is treated as a compatibility hint rather than the source of truth.remainingConditions[] may include market_available for Ondo-backed rebalance and swap decisions, carrying the blocked asset IDs, symbols, availability type (closed or halted), and nextOpenAt when Ondo provides a reopen time.schedule input on the schedule policy endpoints returns the backend default cadence instead of a denial.primary_chain_id = "1":
REBALANCE_ETH_MAINNET_COOLDOWN_ACTIVE>= 24h,24h.SCHEDULE_ETH_MAINNET_INTERVAL_TOO_SHORT, SCHEDULE_ETH_MAINNET_INTERVAL_ONLY$10,$10, only full-balance withdraw is allowed.WITHDRAW_ETH_MAINNET_BELOW_MINIMUM, WITHDRAW_ETH_MAINNET_FULL_REQUIRED_UNDER_MINIMUMkind="swap" and kind="swap_backend_quote"):
$10,LIFI_ETH_MAINNET_BELOW_MINIMUM_TRADEv2.portfolio.scheduledFunctions.* is currently allowlisted to functionKey="recurring_swap" only.recurring_swap is intentionally narrow: buy a token with USDC or sell a token to USDC.v2.public.portfolio.list, v2.public.portfolio.get, v2.public.portfolio.vaults.list, v2.public.portfolio.schedule.get, v2.public.portfolio.performance.*, and v2.public.portfolio.activity.list do not currently enforce is_public.
PORTFOLIO_NOT_FOUND when the portfolio does not exist.v2.public.account.profile.get is the canonical user-profile hydration endpoint used by /user/:userId.
is_public.v2.public.account.assets.list, v2.public.account.performance.series, and v2.public.account.performance.overview are owner-scoped aggregates with no per-portfolio visibility check.v2.agentAuth.createApiKey keeps ownerAddress optional for compatibility.ownerAddress is provided, it must match the authenticated wallet address.v2.* in owner-authenticated flows:
v2.portfolio.actions.submitv2.portfolio.actions.submitv2.portfolio.actions.submit (kind="swap")v2.portfolio.actions.submit (kind="swap_backend_quote")v2.portfolio.activity.listv2.portfolio.statusv2.operations.get in migrated withdraw/transfer/swap pathsv2.public.* in non-owner/public flows:
v2.public.account.profile.getETH/USDC) is unsupported and rejected client-side (legacy backend path is also unsupported)strategyInstances.*schedules.getSchedulesForMultipleStrategies (no v2 equivalent yet)