Primitive/trading4 min read

Introducing /trading: let your AI agent trade stocks, options & crypto

Link a user's brokerage account via OAuth and trade stocks, options, and crypto through one Naïve key — account, positions, orders, and market data, with money-moving actions human-approval-gated by default. Naïve is the governed gateway; the connected brokerage is the broker.

Primitive/trading
TL;DR
  • /trading link a user's brokerage account via OAuth and trade stocks, options & crypto through one Naïve key
  • OAuth, not raw keys each end-user authorizes their own brokerage account (paper or live); Naïve holds a per-user token, never raw credentials
  • One order endpoint, every market the symbol decides it (AAPL, BTC/USD, AAPL241213C00250000)
  • Approval-gated by default placing, cancelling, and closing are human-in-the-loop for your end-users' agents
  • Naïve is the gateway, not the broker the connected brokerage custodies and executes; you get OAuth, encrypted token storage, multi-tenant scoping, and one audit trail
  • Free passthrough Naïve doesn't charge per trade; orders settle in the user's own funded (or paper) brokerage account

Today we're launching /trading — an AI agent can now trade stocks, options, and crypto on a user's linked brokerage account through one Naïve key. The user authorizes via OAuth once; money-moving actions are human-approval-gated by default. Naïve is the governed gateway; the connected brokerage is the broker.

The problem

Wiring an agent into the markets has only had bad options:

  • Raw keys. Handing the agent a brokerage key/secret gives it full account credentials — a security problem across a fleet of agents and users.
  • DIY OAuth. Letting each user link their own account means building the auth-code flow, encrypted token storage, and per-user isolation yourself.
  • Or become a broker. Going the full broker route means you create, custody, fund, and KYC accounts — months of compliance to buy one share.

How /trading works

  • Links a user's brokerage account over OAuth — no raw credentials in your code, only your nv_sk_* key.
  • Connectnaive trading connect --env paper returns an authorize_url (+ a disclosure to show the user). They approve; Naïve stores the token encrypted and marks the connection active.
  • Read (no approval) — naive trading account, positions, orders, quote.
  • Trade (approval-gated for end-users) — naive trading order to place; cancel and close to manage.

Two ways to trade: prompt or code

1. Natural language

# Connect once (open the returned authorize_url and approve)
naive trading connect --env paper
 
# Then trade — the symbol decides the market
naive trading order --symbol BTC/USD --notional 25 --side buy --type market --tif gtc
naive trading positions

2. Code

import { Naive, isPendingApproval } from "@usenaive-sdk/node";
const naive = new Naive({ apiKey: process.env.NAIVE_API_KEY });
 
// Link a user's account — show the returned `disclosure`, then send them to authorize_url
const { authorize_url } = await naive.forUser("alice").trading.connect({ env: "paper" });
 
// Place an order — money-moving, so it may resolve to a pending approval
const res = await naive.forUser("alice").trading.createOrder({
  symbol: "BTC/USD",
  notional: "25",
  side: "buy",
  type: "market",
  time_in_force: "gtc",
});
 
if (isPendingApproval(res)) {
  // Gated by the user's Account Kit — wait for a human to approve.
  await naive.forUser("alice").approvals.wait(res.approval_id);
}

Or hit the REST API directly — the same endpoint trades every asset class:

curl -X POST https://api.usenaive.ai/v1/trading/orders \
  -H "Authorization: Bearer $NAIVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "AAPL",
    "qty": "2",
    "side": "buy",
    "type": "limit",
    "limit_price": "150",
    "time_in_force": "day"
  }'

One endpoint, every market

No separate stocks/crypto APIs — the order symbol picks the market, and the same params (qty or notional, side, type, time_in_force, limit_price, order_class) apply across all three:

StocksCryptoOptions
SymbolAAPLBTC/USDAAPL241213C00250000
time_in_forceday, gtc, …gtc, iocday, gtc
Hoursmarket + extended24/7market
Fractionalyes (notional/qty)yesno
  • Crypto must be enabled on the user's brokerage account (account.crypto_status) — Naïve surfaces it, doesn't toggle it.
  • $10 minimum per crypto order — a smaller one returns a forbidden error and leaves the connection intact.

