Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Trade a real on-chain crypto portfolio through the Voulai agent API. One per-strategy API key lets you read market data, run backtests, fund the strategy with a deposit address, and execute buys and sells that settle gaslessly through NEAR Intents into a custody wallet. You can put money in and trade it; you can never withdraw it — cashing out stays with the owner. Every call you make is logged and shown to them.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 441% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 318% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 295% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 176% | 0% |
You can trade a real on-chain portfolio through the Voulai agent API. The user who gave you the key created a strategy on Voulai, funded it, and scoped this key to that one strategy.
Can: read market helpers, read the portfolio and its history, execute buys and sells on the strategy's custody wallet.
Can also: generate a deposit address so the user (or you) can fund the strategy.
Cannot: withdraw, move funds to any address, touch any other strategy, or change strategy settings. Those stay with the owner on voulai.xyz. Do not promise the user you can move money out — you cannot, by construction. Point them at links.withdraw from /v1/agent/info instead.
The owner can revoke this key at any moment. If a request returns 401 with a revoked message, stop trading and tell the user.
Send the key in the X-Voulai-Key header on every request. Base URL:
https://voulai.xyz/apiGET /v1/agent/infoReturns the strategy you are bound to, its status, whether the key may trade, and your remaining budget for the rolling 24h window (swaps and USD notional). Read it before your first trade and after a 429, so you reason about your limits instead of discovering them as failures.
Trading requires status: "running". If the owner pauses or stops the strategy, trades are refused with 403 until they set it Running again — stop and tell the user rather than retrying.
GET /v1/agent/helpersReturns every read-only helper available to you, each with a description and JSON Schemas for its input and output.
This catalog is not a stable contract. Helpers get added, changed and retired. Call it and use what it returns — never hard-code a helper name, and never assume a helper you used yesterday still exists. A retired helper answers 410 Gone; when that happens, re-read the catalog and adapt rather than retry.
Run one:
POST /v1/agent/helpers/run
{ "helper": "market.ohlcv", "input": { "symbol": "BTC", "interval": "1h", "lookback": 200 } }Shape input from the helper's own input_schema in the catalog response.
The reply always has the same envelope, whatever the helper:
json{ "helper": "market.ohlcv", "version": "1.0.0", "output": { "candles": [ ... ] } }
Read your result from output. Its shape is the helper's output_schema from the catalog — so market.spot gives output.prices, indicators.return_zscore_vs_benchmark gives output.z, and so on. A missing output means the call failed, not that the helper returned nothing.
You can put money IN. You can never take it out — no endpoint exists, and that is deliberate: your key lives outside Voulai, so it is never allowed to move funds past the account's perimeter.
When the user asks to withdraw or cash out, do not apologise and do not look for an endpoint. Give them the link from GET /v1/agent/info (links.withdraw) and tell them to withdraw there with their own wallet. That is the whole answer.
GET /v1/agent/deposit/assetsWhat this strategy can be funded with: token references, their chains and decimals. Read it first — a token reference from anywhere else risks an address on the wrong chain, and those funds are unrecoverable.
POST /v1/agent/intents/deposit/cross-chain
{ "chain": "ethereum", "token": "<token from /deposit/assets>", "amount": "<minimal units>" }Returns a deposit address on the source chain, plus intent_id, an expiry and a quote. Supported chains today: near, ethereum, solana. Send only the named asset, only on the named chain.
GET /v1/agent/intents/deposit/cross-chain/status?id=<intent_id>pending_deposit → bridging → success (or failed / refunded). Wait for success before you size a trade against the new balance; the funds are not spendable until the bridge settles.
GET /v1/agent/portfolioSpendable cash in the base asset, plus every open position with quantity and average cost — reconciled against real custody, not a cached guess.
GET /v1/agent/decisions?limit=20Recent decision history, newest first. It includes trades you submitted and any decided by Voulai's own agent, so read it before acting: it is the full picture of what has happened to this portfolio.
POST /v1/agent/trade
{ "action": "buy", "asset": "<token id>", "size_usd": 25, "reasoning": "why" }
{ "action": "sell", "asset": "<token id>", "fraction": 1, "reasoning": "why" }buy spends size_usd of the strategy's base asset into asset.sell reduces the held position by fraction (1 = full exit).token-to-token hop, because positions, average cost and PnL are all measured against that base.
reasoning is stored and shown to the owner in their feed. Always send areal one — a human reads it to decide whether to keep you running.
asset must be a settlement asset id, and there is exactly one place to get one:
GET /v1/agent/assetsUse its token field verbatim. Do not pass ids from the market helpers: tokens.list and market.spot speak price-feed ids (dogecoin, shiba-inu), which exist for pricing and screening and are not settlement assets. Passing one is refused with a 400 naming this endpoint.
The two vocabularies line up by symbol — that is how you take a candidate you found with the market helpers and find the id you can actually trade. If a symbol is not in /v1/agent/assets, this strategy cannot trade it at all, no matter what the helpers report about it; pick another candidate rather than retrying.
The response carries the execution record. ok: false means the swap did not fill and nothing moved; it does not consume your daily budget.
Your key's tier caps three things, all reported by GET /v1/agent/info under limits:
requests_per_min — how fast you may call, counted per key.swaps_per_day — settled swaps in the rolling window_hours.daily_notional_usd — USD traded in the same window.limits.used tells you how much of the last two you have spent. Exceeding any of them returns 429. Back off and re-read /v1/agent/info rather than retrying immediately — the reply says which ceiling you hit and how much room is left.
Pace yourself against requests_per_min. It is counted per key, so it is yours alone and sharing an IP with other agents does not consume it.
424 with "code": "upstream_unavailable" means a service behind us — the custody/bridge API, the price feed — failed. Your request was fine and nothing moved. Wait a few seconds and retry; it is the one error class here that is worth retrying unchanged.
Read the code, not the status class: 424 is a 4xx only because this API is fronted by a CDN that would otherwise swallow a 5xx body and replace it with its own error page. Every other 4xx here means fix the request.
Every request you make — reads, trades, and anything refused — is recorded and shown to the strategy's owner, along with the reason for each refusal. This is not a reason to be timid; it is a reason to be honest. Send real reasoning, don't retry into a limit, and don't attempt things you were already told no to.
reasoning on every trade. The owner reads it.401, stop trading — the key is revoked or wrong.429, stop trading until the window frees up.424, wait a few seconds and retry the same call — a dependency blinked.links.withdraw and let themdo it with their own wallet.
Other measured skills in the registry, with their headline benchmark lift.