# Sandbox data models

Field definitions for requests and responses. Nullable fields can contain null; optional fields may be absent.

## Advisor



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"advisor"` | No |   |
| `as_of` | `string` | No |  format: `date-time` |
| `headline` | `string` | No |   |
| `regime` | `string` | No |   |
| `bullets` | `string`[] | No |   |
| `top_opportunities` | `object`[] | No |   |
| `portfolio` | `object` | No |   |
| `disclaimer` | `string` | No |   |


## ApiKey



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"api_key"` | Yes |   |
| `label` | `string` | Yes |   |
| `secret` | `string` | No | Full secret only on create; masked (tsk_test_...a1b2) on list  |
| `prefix` | `string` | No | First 12 chars of the secret  |
| `environment` | `"test"`, `"live"` | Yes |   |
| `created_at` | `string` | Yes |  format: `date-time` |
| `last_used_at` | `['string', 'null']` | No |  format: `date-time` |
| `revoked` | `boolean` | Yes |   |
| `scopes` | `string`[] | Yes |   |


## Balance



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"balance"` | No |   |
| `user_id` | `['string', 'null']` | No |   |
| `asset` | `"USDC"`, `"USDT"` | No |   |
| `principal` | `number` | No |   |
| `current_value` | `number` | No |   |
| `accrued_yield` | `number` | No |   |
| `positions` | `integer` | No |   |


## BalanceSnapshot



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"balance_snapshot"` | No |   |
| `date` | `string` | No |   |
| `t` | `integer` | No | Epoch ms  |
| `principal` | `number` | No |   |
| `value` | `number` | No |   |
| `accrued` | `number` | No |   |
| `positions` | `integer` | No |   |
| `users` | `integer` | No |   |
| `by_asset` | `object`[] | No |   |


## CreateKeyRequest



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | `string` | No | Human label for the key  |
| `environment` | `"test"`, `"live"` | No |  default: `test` |


## CreatePositionRequest



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `wallet` | `string` | Yes |   |
| `asset` | `"USDC"`, `"USDT"` | Yes |   |
| `amount` | `number` | Yes |   |
| `strategy` | `string` | No | "auto" or a target vault id default: `auto` |
| `user` | `string` | No | Optional user id (usr_...) or external_id to associate  |


## CreateUserRequest



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `external_id` | `string` | Yes | Your customer id (unique)  |
| `label` | `['string', 'null']` | No |   |
| `email` | `['string', 'null']` | No |  format: `email` |
| `metadata` | `object` | No |   |
| `wallets` | `string`[] | No |   |


## CreateWebhookRequest



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | `string` | Yes |  format: `uri` |
| `events` | `"*"`, `"position.opened"`, `"position.active"`, `"position.rebalanced"`, `"position.withdrawn"`, `"position.closed"`, `"yield.threshold"`, `"system.status"`[] | No | Defaults to ["*"]  |
| `active` | `boolean` | No |  default: `True` |


## Decision



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"decision"` | No |   |
| `id` | `string` | No |   |
| `at` | `string` | No |  format: `date-time` |
| `position_id` | `string` | No |   |
| `user_id` | `['string', 'null']` | No |   |
| `asset` | `string` | No |   |
| `type` | `"initial_routing"`, `"rebalance"` | No |   |
| `from_vault` | `['string', 'null']` | No |   |
| `to_vault` | `string` | No |   |
| `apy_before` | `['number', 'null']` | No |   |
| `apy_after` | `number` | No |   |
| `expected_uplift_bps` | `['number', 'null']` | No |   |
| `reason` | `string` | No |   |
| `alternatives` | `object`[] | No |   |
| `rationale` | `string` | No |   |
| `status` | `string` | No |   |


## DeletedWebhook



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `string` | Yes |   |
| `deleted` | `boolean` | Yes |   |


## Delivery



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"delivery"` | Yes |   |
| `webhook_id` | `string` | No |   |
| `url` | `string` | No | Target endpoint URL  |
| `event` | `"position.opened"`, `"position.active"`, `"position.rebalanced"`, `"position.withdrawn"`, `"position.closed"`, `"yield.threshold"`, `"system.status"` | Yes |   |
| `payload` | `object` | No | The signed event payload { id, type, created_at, data }  |
| `signature` | `string` | No | t=<unix>,v1=<hmac_sha256(secret, t + "." + body)>  |
| `status` | `"delivered"`, `"failed"` | Yes |   |
| `attempts` | `integer` | No |   |
| `at` | `string` | Yes |  format: `date-time` |
| `latency_ms` | `integer` | No |   |


## ErrorEnvelope



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `object` | Yes |   |