Approval-gated by default

  • Sensitive actions: place order, cancel order, close position.
  • For end-users, an agent (API-key) call returns 202 { "status": "pending_approval", "approval_id" } — it runs only after a human approves it in the Approvals queue.
  • Reads are never gated — account, positions, orders, quotes.
  • Operators set which actions require approval per Account Kit.

Naïve is the gateway, not the broker

  • Links the user's account over OAuth — Naïve never holds raw brokerage credentials.
  • Naïve doesn't open, custody, fund, or KYC accounts — the user's own brokerage account does that.
  • Naïve does handle: the OAuth flow, encrypted per-user token storage, multi-tenant scoping, the audit trail, and the approval gate.
  • A required disclosure is returned on connect and shown as an "Authorize naive" consent step before redirect.

What you can build with /trading

  • Trade on your users' direction — each end-user links their own brokerage account; orders are directed by the user and wait for their approval, and you never hold their keys.
  • Multi-tenant, per-user trading product — scope /trading per tenant user so each customer trades only their own account, at their own direction; meter with /billing.
  • 24/7 crypto support — pair a scheduled agent with notional orders (≥ $10) to prepare dollar-cost-averaging orders the user approves.
  • Research + execution on one key — compose with /llm for research and the Approvals queue for the human checkpoint on every trade.
  • Read-only portfolio monitoringaccount, positions, and quote with no money-moving scope.

Get started

Drop this starter prompt into any coding agent to wire up Naïve:

Read https://usenaive.ai/skill.md and use it to set up Naïve in my project.

Frequently Asked Questions
What is /trading?+
/trading is the Naïve primitive that lets an agent trade on a user's linked brokerage account. The user authorizes Naïve over OAuth; Naïve stores a per-user token and proxies the brokerage's trading API — account, assets, positions, orders, and market data — across stocks, options, and crypto. Money-moving actions are human-approval-gated by default.
Does Naïve custody or fund accounts?+
No. Naïve connects to a user's existing brokerage account over OAuth and is not the broker — it doesn't create, custody, or fund accounts. The user already has their own brokerage account and authorizes Naïve to act on it. Naïve is a governed gateway in front of the user's own account; the connected brokerage is the broker.
What can it trade?+
Stocks, options, and crypto — the same endpoints for all of them. The order symbol decides the market: AAPL (stock), BTC/USD (crypto), AAPL241213C00250000 (option). Order types are market, limit, stop, stop_limit, and trailing_stop, with time_in_force values day/gtc/opg/cls/ioc/fok (crypto supports gtc and ioc). Crypto trades 24/7 with a $10 minimum per order.
How is it billed?+
Naïve doesn't charge a per-trade fee — /trading is a passthrough to the user's own brokerage account, which is what's debited. You pay for the orders you place in your (or your user's) linked account; Naïve adds the OAuth, encrypted token storage, multi-tenant isolation, and approval governance around it.
What stops an agent from draining an account?+
Money-moving actions — placing an order, cancelling an order, and closing a position — are approval-gated by default for real end-users: an agent (API-key) call returns status 'pending_approval' and the action only runs after a human approves it in the Approvals queue. Operators configure this per Account Kit. The agent also only ever acts on the account the user explicitly linked via OAuth.
Paper or live?+
Both. Link with env 'paper' for paper trading or 'live' for a funded account; a user can link both and you pass env on each call. Live trading may require your brokerage integration to be approved before it can place live orders — paper works for development.
How do I get started with /trading?+
Run naive trading connect --env paper (or naive.trading.connect({ env: 'paper' })), open the returned authorize_url, and approve. Then naive trading account, naive trading positions, and naive trading order place trades. The full guide is at usenaive.ai/docs/getting-started/trading.
DZ
Dennis ZaxCTO

CTO of Naïve. Building the open-source agent runtime.

@denniszax