Umbix docs: one checked plan per trade.
Umbix turns a request to trade a Robinhood Chain stock token into a list of unsigned steps, dry-runs that list from your wallet against the latest block, and returns a verdict your code can act on. This page covers every field, every rule and every limit.
Public plans on Robinhood Chain mainnet, routed through Uniswap v3, simulated with eth_simulateV1. The plan latch is written and tested but not deployed; stealth and shielded settlement are not part of this build.
A trade idea in, a signable plan out.
Your app sends intent: what to trade, how much, from which wallet. The planner resolves the asset, prices it, picks a route, builds the steps, simulates them and judges the result. The planner holds no key, keeps no funds and has no endpoint that accepts a signature.
Your first plan in three moves.
Buy NVDA with 500 USDG from your wallet. The answer holds unsigned steps only; nothing is sent until your wallet signs.
Send the request
No key and no package: one POST with a JSON body from any HTTP client.
Read the verdict
Stop on block, show the warnings on warn, carry on with allow.
Sign in order
Send each step from the same wallet and wait for its receipt before the next.
curl -s https://umbix.xyz/api/trades/plan \
-H 'content-type: application/json' \
-d '{"side":"buy","symbol":"NVDA","quote":"USDG",
"amountIn":"500","wallet":"0xYourWallet"}'const reply = await fetch("https://umbix.xyz/api/trades/plan", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
side: "buy", symbol: "NVDA", quote: "USDG",
amountIn: "500", wallet: account,
}),
});
const plan: PlanAnswer = await reply.json();
if (plan.verdict === "block") throw new Error(plan.reasons[0].message);// Your app owns the wallet client; the planner never sees a key.
for (const step of plan.transactions) {
const hash = await wallet.sendTransaction({
to: step.to, data: step.data, value: BigInt(step.value),
});
await publicClient.waitForTransactionReceipt({ hash });
}The planner hands back a plan and its evidence. The wallet shows it, signs it and broadcasts it. A simulation reads one block and cannot promise a future fill.
No keys, open limits.
The routes need no account and no API key. Base path: /api on this site, CORS open for POST /api/trades/plan.
curl -s https://umbix.xyz/api/assets/NVDAPOST /api/trades/planAbout 12 plans a minute per network (an IPv4 address or an IPv6 /64). Over that: HTTP 429 with retry-after.
GET /api/assetsCached for a few seconds and safe to poll for a price board.
body sizeUp to 2 KB per request; larger bodies get HTTP 413.
No private key, no recovery phrase and no sign-in signature. Anything that asks for one in Umbix's name is not Umbix.
Try the decision path without spending.
There is no separate test network to sign up for. Three ways to see real answers without moving funds:
You get the live quote and a WALLET_REQUIRED block, which shows routing and pricing without simulation.
Pass any address as wallet. The simulation runs from it, so you see what would happen for that balance, and nothing can be signed.
The playground walks through the steps one by one; closing the wallet prompt ends the trade with nothing sent.
Confirm the share before touching a pool.
A ticker is accepted only when it is on the planner's list of official stock tokens and the token's runtime code still embeds Robinhood's stock-token beacon.
Beacon 0xe10b6f6b275de231345c20d14ab812db62151b00 in the token's code. Look-alikes with the same symbol are refused.
Read from paused() and tokenPaused() before any route is searched.
Chainlink price per share × uiMultiplier / 1e18. The multiplier rises with dividends. ETH uses the ETH/USD feed 0x78F3556b67E17Df817D51Ef5a990cDaF09E8d3A9.
Uniswap v3 (factory 0x1f7d7550B1b028f7571E69A784071F0205FD2EfA, quoter 0x33E885Ed0Ec9bF04eCFB19341582aaDCB4c8A9e7), every fee tier (100, 500, 3000, 10000), directly or via USDG 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 or WETH 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73. The best quote wins.
curl -s https://umbix.xyz/api/assets/NVDAOne field, three modes, one live.
The request takes privacy.mode. Confidentiality with auditability, not anonymity. Only public produces steps in this build.
"privacy": { "mode": "public" }Asking for stealth or shielded returns PRIVACY_MODE_UNAVAILABLE with no steps, rather than a plan that pretends.
Five guards on every public plan.
Each guard covers a different way a trade can go wrong between the ticker and the signature.
Beacon check
Only official stock tokens resolve; look-alike contracts never reach a pool.
assets · beacon · paused stateExact approval
Approvals cover the amount spent and nothing more.
approve(router, amountIn)Wallet dry run
Every step is simulated from your address, in order, in one block.
eth_simulateV1 · decoded revertsPlan latch
The latch recomputes the plan hash and settles each plan once. Written and tested, not deployed yet; plans use the router path meanwhile.
UmbixPlanLatch · settle onceFail closed
Missing facts block the plan instead of waving it through.
PAUSE_STATE_UNKNOWN · REFERENCE_UNAVAILABLEThe later privacy modes aim to keep a strategy from every market watcher while the holder can still show what they did to someone entitled to see it.
Route, steps, evidence and verdict in one answer.
A well-formed request always gets a plan, even when the verdict is block.
{
"side": "buy",
"symbol": "NVDA",
"quote": "USDG",
"amountIn": "500",
"wallet": "0xYourWallet",
"slippageBps": 50,
"privacy": { "mode": "public" }
}| Field | Type | Meaning |
|---|---|---|
| side | "buy" | "sell" | Buy spends the quote asset to receive the stock token; sell does the reverse. |
| symbol | string | Stock ticker such as NVDA. Checked against the official list and the beacon, never trusted by name. |
| quote | "USDG" | "ETH" | "WETH" | What you pay with or receive. Default USDG. ETH is wrapped and unwrapped for you. |
| amountIn | decimal string | Exact amount of the asset you spend, such as "500" or "0.25". No exponent, no more decimals than the asset has. |
| wallet | 0x address | The wallet that will sign. Without it you get a quote and a block verdict, because nothing can be simulated. |
| recipient | 0x address | Where the output goes. Default: the wallet. Anything else raises RECIPIENT_OTHER. |
| slippageBps | integer | How far the fill may fall short of the quote. Default 50, range 1 to 500. Above 100 warns. |
| deadlineSec | integer | Seconds until the steps stop being valid on chain. Default 600, range 60 to 3600. |
| privacy.mode | "public" | "stealth" | "shielded" | Only public is produced in this build; the other two return a block verdict that says so. |
{
"verdict": "allow",
"reasons": [
{ "code": "APPROVAL_NEEDED", "level": "info", ... },
{ "code": "EXECUTOR_ROUTER", "level": "info", ... }
],
"asset": { "symbol": "NVDA", "canonical": true, "halted": false, ... },
"reference": { "priceUsd": 217.0, "tokenValueUsd": 217.17, "ageSec": 840 },
"quote": {
"venue": "Uniswap v3",
"route": [ { "fee": 100, ... }, { "fee": 500, ... } ],
"amountOut": "2.2982", "minOut": "2.2867", "deviationBps": 18
},
"transactions": [
{ "step": 1, "kind": "approval", "to": "0x5fc5…", "data": "0x095e…" },
{ "step": 2, "kind": "swap", "to": "0xCaf6…", "data": "0x5ae4…" }
],
"simulation": { "ran": true, "ok": true, "calls": [ ... ] },
"deadline": 1792520400
}asset: the official token, its beacon check, paused state and multiplier.
reference and quote: Chainlink value, pools and fee tiers, amountOut, minOut, slippage, and deviationBps against the reference.
transactions: to, data, value (wei as a decimal string) and chainId. Empty on block.
simulation: the eth_simulateV1 run, per step success, gas used and a readable error, plus the simulated output.
deadline / expiresAt: Unix time after which the swap step reverts on chain.
UmbixPlanLatch is an immutable contract that settles one plan through the Uniswap v3 router (0xCaf681a66D020601342297493863E78C959E5cb2). It recomputes the plan hash from the call and reverts on any difference, on a second settlement, on a caller other than the payer, after the deadline, or below the minimum output. No owner, no fee, no pause, no upgrade. Not deployed yet.
Every verdict names its rule.
Let your code follow the verdict and the reason codes, never the wording of the messages.
| Verdict | What your app should do | Steps |
|---|---|---|
| allow | Every rule passed. Show the steps to the wallet. | Included |
| warn | The trade works, but a person or agent should read the warnings first. | Included |
| block | A rule did not pass. Show the reason and stop. | None |
Thresholds: cost over reference warns from 2% and blocks from 10%. A reference older than 6 hours warns. USDG counts as one dollar for this check.
What anyone can still see.
A public plan is an ordinary swap. A watcher of the chain can read all of this:
The address that signs the approval and the swap.
Which stock token moved, in which direction, and how much.
The Uniswap v3 pools and fee tiers the route used.
Who paid for each transaction and how much.
Each answer is computed from chain state when it is asked for. Rate limits keep a short-lived counter per network and nothing else.
A small surface with plain answers.
Every route answers JSON. Amounts are exact decimal strings; raw integer amounts are strings too.
/api/trades/planResolve, quote, build, simulate and judge one trade./api/assetsEvery official stock token with value, multiplier and trading state./api/assets/{symbol}One ticker resolved, or 404 when it is not an official token./api/chainChain head, gas price, ETH/USD and the latch status./api/plans/{planId}Planned: fetch a stored plan before it expires./api/simulatePlanned: dry-run an ordered list of unsigned calls you built.Fields are added, never renamed, within v0. Errors carry a code, an HTTP status and a sentence.
One fetch, no package to install.
There is no SDK. A dozen lines of fetch give you the whole API:
const reply = await fetch("https://umbix.xyz/api/trades/plan", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
side: "buy", symbol: "NVDA", quote: "USDG",
amountIn: "500", wallet: account,
}),
});
const plan: PlanAnswer = await reply.json();
if (plan.verdict === "block") throw new Error(plan.reasons[0].message);Copy the PlanAnswer shape from the response example; every field is documented above.
Retry on HTTP 429 after the retry-after seconds, and on CHAIN_UNAVAILABLE.
Keep amounts as strings end to end; never round-trip them through floating point.
Send steps unchanged, in order, from the wallet named in the request.
Let an agent propose, never sign.
An AI agent can call the endpoint like any client and reason over the reason codes. Keep the wallet outside the agent.
curl -s https://umbix.xyz/api/trades/plan \
-H 'content-type: application/json' \
-d '{"side":"sell","symbol":"TSLA","quote":"ETH",
"amountIn":"0.25","wallet":"0xYourWallet",
"slippageBps":75,"deadlineSec":300}'GET /api/assetsList the tokens an agent may name.GET /api/assets/{symbol}Check one ticker before planning.POST /api/trades/planAsk for a plan and its verdict.GET /api/chainCheck the network before acting.Because a block verdict carries no steps, an agent cannot pass on something the planner refused. Let a person or a wallet policy approve the rest.
Errors a program can handle.
Malformed requests get HTTP 400 with a code. A well-formed request always gets a plan; problems with the trade itself come back as reason codes.
| Code | Level | Meaning |
|---|---|---|
| ASSET_NOT_CANONICAL | block | The ticker is not one of the official stock tokens, or the token at that address no longer carries Robinhood's stock-token beacon. |
| ASSET_HALTED | block | The stock token reports paused trading. |
| PAUSE_STATE_UNKNOWN | block | The stock token's paused / tokenPaused state could not be read. Missing facts fail closed: no steps are returned. |
| REFERENCE_UNAVAILABLE | block | The Chainlink reference price or the token multiplier could not be read, so the cost check could not run. Missing facts fail closed: no steps are returned. |
| PRIVACY_MODE_UNAVAILABLE | block | Stealth and shielded settlement are not part of this build. Only public plans are produced. |
| WALLET_REQUIRED | block | No wallet was given, so balances, allowance and simulation could not be checked. The quote is still returned. |
| RECIPIENT_INVALID | block | The recipient is not a valid address. |
| NO_ROUTE | block | No Uniswap v3 pool path with liquidity connects the two assets. |
| INSUFFICIENT_BALANCE | block | The wallet holds less than the amount it would spend. |
| PRICE_DEVIATION_HIGH | block | The trade would cost more than the block threshold above the Chainlink reference value. |
| SIMULATION_FAILED | block | At least one step reverted when the ordered sequence was simulated against the latest block. |
| CHAIN_UNAVAILABLE | block | The planner could not read Robinhood Chain right now. |
| PRICE_DEVIATION | warn | The trade costs noticeably more than the reference value (fees, spread, thin pool). |
| REFERENCE_STALE | warn | The reference price is hours old, which usually means the US market is closed. Pool prices can drift meanwhile. |
| SLIPPAGE_WIDE | warn | The slippage you allowed is wide; a worse fill would still settle. |
| RECIPIENT_OTHER | warn | The output goes to an address other than the signing wallet. |
| GAS_BALANCE_LOW | warn | The wallet's ETH may not cover gas for every step. |
| APPROVAL_NEEDED | info | The allowance is short, so the plan starts with an approval for exactly this amount (never unlimited). |
| EXECUTOR_ROUTER | info | The plan latch is not deployed yet, so the swap goes straight to the Uniswap v3 router with your minimum output and deadline. |
| EXECUTOR_LATCH | info | The swap settles through the plan latch, which refuses any change to the reviewed plan and settles it at most once. |
Request errors include INVALID_JSON, INVALID_AMOUNT, INVALID_SIDE and UNKNOWN_FIELD (400) and BODY_TOO_LARGE (413). Going over the rate limit returns HTTP 429 with a retry-after header.
What the planner will not stretch to.
Each limit is deliberate; most protect you from a plan that looks fine and settles badly.
Very large trades may find no route or a costly one; the deviation rules will say so.
You fix what you spend; the minimum output follows from the quote and your slippage.
Simulation reads the latest block. Prices move, so the minimum and the deadline are what protect you on chain.
Chainlink stock feeds follow US trading hours; outside them the reference ages and REFERENCE_STALE warns.
Confidentiality with auditability, not anonymity.
Umbix is a planning tool. It is not a way to hide funds from anyone with a lawful right to see them, and it will not be described as one.
- It does not sign, send, custody or hold anything, and never requests a private key or recovery phrase.
- It does not guarantee a fill: simulation reads one block, the market moves on.
- It does not give investment advice. Stock tokens track a share's price and carry no shareholder rights.
- It is not affiliated with Robinhood or Uniswap and only reads their public contracts.
The playground calls the same endpoint and lets you sign the steps one at a time.