Skip to main content
The Trading primitive links a user’s brokerage account via an OAuth2 Connect flow. Each user authorizes their own brokerage account (paper and/or live); Naive performs the token exchange and proxies the brokerage’s trading API on their behalf — so you never touch OAuth plumbing, token storage, or per-user isolation. One primitive trades stocks, options, and crypto: the order symbol decides the market (AAPL, BTC/USD, AAPL241213C00250000).
Naive is not the broker, a broker-dealer, or an investment adviser, and does not exercise trading discretion — the connected brokerage is the broker. Naive is a governed gateway in front of your users’ own brokerage accounts: the user directs and approves the trades. Money-moving actions (place/cancel order, close position) are approval-gated by default — see Approvals.

CLI First

# 1. Link a brokerage account (returns an authorize URL to open)
naive trading connect --env paper

# 2. Once authorized, read the account and trade
naive trading account
naive trading order --symbol BTC/USD --notional 25 --side buy --type market --tif gtc
naive trading positions

How the OAuth connection works

Naive owns a single platform OAuth app registered with the brokerage. connect returns an authorize_url; the user opens it, approves access, and the brokerage redirects back to Naive’s callback, which exchanges the code for a bearer token and stores it encrypted. The token is then used to call the brokerage’s trading API for that user.
1

Start the flow

naive trading connect --env paper
Returns { "authorize_url": "https://<brokerage-oauth>/authorize?...", "env": "paper" }.
2

User authorizes

Open the authorize_url and approve access. The brokerage redirects to Naive’s callback (/v1/trading/oauth/callback), which stores the token.
3

Confirm and trade

naive trading connections   # status: "active"
naive trading account
Use --env paper for paper trading and --env live for a funded account. A user can connect both; when both are connected, pass --env (or env) on each call. OAuth access tokens are long-lived (there is no refresh token); if access is ever revoked, calls return unauthorized and you simply reconnect.
Disclosure. A disclosure must be shown to the user at connection time. POST /v1/trading/connect returns it as a disclosure field (and the dashboard renders it as an “Authorize naive” consent step before redirecting). Display it before sending the user to the authorize URL.

Tools

ToolTypeDescription
trading_connectSetupStart the brokerage OAuth flow (returns an authorize URL)
trading_connectionsSetupList linked environments (paper/live) and status
trading_disconnectSetupForget a stored connection
trading_accountReadGet the connected brokerage account
trading_assetsReadList tradable assets (filter by asset class)
trading_positionsReadList open positions
trading_positionReadGet one open position
trading_ordersReadList orders
trading_get_orderReadGet one order
trading_quoteReadLatest quote(s) for symbols
trading_create_orderCore (sensitive)Place an order
trading_cancel_orderCore (sensitive)Cancel an open order
trading_close_positionCore (sensitive)Close (liquidate) a position

Placing orders

The same endpoint trades every asset class — the symbol selects the market. Provide either qty (shares/coins) or notional (dollar amount).
# Buy $25 of BTC at market (crypto trades 24/7; time_in_force gtc or ioc)
naive trading order --symbol BTC/USD --notional 25 --side buy --type market --tif gtc
Via the API:
curl -X POST https://api.usenaive.ai/v1/trading/orders \
  -H "Authorization: Bearer nv_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "BTC/USD",
    "notional": "25",
    "side": "buy",
    "type": "market",
    "time_in_force": "gtc"
  }'

Order parameters

ParameterTypeDescription
symbolstringAsset symbol — AAPL, BTC/USD, or an OCC option symbol
sidestringbuy or sell
qtystringQuantity (shares/coins). Use qty or notional
notionalstringDollar amount (fractional). Use notional or qty
typestringmarket (default), limit, stop, stop_limit, trailing_stop
time_in_forcestringday, gtc, opg, cls, ioc, fok. Crypto supports gtc/ioc
limit_pricestringRequired for limit / stop_limit
stop_pricestringRequired for stop / stop_limit
order_classstringsimple, bracket, oco, oto (equities)
extended_hoursbooleanAllow execution during extended hours (equities)
envstringpaper or live (required if both are connected)
Naive sends the request’s Idempotency-Key as the order’s client_order_id, so a retried logical order deduplicates at the broker.

Asset class differences

StocksCryptoOptions
SymbolAAPLBTC/USDAAPL241213C00250000
Order typesallmarket, limit, stop_limitall
time_in_forceday, gtc, …gtc, iocday, gtc
Hoursmarket + extended24/7market
Fractionalyes (notional/qty)yesno
Crypto trading must be enabled on the user’s brokerage account (the crypto agreement signed). Check trading_accountcrypto_status. Naive surfaces this but does not toggle it — it’s an account-level setting on the brokerage.
The brokerage enforces a $10 minimum per crypto order. An order below it is rejected with a forbidden error ("cost basis must be >= minimal amount of order 10") — the connection stays valid; just resize the order.

Positions & orders

# Positions
naive trading positions
naive trading position BTCUSD          # crypto position symbols are concatenated
naive trading close BTCUSD             # liquidate (SENSITIVE)
naive trading close AAPL --percentage 50

# Orders
naive trading orders --status open
naive trading get-order <order-id>
naive trading cancel <order-id>        # SENSITIVE

Market data

naive trading quote --symbols BTC/USD,ETH/USD            # crypto (default)
naive trading quote --symbols AAPL --class us_equity     # stocks

Governance

trading.order.create, trading.order.cancel, and trading.position.close are in the default approval set. For a real end-user (not the operator’s own default user), an agent (API-key) call returns 202 { "status": "pending_approval" } and the action runs only after a human approves it in Approvals. Operators can opt in/out per Account Kit via primitives_config.trading.requiresApproval.

Connection statuses

StatusMeaning
pendingOAuth started, awaiting authorization
activeConnected and ready to trade
expiredThe brokerage rejected the token (401) — reconnect
failedToken exchange failed
Disconnecting (DELETE /v1/trading/connections/:env) removes the stored connection entirely; reconnecting creates a fresh one.

Configuration

The trading primitive requires the platform OAuth app credentials + an encryption key on the API:
SettingPurpose
Brokerage OAuth app credentialsClient ID + secret for the platform’s brokerage OAuth app
OAuth redirect URIWhitelisted callback (defaults to ${API_URL}/v1/trading/oauth/callback)
Encryption key64-char hex key used to encrypt stored tokens at rest
Your brokerage OAuth app must be approved before it can execute live trades; paper works for development.