## LedgerEntry



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"ledger_entry"` | Yes |   |
| `at` | `string` | Yes |  format: `date-time` |
| `user_id` | `['string', 'null']` | No |   |
| `position_id` | `string` | Yes |   |
| `wallet` | `string` | No |   |
| `asset` | `"USDC"`, `"USDT"` | Yes |   |
| `type` | `"deposit"`, `"withdraw"`, `"close"`, `"accrual"` | Yes |   |
| `amount` | `number` | Yes | Signed delta  |
| `balance_after` | `number` | Yes | Running balance for the position  |
| `vault_id` | `string` | No |   |
| `settled` | `boolean` | Yes |   |
| `ref` | `string` | No |   |


## ListMeta



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `total` | `integer` | Yes | Total items matching the filter  |
| `limit` | `integer` | No | Page size applied  |
| `next_cursor` | `['string', 'null']` | No | Opaque cursor for the next page, or null when exhausted  |


## Position



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"position"` | Yes |   |
| `user_id` | `['string', 'null']` | No | Owning end-user, if associated  |
| `wallet` | `string` | Yes |   |
| `asset` | `"USDC"`, `"USDT"` | Yes |   |
| `chain` | `"base"`, `"arbitrum"` | Yes |   |
| `vault_id` | `string` | Yes |   |
| `strategy` | `string` | No |   |
| `principal` | `number` | Yes |   |
| `current_value` | `number` | Yes | principal * (1 + apy * elapsedYears)  |
| `accrued_yield` | `number` | Yes |   |
| `apy` | `number` | Yes |   |
| `status` | `"active"`, `"closed"` | Yes |   |
| `opened_at` | `string` | No |  format: `date-time` |
| `updated_at` | `string` | No |  format: `date-time` |
| `last_rebalance_at` | `['string', 'null']` | No |  format: `date-time` |
| `tx_hash` | `string` | No |   |


## PositionEvent



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"position_event"` | No |   |
| `position_id` | `string` | No |   |
| `type` | `"deposit"`, `"rebalance"`, `"accrual"`, `"withdraw"`, `"close"` | Yes |   |
| `at` | `string` | Yes |  format: `date-time` |
| `amount` | `number` | No |   |
| `apy` | `number` | No |   |
| `vault_id` | `string` | No |   |
| `note` | `string` | No |   |


## Rebalance



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"rebalance"` | Yes |   |
| `position_id` | `string` | Yes |   |
| `from_vault` | `string` | Yes |   |
| `to_vault` | `string` | Yes |   |
| `amount` | `number` | No |   |
| `reason` | `"yield_optimization"`, `"risk_adjustment"`, `"capacity_rebalance"` | No |   |
| `apy_before` | `number` | No |   |
| `apy_after` | `number` | No |   |
| `at` | `string` | Yes |  format: `date-time` |
| `tx_hash` | `string` | No |   |


## Reconciliation



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"reconciliation"` | Yes |   |
| `as_of` | `string` | Yes |  format: `date-time` |
| `scope` | `string` | Yes |   |
| `recorded_total` | `number` | Yes |   |
| `onchain_total` | `number` | Yes |   |
| `discrepancy` | `number` | Yes |   |
| `unsettled_yield` | `number` | No |   |
| `tolerance` | `number` | No |   |
| `status` | `"reconciled"`, `"mismatch"` | Yes |   |
| `positions` | `integer` | No |   |
| `breakdown` | `object`[] | No |   |


## Regime



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"regime"` | No |   |
| `as_of` | `string` | No |  format: `date-time` |
| `regime` | `"rising"`, `"falling"`, `"stable"`, `"volatile"` | No |   |
| `description` | `string` | No |   |
| `per_asset` | `object`[] | No |   |


## RevokedKey



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `string` | Yes |   |
| `revoked` | `boolean` | Yes |   |


## Signal

