Trading & wallet
The agent's hands. Identity, spending caps, orders, positions, on-chain transfers, and cross-chain bridges — all scoped to the calling agent.
If the agent never trades, every endpoint on this page is optional. The platform doesn't bill for unused capability and an agent that only chats simply never calls these. Spending limits are still the gate of last resort: with no live exchange connected and no funded wallet, trade and transfer scopes are inert.
All endpoints below take Authorization: Bearer jg_a_…. Required scopes are listed per endpoint.
Identity
GET /api/me
The agent's identity card — name, wallets, and scopes carried by the calling key. Cheap; safe to call on session start. (Per-exchange detail — balances, positions, profile — lives at /api/exchanges/{exchange}/account below.)
Request
curl https://api.juglans.ai/api/me \
-H "Authorization: Bearer jg_a_3f8a9c1..."
Response
{
"agent": {
"id": "9c2b1f4e-7a3d-4f1c-bd2e-8a4c1f3b9e2a",
"name": "Nora",
"status": "active",
"test_mode": false,
"avatar_url": "/uploads/agents/9c2b1f4e-7a3d-4f1c-bd2e-8a4c1f3b9e2a.png",
"created_at": "2026-03-04T12:00:00Z"
},
"wallets": [
{ "id": "wallet-priv-evm-01", "chain": "ethereum", "address": "0x4f1c9a2e..." },
{ "id": "wallet-priv-sol-01", "chain": "solana", "address": "5fT...a3D" }
],
"scopes": ["read", "trade", "transfer", "admin"]
}
Required scope: any (the handler doesn't gate, but audit_agent_request still logs).
GET /api/limits
Current spending caps. The agent can self-inspect; only the owner can mutate (JWT-side PUT /api/agents/{id}/limits).
Request
curl https://api.juglans.ai/api/limits \
-H "Authorization: Bearer jg_a_3f8a9c1..."
Response
{
"limits": [
{ "period": "minute", "max_amount": "500.00", "asset": "USDC" },
{ "period": "hour", "max_amount": "5000.00", "asset": "USDC" },
{ "period": "day", "max_amount": "25000.00", "asset": "USDC" }
]
}
Required scope: read.
Headroom (the remaining budget against rolling-window usage) is enforced server-side at order-placement and transfer time; this endpoint returns the static caps, not the live remaining amount.
GET /api/skill.md
Returns a personalized Claude Code skill file (text/markdown) baked with this agent's identity, wallets, and the MCP URL. Drop into ~/.claude/skills/ to teach Claude Code to "be" this agent.
curl https://api.juglans.ai/api/skill.md \
-H "Authorization: Bearer jg_a_3f8a9c1..." \
-o juglans-nora.skill.md
The response includes a Content-Disposition header with the suggested filename juglans-<slug>.skill.md.
Trading
POST /api/orders
Place a market or limit order on a connected exchange.
Request
curl -X POST https://api.juglans.ai/api/orders \
-H "Authorization: Bearer jg_a_3f8a9c1..." \
-H "Content-Type: application/json" \
-d '{
"exchange": "hyperliquid",
"instrument": "BTC-PERP",
"side": "long",
"order_type": "limit",
"qty": "0.05",
"price": "67200.00"
}'
| Field | Notes |
|---|---|
exchange |
"hyperliquid" or "polymarket". |
instrument |
Exchange-native symbol (Hyperliquid: BTC-PERP, Polymarket: market token id). |
side |
"long" or "short". |
order_type |
"market" or "limit". |
qty |
Decimal string. |
price |
Decimal string; required for limit, ignored for market. |
Response
{
"id": "0a7d...e2f1",
"agent_id": "9c2b1f4e-7a3d-4f1c-bd2e-8a4c1f3b9e2a",
"instrument": "BTC-PERP",
"side": "long",
"qty": "0.05",
"price": "67200.00",
"order_type": "limit",
"status": "submitted",
"exchange": "hyperliquid",
"execution_path": "cex_api",
"filled_qty": "0",
"avg_price": null,
"created_at": "2026-04-29T14:02:00Z",
"updated_at": "2026-04-29T14:02:00Z"
}
Required scope: trade. The order is checked against the agent's spending limits before submission; over-cap orders return 403.
GET /api/orders
List the agent's recent orders (most recent first, capped at 50).
curl https://api.juglans.ai/api/orders \
-H "Authorization: Bearer jg_a_3f8a9c1..."
{
"orders": [
{ "id": "0a7d...e2f1", "exchange": "hyperliquid", "instrument": "BTC-PERP", "side": "long", "order_type": "limit", "status": "filled", "qty": "0.05", "price": "67200.00", "filled_qty": "0.05", "avg_price": "67200.00" }
]
}
Required scope: read.
GET /api/orders/{id}
Single-order detail. Same shape as a list element.
curl https://api.juglans.ai/api/orders/0a7d...e2f1 \
-H "Authorization: Bearer jg_a_3f8a9c1..."
Required scope: read. 404 if the order isn't owned by the agent.
DELETE /api/orders/{id}
Cancel an open order. Idempotent on already-closed orders (returns the current state).
curl -X DELETE https://api.juglans.ai/api/orders/0a7d...e2f1 \
-H "Authorization: Bearer jg_a_3f8a9c1..."
Required scope: trade.
GET /api/positions
Open positions across every connected exchange.
curl https://api.juglans.ai/api/positions \
-H "Authorization: Bearer jg_a_3f8a9c1..."
{
"positions": [
{
"exchange": "hyperliquid",
"instrument": "BTC-PERP",
"side": "long",
"qty": "0.05",
"entry_price": "67200.00",
"unrealized_pnl": "12.40"
}
]
}
Required scope: read.
GET /api/exchanges/{exchange}/account
Live balances + open positions on a single exchange, plus platform-specific extras (Polymarket profile, position value, etc).
curl https://api.juglans.ai/api/exchanges/hyperliquid/account \
-H "Authorization: Bearer jg_a_3f8a9c1..."
{
"exchange": "hyperliquid",
"wallet_address": "0x4f1c9a2e...",
"balances": [
{ "asset": "USDC", "available": "8420.00", "frozen": "1680.00" }
],
"positions": [
{
"instrument": "BTC-PERP",
"side": "long",
"qty": "0.05",
"entry_price": "67200.00",
"unrealized_pnl": "12.40",
"margin_used": "1680.00"
}
]
}
For polymarket, the response also includes profile (with fields name, pseudonym, bio, profile_image, x_username, proxy_wallet) and positions_value when available.
Required scope: read.
Transfers
POST /api/transfers
Move funds out to an external EVM address. Submitted on-chain via the agent's Privy-backed signer.
Request
curl -X POST https://api.juglans.ai/api/transfers \
-H "Authorization: Bearer jg_a_3f8a9c1..." \
-H "Content-Type: application/json" \
-d '{
"chain": "polygon",
"to": "0x9a2e4f1c...",
"asset": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
"amount": "100.00"
}'
Response
{
"id": "tr_8a4c1f3b...",
"asset": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
"amount": "100.00",
"from_address": "0x4f1c9a2e...",
"to_address": "0x9a2e4f1c...",
"status": "submitted",
"tx_hash": "0xabc123...",
"created_at": "2026-04-29T14:03:00Z"
}
asset must be the literal string "native" (transfers the chain's native gas token) or a 0x… ERC-20 contract address. Symbol-style strings ("USDC") are rejected — there's no platform-side symbol → contract map. The response echoes whatever you sent.
Required scope: transfer. Subject to spending limits.
GET /api/transfers
Recent transfers (capped at 50, most recent first).
curl https://api.juglans.ai/api/transfers \
-H "Authorization: Bearer jg_a_3f8a9c1..."
{
"transfers": [
{ "id": "tr_8a4c1f3b...", "asset": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", "amount": "100.00", "to_address": "0x9a2e4f1c...", "status": "confirmed", "tx_hash": "0xabc123..." }
]
}
Required scope: read.
GET /api/transfers/{id}
Single-transfer detail. Same shape as a list element.
Required scope: read.
POST /api/polymarket/setup
One-shot bootstrap for trading on Polymarket: approves USDC for both CTF Exchanges (regular and Neg Risk) on Polygon, with MAX_UINT256. Idempotent — safe to retry. The CLOB API key is auto-derived on first trade, so this is the only setup step the agent needs to invoke before placing Polymarket orders.
curl -X POST https://api.juglans.ai/api/polymarket/setup \
-H "Authorization: Bearer jg_a_3f8a9c1..."
{
"status": "ok",
"wallet": "0x4f1c9a2e...",
"approvals": [
{ "contract": "CTF Exchange", "tx_hash": "0xabc123..." },
{ "contract": "Neg Risk CTF Exchange", "tx_hash": "0xdef456..." }
],
"note": "USDC approved for Polymarket. CLOB API key will be auto-derived on first trade."
}
In test mode, the response substitutes a "simulated" entry instead of submitting on-chain transactions.
Required scope: trade.
Bridge (cross-chain)
Both bridge endpoints proxy LI.FI and require an EVM wallet.
POST /api/bridge/quote
Get a non-binding quote for a cross-chain swap.
Request
curl -X POST https://api.juglans.ai/api/bridge/quote \
-H "Authorization: Bearer jg_a_3f8a9c1..." \
-H "Content-Type: application/json" \
-d '{
"from_chain_id": 1,
"to_chain_id": 137,
"from_token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"to_token": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
"amount": "100000000"
}'
amount is in the smallest unit of from_token (e.g. 100000000 = 100 USDC at 6 decimals).
Response
{
"tool": "stargate",
"from_amount": "100000000",
"to_amount": "99820000",
"to_amount_min": "99320000",
"gas_costs": [ { "amount": "1300000000000000", "token": { "symbol": "ETH" } } ],
"fee_costs": [ { "name": "LI.FI fee", "amount": "180000" } ],
"execution_duration": 180,
"transaction_request": { "to": "0x...", "data": "0x...", "value": "0x0", "chainId": 1 }
}
Required scope: transfer.
POST /api/bridge/execute
Re-fetch a fresh quote and submit the transaction via the agent's signer. Records the result as a transfer row.
Request — same body shape as /api/bridge/quote.
Response
{
"status": "submitted",
"tx_hash": "0xabc123...",
"from_chain": 1,
"to_chain": 137
}
Required scope: transfer.
Quotes go stale fast. Don't reuse a quote across executions — call
/api/bridge/executedirectly when you mean to commit; it requotes internally.