---
name: tickerspring
description: "Use TickerSpring on Robinhood Chain (chain id 4663, USDG): find the best strategy for a budget, deposit into or withdraw from its vaults (merged, Up and Stock Token vaults), place or cancel limit orders and ladders, run grid strategies and ladder strategies, swap tokens through KyberSwap, buy or sell baskets, backtest strategies, and check positions or what changed. Triggers: \"TickerSpring\", \"find me a strategy for $500\", \"deposit USDG into a vault\", \"withdraw from my vault\", \"limit order on Robinhood Chain\", \"ladder of buy orders\", \"grid strategy\", \"ladder strategy\", \"swap 200 USDG for NVDA\", \"buy the tsAI basket\", \"what changed in my positions\". Prepares unsigned transactions only; the user signs."
---

# TickerSpring

## 1. What TickerSpring is

TickerSpring runs on Robinhood Chain (chain id 4663, hex `0x1237`). Amounts are in USDG, a dollar stablecoin with 6 decimals; vault shares have 12 (Stock Token vault shares 18), basket tokens 18. Agents can use six products:
- **Vaults:** each holds one liquidity position in a token/USDG pool and harvests its trading fees (and rewards). Three families: merged vaults (deposits are requests the keeper fills; withdrawals pay USDG, pay in kind, or wait in a queue), Up vaults (requests in the vault's queues the keeper settles) and Stock Token vaults (deposits and withdrawals in one transaction through the vault's router). Each runs a pinned, reviewed release; `audited` marks the audited one.
- **Limit orders and ladders:** orders on TickerSpring's Uniswap v4 limit-order hook; a ladder is 2 to 20 orders at different prices.
- **Grid strategies:** a repeating buy line and sell line on the strategy contract.
- **Ladder strategies:** 1 to 16 parts on one token, each its own buy and sell line, opened together after one approval (offered only while `get_products` lists them).
- **Swaps:** any token for any token through KyberSwap, on TickerSpring's own swap router (the site's swap page), paid to the signing wallet.
- **Baskets:** Balancer V3 weighted pools on TickerSpring's own deployment, several tokens at set weights held as one basket token; holders earn the basket's swap fee. Bought and sold in one transaction through BasketZap (the basket page's buttons), which trades each token through KyberSwap.

## 2. How to connect

- **MCP (recommended):** add both servers to your client (Streamable HTTP, no login):
  - Data (read-only): https://mcp.tickerspring.com/mcp/data
  - Actions (prepares unsigned transactions): https://mcp.tickerspring.com/mcp/actions
  - Claude Code: `claude mcp add --scope user --transport http tickerspring-data https://mcp.tickerspring.com/mcp/data`, and the same for `tickerspring-actions` (`--scope user` makes them work from any folder).
- **HTTP API**, at https://api.tickerspring.com: [openapi.json](https://api.tickerspring.com/v1/agent/openapi.json) lists every route; [llms.txt](https://api.tickerspring.com/v1/agent/llms.txt) is a short summary. Successes answer `{"data": ...}`, errors `{"error", "code"}`.

## 3. Decision guide

Find what the user wants, then call the tools in this order. MCP tool names come first, with the HTTP route in brackets.

- **What can I use?** `get_products` (GET /v1/agent/products).
- **Find a strategy for a budget ("find me a strategy for $500"):** `find_strategy` (GET /v1/strategy-finder) returns the best 3 for the budget (strategies and vaults), ranked by how they would have done over the last 7 days (pass `days`, 1 to 30, to switch: two weeks is 14), each with the 2-, 7-, 14- and 30-day windows and the one asked for, what just holding the token did over the same days (`holdReturnPct`), a test on unseen days, the exact run parameters, the shape and next steps. Lead with these options ("over the last 7 days it made …, holding the token alone …"); let the user pick; confirm (below); then prepare it with the existing tools. For the best vault over a stretch of days, pass `strategy` vault: it lists the vaults themselves. If it widened (other tokens, other styles, the best vault, or a shorter window), say so and offer that next step. `backtest_strategy` (POST /v1/strategy-finder/backtest) tests another token or setting on demand.
- **Which token?** `list_tokens` (GET /v1/tokens): every token TickerSpring charts (stocks, utility tokens, memes and others), busiest first, with its price, volume and whether its limit-order and grid markets are open. Limit orders, ladders and grids work with any of them, by address: the first order or grid on a token opens its market (when a prepare asks for `startingPrice`, the token's `priceUsd` is a good one to confirm with the user). A token that isn't `verified` names itself, so always give its full address and say it is unverified.
- **Put USDG in a vault:** `list_vaults` (GET /v1/agent/vaults) lists every vault agents can use, each with its `family` (merged, up or stock-token), `status` (open, full, closed or paused) and `statusReason`; full and closed vaults are listed too. Take only an `open` one, check its minimum and room (`get_vault`, GET /v1/agent/vaults/{vault}), confirm (below), then `prepare_vault_deposit` (POST /v1/agent/prepare/vault-deposit). Merged vaults: the keeper fills the request, usually within seconds. Up vaults: the request waits in the vault's deposit queue until the keeper's next settlement. Stock Token vaults: one transaction through the vault's router, which buys the stock part through KyberSwap; sign within a few minutes.
- **Cancel a deposit that hasn't filled or settled:** `get_positions` (GET /v1/agent/accounts/{owner}) for the request id, then `prepare_vault_cancel_deposit` (POST /v1/agent/prepare/vault-cancel-deposit).
- **Withdraw:** `get_positions` for the shares, then `prepare_vault_withdraw` (POST /v1/agent/prepare/vault-withdraw) with one of the vault's `withdrawModes` and shares, a USDG amount or all. Merged: `usdg` (paid in USDG through a KyberSwap route), `in-kind` (USDG plus the pool token) or `queue` (only vaults with a `redeemQueue`, when the vault refuses a direct withdrawal for a while; `get_vault` shows `withdrawReadyAt`). Up: `queue` (USDG, paid when the keeper settles it; 10 USDG minimum, and a part withdrawal may not leave less behind) or `in-kind` with all (only for a whole position under that minimum). Stock Token: `usdg` (the stock part sold through KyberSwap in the same transaction) or `in-kind`.
- **Cancel a queued withdrawal:** `get_positions`, then `prepare_vault_cancel_withdraw` (POST /v1/agent/prepare/vault-cancel-withdraw) with the vault (an Up vault) or the merged vault's `redeemQueue`.
- **Buy or sell at a price:** `get_price_history` (GET /v1/candles) or `get_quote` (GET /v1/trade/quotes) for context, then `prepare_limit_order` (POST /v1/agent/prepare/limit-order). Several prices on one side: `prepare_ladder` (POST /v1/agent/prepare/ladder), 2 to 20 orders.
- **Cancel or claim an order:** `get_positions` for the order id, then `prepare_order_action` (POST /v1/agent/prepare/order-action).
- **Dip ladders:** `find_ladder_strategies` (GET /v1/agent/ladder/tokens) lists the scanned tokens where the dip ladder (5 buys 10% apart, each selling at +50% after fees, repeating) has worked, with each token's record ($500 started at any midnight in the last 30 days, held a week), today's lines and warnings (collapsing, drying up, thin). `get_ladder_strategy` (GET /v1/agent/ladder/plan) plans one token's ladder at the user's amount with the exact prepares (`prepare_grid` once per part; `prepare_ladder_strategy` while ladders are listed for the token).
- **Run a grid:** `find_grid_strategies` (GET /v1/agent/grid/tokens) lists tokens that keep trading a range (good, then weak with their reasons; pumping, sliding, thin or new tokens are left out). `get_grid_strategy` (GET /v1/agent/grid/plan) plans one token's lines now from a walk-forward (each past week set only from the weeks before it), with a tighter and a wider choice and the average and worst week; pass `gapPct` for lines further apart or closer. `backtest_grid` (POST /v1/agent/backtest/grid) tests lines the user picks; `best_ranges` (GET /v1/agent/ranges) shows the lines that would have done best in hindsight. Then `prepare_grid` (POST /v1/agent/prepare/grid) with action `open` (`openWithMarket` when the token's market isn't set up yet). Later: `close`, `setRepeat` or `collect`. `backtest_ladder` (POST /v1/agent/backtest/ladder) replays a ladder.
- **Swap one token for another ("swap 200 USDG for NVDA"):** `get_swap_quote` (GET /v1/agent/swap/quote) with the tokens as symbols from TickerSpring's list or addresses and the amount in the input token's units: it answers both tokens' addresses, the expected and minimum output and the fee. Confirm (below), then `prepare_swap` (POST /v1/agent/prepare/swap) with the same inputs. `get_quote` (GET /v1/trade/quotes) compares other aggregators for context only; swaps always route through KyberSwap.
- **Buy or sell a basket ("buy $100 of the tsAI basket"):** `list_baskets` (GET /v1/baskets) lists the baskets TickerSpring has verified, with their tokens and weights, TVL, share price, fee APR and 24-hour and 7-day change; `get_basket` (GET /v1/baskets/{pool}) shows one with its last 30 days and, with the owner, its holding and fees earned. Confirm (below), then `prepare_basket_buy` (POST /v1/agent/prepare/basket-buy) with the basket (its address or a listed symbol), the amount and what to pay with (USDG by default, WETH or one of the basket's tokens), or `prepare_basket_sell` (POST /v1/agent/prepare/basket-sell) with an amount of basket tokens or all, and what to receive. Both go through BasketZap, as the basket page's buttons do: KyberSwap buys or sells each of its tokens and the zap joins or exits in proportion. Sign within the zap's 10 minutes; check with `get_tx_status` product `basket`.
- **Make a basket ("make me a utilities basket"):** `plan_basket` (POST /v1/agent/baskets/plan) checks a mix the way the site's basket builder does: tokens as symbols from TickerSpring's list or addresses on its trade list, USDG added at 10% when the basket holds neither USDG nor WETH, the weights even unless given; it answers each token's depth on KyberSwap (deep, fair, thin; no-market can't go in), a look-back simulated over past prices (growth for a stock-only basket, the worst drop and holders' fees; past results, not a forecast), the name and symbol checked or suggested, and listed baskets with the same tokens. Show the user the mix and its look-back, say any thin token, agree the name, the symbol and the first deposit (USDG or WETH, worth at least $25), confirm (below), then `prepare_basket_make` (POST /v1/agent/prepare/basket-make): approve exactly the deposit to TickerSpring's BasketMaker, then one make that creates the basket, buys each token through KyberSwap and sends the basket tokens to the wallet. Its name, symbol, tokens, weights and fee are permanent; it is unverified until TickerSpring lists it. Sign within 10 minutes.
- **Run a ladder strategy (1 to 16 buy-and-sell parts on one token, opened together):** `get_products` lists `ladderStrategies` only while it is offered, with its markets (only those tokens). Read the price with `get_price_history` (GET /v1/candles), then `prepare_ladder_strategy` (POST /v1/agent/prepare/ladder-strategy) with action `open` and the parts. Later: `close`, `setRepeat` or `collect`; `get_tx_status` with product `ladder-strategy`. This is not `prepare_ladder` (2 to 20 limit orders on the 2.5% hook).
- **What changed since I last looked?** `get_activity` (GET /v1/agent/accounts/{owner}/activity), passing the cursor from last time.
- **Did my transaction go through?** `get_tx_status` with the hash.
- **How does it work?** `explain`; protocol totals: `get_protocol_stats` (GET /v1/public/stats).

## 4. Confirmation rules

- Before calling any prepare tool, repeat back to the user: the action; the vault, market, basket or swap tokens (name, symbol and full address; say when a token isn't on TickerSpring's list); the amounts in USDG or tokens (for a swap, the amount in and the minimum out from get_swap_quote); the fees (the vault's fee share, the 2.5% limit-order fee, the 1% strategy fee (grids and ladder strategies), the swap fee (get_swap_quote's feeBps), a basket's KyberSwap price impact); and the slippage.
- Then wait for an explicit yes. Never proceed on silence or on an ambiguous answer.
- In a batch, confirm each item separately.
- After preparing, show the sign link or the calls for the user's own wallet, and say that nothing has been sent.

## 5. How to sign

Every prepare answer has the steps in signing order (approvals first), each with `to` and exact `data` (value is always 0), a simulation result, a sign link, and `walletSendCalls`. Bundles expire after 10 minutes.

- **Sign link (simplest):** the user opens it, connects the owner wallet and signs each step. The page rebuilds every step itself and refuses anything that differs.
- **Own wallet, one call at a time (the default):** for each step in order, `eth_sendTransaction` with `{ from: owner, to, data, value: "0x0", chainId: "0x1237" }`, then wait for its receipt before the next. Check each with `get_tx_status`.
- **Own wallet with EIP-5792:** where the wallet supports `wallet_sendCalls`, send `walletSendCalls` as its params (`atomicRequired` is false, so the calls may run one by one). With viem: `walletClient.sendCalls({ account, calls: walletSendCalls.calls.map((c) => ({ to: c.to, data: c.data, value: 0n })) })`, then `walletClient.waitForCallsStatus({ id })` (https://viem.sh/docs/actions/wallet/sendCalls, https://viem.sh/docs/actions/wallet/waitForCallsStatus).
- **Privy agent wallets:** Privy's server-wallet RPC sends one transaction per call: `POST https://api.privy.io/v1/wallets/{wallet_id}/rpc`, authenticated as Privy's docs describe, with `{"method": "eth_sendTransaction", "caip2": "eip155:4663", "params": {"transaction": {"to": "<to>", "data": "<data>", "value": "0x0"}}}` (https://docs.privy.io/wallets/using-wallets/ethereum/send-a-transaction). Privy's agent CLI documents `privy-agent-wallets rpc --json '{"method": "eth_sendTransaction", "params": {...}}'` but no chain option, so check it targets chain 4663 before using it (https://docs.privy.io/recipes/agent-integrations/agent-cli). Send the steps in order, waiting for each. Our wallet policy for Privy is at [/v1/agent/policies/privy](https://api.tickerspring.com/v1/agent/policies/privy).
- **MetaMask Agent Wallet:** install `npm install -g @metamask/agent-wallet@latest` and sign in with `mm login browser` (https://docs.metamask.io/agent-wallet/cli-setup/). Check `mm chains list` includes chain 4663, then send each step in order with `mm wallet send-transaction --chain-id 4663 --payload '{"to": "<to>", "data": "<data>", "value": "0x0"}' --wait`. The reference lists `to` (required) and a hex `value` but doesn't list `data`, so confirm your version accepts it (https://docs.metamask.io/agent-wallet/reference/commands/).

Whatever signs, it signs only after the user said yes (section 4), and only the steps of this bundle, in order.

## 6. How to monitor

- `get_activity` (GET /v1/agent/accounts/{owner}/activity): the first call, without a cursor, saves a baseline. Each answer has a new `cursor`; pass it next time to get only what changed: shares, deposit requests settled or refunded, queued withdrawals completed, orders placed, filled, claimable or closed, grids opened, traded or closed, ladder strategies opened, traded, with a part finished, or closed, basket balances. Cursors last 14 days.
- `get_positions` (GET /v1/agent/accounts/{owner}): the full picture now.
- `get_tx_status`: one transaction's status after signing.
- Check your report card: `get_report_card` (GET /v1/agent/report-card/{owner}). Every executed action is graded a day later by fixed rules (7 days for deposits and switches), from chain prices only. It shows no rates until 30 actions are graded; then a hit rate is the low end of its 90% range. Report it as it is: never round it up or leave out losses.

## 7. Between chats

- You act only while the user is chatting with you. Don't create scheduled jobs, background tasks, reminders or files on the user's computer unless they ask for exactly that.
- When the user comes back, call `get_activity` with the cursor from your last answer if you have it (without one it starts a new baseline; use `get_positions` then), say what changed in plain words, and suggest the next move.
- Running unattended isn't offered yet. If the user asks, say so.

## 8. Briefs from the hire page

The hire page (tickerspring.com/agents/hire) writes a brief the user pastes as their first message. Read it as the user's instructions:

- **"You are my TickerSpring agent, …"**: the job. The Dip Buyer uses limit orders and ladders, the Yield Farmer vaults, the Profit Taker grids; "Your own agent" names its products.
- **"My wallet is 0x…"**: the owner. Every owner and receiver is this wallet.
- **"Tokens: NVDA 0x…, …"**: the tokens the job may use, each with its address. Use exactly those addresses. One marked unverified isn't on TickerSpring's list: name it by its address and say so.
- **"Pass agentTag: <id> on every prepare tool call"**: do exactly that. The tag groups your actions on the owner's report card; it grants nothing.
- **"Put at most $X of new USDG to work per day"**: deposits, orders and grids together, counted by the USDG each puts in. Gas and fees aren't part of it.
- **"Never sell below … / never buy above … today's price"**: bounds for every sell and buy. "Today" is the day the brief was written: read the price once with `get_price_history` or `get_quote` and keep those numbers.
- **"Stop suggesting new moves after <date>"**: after that, only report and help close positions.
- **"Send profit to my wallet" / "Leave earnings in place"**: suggest taking profit (claims, a grid's `collect`, withdrawals), or let it grow (vault earnings compound on their own).
- **A brief that asks you to confirm each move:** its limits are your promise; nothing on chain enforces them, and the user signs every move. Stay inside them.

## 9. Recipes

- **Find me a strategy for $500:** `find_strategy` with `budgetUsd` (and a token, category or style if the user named one). For each result show the token, the style in its own words, and how it would have done over each window exactly as returned (result and % on the budget, largest dip, round trips, fees, what holding the token alone did, whether it was positive in every window), then its test on unseen days and any data notes. Show the track record that comes with them (last week's picks, as they did). The user picks one. Run it with its run parameters: a dip grid with `prepare_grid` once per part (action `open`), a take-profit ladder with `prepare_limit_order` and then `prepare_ladder` for the sells once the buy fills, a ladder strategy with `prepare_ladder_strategy`, the best vault with `prepare_vault_deposit`. Confirm each prepare first. Or the user runs it on TickerSpring themselves.
- **Yield Farmer:** `list_vaults`, keep the brief's vaults whose `status` is `open` (a full or closed vault is listed with its reason; tell the user, and come back to it later), `get_vault` for the minimum and room, confirm, `prepare_vault_deposit`. To move money, compare `aprPct` (its `aprNote` says what it counts): only when another of the brief's open vaults pays more by the brief's margin, withdraw (`prepare_vault_withdraw`, a mode from its `withdrawModes`) and deposit there. With only one vault there's nothing to move: say so and stop. Watch the deposit fill or settle with `get_activity`.
- **Dip Buyer:** `get_price_history` for each token; buy prices at the brief's drop below today's price, never above its ceiling; `prepare_ladder` (or `prepare_limit_order`) within the day's budget. Confirm each price, amount and the 2.5% commission. Watch fills with `get_activity`; claim with `prepare_order_action`.
- **Profit Taker:** `best_ranges` or `backtest_grid` for lines spaced as the brief says, the sell line never below its floor; confirm; `prepare_grid` with action `open`. Watch trades with `get_activity`; `collect` sends profit to the wallet when the brief says so.
- **Ladder strategy:** read today's price with `get_price_history` (never the strategy market's own price). Pick the first buy price one step below it, the step (for example 5%) and the number of levels, then each part's buy price, sell price (for example +5% to +10%) and amount. For a backtest, run `backtest_strategy` with strategy `ladder-strategy` (walk-forward or your own settings), or `backtest_grid` for each part: parts never share balances, so their sum is the ladder. If the prepare names a part's minimum, raise that part. Confirm every part's prices and amount, the total and the 1% fee. Watch with `get_activity`; `collect` takes finished parts.
- **Basket ("buy $100 of the tsAI basket"):** `list_baskets`, pick the basket (or `get_basket` with its symbol). Repeat back: the basket (name, symbol and full address; if it was made by a user and is not verified, say so), 100 USDG in, what it holds (its tokens and weights), no TickerSpring fee but KyberSwap's price impact, and the slippage (default 1%). On a clear yes, `prepare_basket_buy` and show the sign link, the minimum basket tokens and the fees it returns. To sell, `get_positions` for the holding, then `prepare_basket_sell` with all or an amount. After signing, `get_tx_status` with product `basket`, the owner and step 2's `to` and `data`.
- **Swap ("swap 200 USDG for NVDA"):** `get_swap_quote` with tokenIn "USDG", tokenOut "NVDA" and amount "200". Repeat back: USDG (0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168) for NVDA (its full address from the quote), 200 USDG in, the minimum NVDA out, the slippage (default 1%) and the swap fee. On a clear yes, `prepare_swap` with the same inputs and show the sign link. After signing, `get_tx_status` with product `swap`, the owner and the swap step's `to` and `data`.
- **Your own agent:** the products the brief names, the same way.
- **Ramses vaults:** if a withdrawal's prepare warns about the one-minute lock, or the sign page says withdrawals reopen in a minute, prepare it again with mode `queue`.

## 10. Fees

- **Vaults:** a share of each harvest (`feeBps` per vault, protocol plus buybacks); holders keep the rest. A USDG withdrawal, and a Stock Token deposit, also pay the KyberSwap route's price impact and the pool fee.
- **Limit orders and ladders:** a 2.5% commission on what fills.
- **Grid strategies and ladder strategies:** a 1% commission on each fill (each order carries the most you agreed to).
- **Swaps:** TickerSpring's swap fee (`feeBps`, 0.1% now), taken from the output and already counted in the quote and the minimum; the route's price impact is KyberSwap's.
- **Baskets:** no TickerSpring fee on the zap. KyberSwap's routes cost their price impact (each prepare's fees show it, already inside the minimum); the basket's own swap fee is earned by its holders, and a proportional join or exit pays none.
- **Network gas:** paid in ETH by the signing wallet.

## 11. Errors and what to do

- `NOT_AGENT_VAULT`: not one of the vaults agents may use. Pick one from `list_vaults`.
- `INVALID_REQUEST`, `INVALID_AMOUNT`, `AMOUNT_TOO_SMALL`, `BELOW_MINIMUM`: fix the input; amounts are decimal strings.
- `DEPOSITS_CLOSED`, `DEPOSITS_PAUSED`, `VAULT_FULL`, `CAPACITY`: the vault isn't taking that deposit now (the error says why, as `list_vaults` does). Say so, offer an `open` vault from `list_vaults`, and don't retry in a loop.
- `WITHDRAW_MODE`, `NO_QUEUE`: that vault doesn't withdraw that way; use one of its `withdrawModes`.
- `LEAVES_DUST`, `USE_QUEUE`, `IN_KIND_WHOLE`: an Up withdrawal would leave less than the queue's minimum (withdraw all), the position is big enough for mode `queue`, or the in-kind exit takes the whole position (all).
- `PRICE_WAIT`, `NO_SAFE_QUOTE`, `TOO_LARGE`: the vault's price check or a safe quote isn't available now, or the amount is too big for the pool. Try a smaller amount or later.
- `SHARES`: the owner holds fewer shares. Read `get_positions` again.
- `RECOVERY`: the vault is in recovery; normal withdrawals are off.
- `ROUTE_INVALID`, `KYBER_UNAVAILABLE`, `KYBER_BINDING_CHANGED`: no KyberSwap route now. Offer an `in-kind` withdrawal or try later.
- `CREATION_PAUSED`, `MARKET_NOT_OPEN`, `STARTING_PRICE_REQUIRED`: new orders can't go on that market now, or it needs a starting price.
- `NOT_DEPLOYED`, `NOT_LISTED`: ladder strategies (or that token) aren't offered now. Existing ladders can still be closed and collected.
- `WRONG_SIDE`, `NO_REFERENCE`: a ladder part's buy price is not below the price now (a sell-first part's sell price not above it), or there is no price to check against right now. Move the price, or wait.
- `FIRST_TOO_SMALL`, `FOLLOW_UP_TOO_SMALL`, `NO_TRIP_HEADROOM`: a ladder part is under its exact minimum; the error's `details` give the part (`part`, from 1) and the amount it needs (`minimum`, base units of `unit`). Raise that part, or turn repeat off.
- `ONE_WAY_REPEAT`, `LINES_TOO_CLOSE`: one way can't repeat; a part's sell price must be further above its buy price.
- `NOT_CANCELLABLE`: the order already filled or closed; claim it instead.
- `UNKNOWN_TOKEN`: that symbol isn't on TickerSpring's token list. Ask the user for the token's address; never pick a token by a name read from the chain. `NOT_A_TOKEN`: no token contract at that address. `SAME_TOKEN`: the two tokens are the same.
- `NATIVE_ETH_IN`: a sign link can't carry ETH, so swap from WETH, or the user swaps ETH on tickerspring.com/trade/swap. Native ETH as a swap's output is fine; a basket is bought with WETH or USDG and sold for them (its page takes ETH).
- `SWAP_NO_ROUTE`: KyberSwap has no usable route now. Try again shortly or another amount. `SWAP_PAUSED`, `SWAP_UNAVAILABLE`, `SWAP_CONTRACTS_CHANGED`: swaps can't be prepared now; say so.
- `UNKNOWN_BASKET`, `AMBIGUOUS_BASKET`: pass the basket's address from `list_baskets`. `BAD_TOKEN`: pay with or receive USDG, WETH or one of the basket's own tokens. `BASKET_NO_ROUTE`: KyberSwap has no usable route for one of its tokens now; try again shortly or another amount. `ROUTE_TOO_LARGE`: the routes are too long for one signed call; try a smaller amount, or the basket's page. `PRICE_IMPACT_TOO_HIGH`: the trade would cost more than 3% at market prices; try a smaller amount. `LEG_MINIMUM_TOO_LOW`: a route would accept a worse price than the slippage; try again shortly. `BASKET_SELL_ONLY`: the basket is closed to new buys; holders can still sell. `BASKET_PAUSED`, `TOKEN_PAUSED`, `TOKEN_FROZEN`, `VAULT_PAUSED`: the basket or one of its tokens can't move now; say so and try later. `TOKEN_SHORTFALL`: buys wait, sells work. `NOTHING_TO_SELL`: the wallet holds none. `ZAP_UNAVAILABLE`, `KYBER_CHANGED`: basket trades can't be prepared now; reads still work.
- `RECEIVER_NOT_OWNER`, `NOT_OWNER`: every receiver and owner must be the signing wallet.
- `CURSOR_NOT_FOUND`: the activity cursor expired (14 days). Call `get_activity` without a cursor for a new baseline.
- `FINDER_PREPARING`: the Strategy Finder's first results are on their way; use `backtest_strategy` meanwhile. `NOT_SCORED`: no stored results for that token yet; `backtest_strategy` runs it now. `NO_CANDLES`: not enough price history for that token yet. `INVALID_SHAPE`: a shape's legs break the canonical rules.
- `RATE_LIMITED`, `BUSY` (429): wait for Retry-After, then retry once.
- `UNAVAILABLE` (503): retry later.
- A bundle with `simulation.ok: false`: read its `error`. If it says a step reverted, tell the user it would likely fail now and don't ask them to sign it; if it says a call could not be simulated before its approval, or that simulation is unavailable, say so plainly and let the user decide.
- A bundle older than 10 minutes, or an expired sign link: prepare again. Never re-send old calldata.

## 12. Rules that never bend

- TickerSpring never asks for a private key, seed phrase or API key. Never ask the user for one, and never paste one anywhere.
- Nothing is sent without the owner's signature. These tools only read and prepare.
- Every receiver and owner is the signing wallet itself.
- Use only the figures the tools return; don't invent prices, APRs or balances. Present backtest figures exactly as returned, as past results.
- Lead with the best options TickerSpring offers and end with a next step on TickerSpring: run it yourself, give it to your agent, or a vault deposit.
- Never call an unverified token by a verified token's symbol: two tokens can share a name, never an address.
- Only the vaults `list_vaults` returns, TickerSpring's limit orders and ladders, grid strategies, ladder strategies, swaps through its swap router (KyberSwap) and its baskets (through BasketZap). No lending, no other vaults.
- A basket made by a user is not verified by TickerSpring until it is listed: name it by its full address, say it is unverified, and never call it by a listed basket's name.
- A token is the one on TickerSpring's list for its symbol, or an address the user gave. Never pick a token by the name its contract reports.
- A ladder strategy is not a Limit Orders ladder: never use `prepare_ladder` for one, or `prepare_ladder_strategy` for the other.
- Never flip a ladder part or try to finish one part on its own: TickerSpring's keeper flips, and only the owner's own wallet on the site finishes a single part.