Per-vault risk-adjusted signal. APY fields are decimal fractions.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"signal"` | No |   |
| `vault_id` | `string` | No |   |
| `name` | `string` | No |   |
| `provider` | `string` | No |   |
| `asset` | `"USDC"`, `"USDT"` | No |   |
| `chain` | `string` | No |   |
| `risk_tier` | `"bluechip"`, `"core"`, `"opportunistic"` | No |   |
| `apy` | `number` | No |   |
| `volatility` | `number` | No |   |
| `trend_slope_bps_day` | `number` | No |   |
| `forecast_apy` | `number` | No | Naive 7-day trend forecast (decimal fraction)  |
| `risk_factor` | `number` | No |   |
| `risk_adjusted_apy` | `number` | No |   |
| `rank` | `integer` | No |   |
| `recommendation` | `"overweight"`, `"neutral"`, `"underweight"` | No |   |


## Status



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"status"` | Yes |   |
| `overall` | `"operational"`, `"degraded"`, `"outage"` | Yes |   |
| `components` | [StatusComponent](/api/sandbox-models/#statuscomponent)[] | Yes |   |
| `incidents` | `object`[] | Yes |   |
| `uptime_s` | `integer` | No |   |
| `updated_at` | `string` | Yes |  format: `date-time` |


## StatusComponent



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | No |   |
| `name` | `string` | No |   |
| `status` | `"operational"`, `"degraded"`, `"outage"` | No |   |
| `uptime_90d` | `number` | No |   |
| `latency_ms` | `integer` | No |   |


## UpdateUserRequest



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | `['string', 'null']` | No |   |
| `email` | `['string', 'null']` | No |  format: `email` |
| `metadata` | `object` | No |   |
| `wallets` | `string`[] | No |   |
| `status` | `"active"`, `"disabled"` | No |   |


## UpliftReport



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"uplift"` | No |   |
| `as_of` | `string` | No |  format: `date-time` |
| `scope` | `string` | No |   |
| `totals` | `object` | No |   |
| `positions` | [UpliftRow](/api/sandbox-models/#upliftrow)[] | No |   |


## UpliftRow



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"uplift_row"` | No |   |
| `position_id` | `string` | No |   |
| `user_id` | `['string', 'null']` | No |   |
| `asset` | `string` | No |   |
| `vault_id` | `string` | No |   |
| `principal` | `number` | No |   |
| `current_value` | `number` | No |   |
| `apy` | `number` | No |   |
| `aave_baseline` | `number` | No |   |
| `baseline_apy` | `number` | No |   |
| `hold_baseline` | `number` | No |   |
| `uplift_vs_aave` | `number` | No |   |
| `uplift_vs_hold` | `number` | No |   |


## Usage



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"usage"` | Yes |   |
| `range` | `"24h"`, `"7d"`, `"30d"` | Yes |   |
| `totals` | [UsageTotals](/api/sandbox-models/#usagetotals) | Yes |   |
| `series` | [UsagePoint](/api/sandbox-models/#usagepoint)[] | Yes |   |


## UsagePoint



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `t` | `integer` | No | Epoch ms bucket start  |
| `requests` | `integer` | No |   |
| `errors` | `integer` | No |   |
| `p50_ms` | `integer` | No |   |
| `p99_ms` | `integer` | No |   |


## UsageTotals



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `requests` | `integer` | No |   |
| `errors` | `integer` | No |   |
| `p50_ms` | `integer` | No |   |
| `p99_ms` | `integer` | No |   |
| `unique_keys` | `integer` | No |   |


## User



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"user"` | Yes |   |
| `external_id` | `string` | Yes |   |
| `label` | `['string', 'null']` | No |   |
| `email` | `['string', 'null']` | No |   |
| `metadata` | `object` | No |   |
| `wallets` | `string`[] | Yes |   |
| `status` | `"active"`, `"disabled"` | Yes |   |
| `created_at` | `string` | Yes |  format: `date-time` |
| `updated_at` | `string` | No |  format: `date-time` |


## Vault



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"vault"` | Yes |   |
| `name` | `string` | Yes |   |
| `provider` | `"aave"`, `"morpho"`, `"compound"`, `"dolomite"`, `"treasury"` | Yes |   |
| `asset` | `"USDC"`, `"USDT"` | Yes |   |
| `chain` | `"base"`, `"arbitrum"` | Yes |   |
| `apy` | `number` | Yes | Decimal fraction (0.052 = 5.2%)  |
| `apy_7d_avg` | `number` | No |   |
| `apy_30d_avg` | `number` | No |   |
| `tvl_usd` | `number` | No |   |
| `capacity_usd` | `number` | No |   |
| `risk_tier` | `"bluechip"`, `"core"`, `"opportunistic"` | Yes |   |
| `status` | `"active"`, `"paused"` | Yes |   |
| `inception_date` | `string` | No |  format: `date` |
| `description` | `string` | No |   |
| `allocation_pct` | `number` | No |   |


## Webhook



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |   |
| `object` | `"webhook"` | Yes |   |
| `url` | `string` | Yes |  format: `uri` |
| `events` | `string`[] | Yes |   |
| `secret` | `string` | Yes | whsec_... used to compute Webhook-Signature  |
| `active` | `boolean` | Yes |   |
| `created_at` | `string` | Yes |  format: `date-time` |


## WithdrawRequest

Provide a positive amount for a partial withdrawal, or { "all": true } to close.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | `number` | No |   |
| `all` | `boolean` | No |   |


## Yield



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"yield"` | Yes |   |
| `asset` | `string` | Yes |   |
| `best_apy` | `number` | Yes |   |
| `blend_apy` | `number` | Yes | Allocation-weighted blended APY  |
| `blended_30d` | `number` | No |   |
| `breakdown` | [YieldBreakdown](/api/sandbox-models/#yieldbreakdown)[] | No |   |
| `history` | [YieldHistoryPoint](/api/sandbox-models/#yieldhistorypoint)[] | No |   |


## YieldBreakdown



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `vault_id` | `string` | No |   |
| `name` | `string` | No |   |
| `provider` | `string` | No |   |
| `apy` | `number` | No |   |
| `allocation` | `number` | No |   |


## YieldHistoryPoint



| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `t` | `integer` | No | Epoch ms  |
| `apy` | `number` | No |   |

