publicOrdinary wallet execution
- Hidden
- Nothing
- Still visible
- wallet, asset, amount, venue
Plan, simulate and privately execute Stock Token trades.
One call returns a policy verdict and unsigned transactions. Your wallet signs.
POST /trades/plan
{
"side": "buy",
"symbol": "NVDA",
"quote": "USDG",
"amountIn": "500",
"privacy": { "mode": "shielded" }
}
→ verdict + unsigned callsBuilt for apps, wallets,
bots and AI agents.
Each checked trade plan binds the asset, route, transaction order, simulation evidence, privacy mode, policy verdict and expiry into one result your product can hand to a wallet.
const res = await fetch(`${process.env.VEILRAIL_API_BASE_URL}/trades/plan`, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.VEILRAIL_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"side": "buy",
"symbol": "NVDA",
"quote": "USDG",
"amountIn": "500",
"privacy": {
"mode": "shielded"
}
}),
});
const plan = await res.json(); // verdict + unsigned callsStart with the ticker your product already understands. VeilRail resolves it to the canonical Robinhood Chain Stock Token (address, decimals, issuer provenance, active deployment) and checks trading state before anything is routed.
A Chainlink reference price and the multiplier-adjusted token value stay separate from the executable quote. The quote makes input, minimum output, route, fees, slippage and expiry explicit across Uniswap v3/v4 and Pons, where available.
One call to /trades/plan returns ordered, unsigned calls: an approval only when the allowance is insufficient, then execution. Ask for privacy and the same plan carries a stealth settlement address or a locally generated proof.
The sequence is simulated against chain state and checked by the policy engine. allow means unsigned payloads may be presented; warn needs human or agent review; block means a named rule failed closed and no signable payload is returned.
VeilRail never signs and never needs a private key or seed phrase. API keys authorize API access only; they cannot sign or spend funds. Your app chooses when the connected wallet reviews, signs, and submits.
Same endpoint, same plan shape. Public plans execute like any wallet trade; stealth settles to a fresh single-use address; shielded hides owner, asset and amount behind sealed notes and a zero-knowledge proof.
publicstealthshieldedThe only request-line difference+ privacy: { mode: "shielded" }
A single-use address prevents a reusable public trading history from being tied back to the wallet that started the flow.
Explore the mechanism 01Commitment notes represent holdings without publishing the owner, asset, or amount, while zero-knowledge proofs verify valid spends.
Explore the mechanism 02The order stays unreadable before it enters settlement, so pre-trade strategy is not exposed to public market observers.
Explore the mechanism 03Opposite orders cancel inside short batch windows before only the aggregate residual reaches a public venue.
Explore the mechanism 04A holder can grant read-only visibility or provide compliance proofs without making every trade public by default.
Explore the mechanism 05A public observer still sees that a valid proof was submitted, aggregate residual swaps, the gas payer of public transactions and the pool size. Viewing keys and compliance proofs give lawful, read-only visibility; deposit screening is a protocol feature.
Read the compliance boundaryMost products start and stop at POST /trades/plan. Drop down to asset, price, quote, stored-plan, simulation and pool endpoints only when you need more control.
/trades/planBuild, prove, simulate, and check an unsigned plan.
↗GET/assetsList canonical supported assets.
↗GET/assets/{symbol}Resolve a symbol to its canonical Stock Token.
↗GET/prices/{symbol}Read reference and token-equivalent prices.
↗POST/quotesRequest an executable exact-input or exact-output quote.
↗GET/trade-plans/{planId}Retrieve a stored plan before expiry.
↗POST/transactions/simulateSimulate an ordered unsigned sequence.
↗GET/privacy/poolRead public pool size and supported shielded assets.
↗v0 developer-preview contract. Quantities are exact decimal strings. The base URL and OpenAPI schema ship with the live service.

Give every surface the same checked plan. Humans review it, bots branch on the verdict, agents call it through MCP tools, and the wallet stays the signing boundary.
A scrollable app screen with market discovery, quotes, transfers, and shielded activity, wired to the testnet API.
Open example ↗02 · Browser extensionShielded trade assistantA compact popup that adds VeilRail quotes and privacy checks to an existing broker flow, then builds a shielded plan before signing.
Open example ↗03 · Your productCustom surface on the APIShielded quotes, policy checks and unsigned trade plans, ready for your own app flow. Try the contract in the local playground.
Open playground →04 · AI agentsEight MCP toolsveil_get_asset, veil_get_price, veil_get_portfolio, veil_create_quote and four more, for Claude, Cursor and any MCP client.
Agents and MCP →A deterministic sandbox, plain HTTPS, and the same policy engine designed for live execution. The production base URL, packages and contract addresses are not published yet; the contract and the playground are.
A free sandbox includes a funded test wallet and simulated USDG. No funds or signature are required to test the planning flow.
veil_test_ / veil_live_granular scopesidempotency keysPlain HTTPS today; a TypeScript SDK, an OpenAPI schema and an MCP server with 8 tools for Claude, Cursor and any MCP client are planned for launch.
HTTPS + JSONOpenAPI (at launch)MCP · 8 toolstyped errorsA public plan and a shielded plan use the same endpoint and the same response shape. Add a privacy object; that is the whole diff.
+ privacy: { mode: "shielded" }const BASE = process.env.VEILRAIL_API_BASE_URL; // ships with the live service
const headers = {
"Authorization": `Bearer ${process.env.VEILRAIL_API_KEY}`, // veil_test_...
"Content-Type": "application/json",
};
export async function planTrade(intent: Record<string, unknown>) {
const res = await fetch(`${BASE}/trades/plan`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify(intent),
});
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.error.message), body.error);
return body; // verdict, reasons, unsigned transactions, expiry
}
const plan = await planTrade({
"side": "buy",
"symbol": "NVDA",
"quote": "USDG",
"amountIn": "500",
"privacy": {
"mode": "shielded"
}
});
DETERMINISTIC SANDBOXNo funds, no signature, no commitment. Deterministic prices, a funded test wallet, and the same policy engine designed for production.