# Joyride
> Joyride is a 0DTE (zero days to expiration) crypto options exchange on Solana. Paper trading only — no real money at risk.
No API key required. Create an account in the web app at https://joyride.exchange (referral code + terms attestation), then sign in with the same wallet. The CLI is login-only — invite/referral codes are redeemed in the web app, not the CLI. A wallet with no Joyride account cannot sign in from the CLI.
## Onboarding paths
### MCP agents (Claude Code, Cursor, Codex)
Five commands:
```bash
npm install -g joyride-cli
joyride setup
joyride login
joyride mcp install --client claude # or cursor, codex
# restart your MCP client
```
The CLI ships a bundled stdio MCP server with 18 tools for market data, trading, and account management. Node.js >= 20.0.0 required. The MCP server is stdio-only — there is no hosted HTTP MCP endpoint.
### Raw API bots (Python, Rust, any language)
No npm package required. Use HTTP and WebSocket directly. Every surface derives from the single public origin `https://joyride.exchange`:
- Trading WebSocket (SIWS auth, orders): `wss://joyride.exchange/api/client`
- Market-data WebSocket (books, trades): `wss://joyride.exchange/api/md`
- Oracle WebSocket (spot price): `wss://joyride.exchange/api/oracle`
- Public HTTP (market reads): `https://joyride.exchange/api/v1/market/*`
- Query API (self-scoped reads, Bearer): `https://joyride.exchange/api/query/*`
- SDK config `http_url` / `JOYRIDE_HTTP_URL`: the bare origin `https://joyride.exchange` (all URLs above derive from it)
Use the `joyride.exchange` origin above for production integrations. Older `api.joyride.exchange` split-host examples are legacy/stale and should not be used.
## Authentication
Wallet-based via SIWS (Sign-In with Solana). Generate any ed25519 keypair — that's your trading identity.
### WebSocket auth flow (on the trading WS)
1. Connect to the core trading WS `wss://joyride.exchange/api/client`
2. Request a nonce: `{"jsonrpc":"2.0","id":1,"method":"public/get_nonce","params":{"wallet":"
"}}`
3. Sign the message: `Sign in to Joyride\n\nWallet: \nNonce: ` with the wallet's ed25519 key
4. Submit: `{"jsonrpc":"2.0","id":2,"method":"public/auth","params":{"wallet":"","signature":"","message":""}}`
Successful auth returns `{ wallet, account_id, roles, session_token }`. Accounts are NOT auto-provisioned — a wallet with no Joyride account yields no usable `account_id` (sign up in the web app first). Reuse the `session_token` (a JWT whose lifetime the server sets via its `exp` claim) via `public/session_resume` to reconnect without re-signing.
### HTTP auth
Send the JWT as a Bearer token: `Authorization: Bearer ` (query API reads).
For CLI users, `joyride login` handles the SIWS flow and stores the JWT at `~/.joyride/session.json`. The server sets the session lifetime (JWT `exp`), not a fixed client default; `joyride auth status` shows the exact expiry, and `joyride logout` clears it on shared machines.
## Data conventions
- Prices and quantities: decimal strings, fixed 8dp (`"5.50000000"` = $5.50, `"1.00000000"` = 1 contract). Never parse to float for math — use fixed-point.
- Balances: decimal strings, 8dp (`"10000.00000000"` = $10,000)
- Instruments are identified by symbol only (see Instrument IDs)
## Instrument IDs
Format: `{ASSET}_USDC-{DMMMYY}-{STRIKE}-{C|P}`
Examples: `SOL_USDC-25APR26-150-C`, `BTC_USDC-25APR26-100000-P`, `ETH_USDC-25APR26-3500-C`
Assets: SOL, BTC, ETH. Instruments are 0DTE — they expire daily and refresh.
## WebSocket API (JSON-RPC 2.0)
### Trading methods (trading WS)
- `private/buy` — place a buy order (params: `instrument_name`, `price` and `quantity` as decimal strings, `order_type`, required `client_order_id` + `nonce`). Returns `{ok:true}`; outcome arrives as an async `order_ack` / `fill` / `reject` notification.
- `private/sell` — place a sell order (same params)
- `private/cancel` — cancel an order (params: `instrument_name`, `order_id`, `client_order_id`, `nonce`); async `cancel_ack` / `cancel_reject`
- Cancel-all: the SDK exposes a cancel-all facade (iterates open orders); check core for native `private/cancel_all` support
### Query methods
- `public/get_instruments` — list available options contracts (open instruments only)
- `public/get_market_config` — exchange configuration (decimals/version)
- query API `GET /api/query/open-orders`, `/api/query/positions`, `/api/query/balances`, `/api/query/fills` (Bearer, self-scoped)
### Subscription channels (market-data WS)
Subscribe by symbol on the MD WS: `{"jsonrpc":"2.0","id":10,"method":"public/subscribe","params":{"instruments":["SOL_USDC-25APR26-150-C"]}}`
- Book: `snapshot_start` / `book_delta` (incremental, keyed by `book_seq`) — the client maintains a book mirror
- Trades: `trades.`
- Lifecycle: `instrument_added`, `instrument_state`
- Private (trading WS, requires auth): `order_ack`, `fill`, `cancel_ack`, `settlement_entry` reports
- Spot: standalone oracle WS (`wss://joyride.exchange/api/oracle`), raw `price`/TWAP frames
## Error codes
| Code | Meaning |
|------|---------|
| 1001 | Not authenticated |
| 1002 | Insufficient balance |
| 1003 | Order not found |
| 1004 | Instrument not found |
| 1005 | Invalid price |
| 1006 | Invalid size |
| 1007 | Rate limit exceeded |
| 1008 | Order already cancelled or filled |
| 1009 | Market closed or instrument expired |
| 1010 | Authentication failed |
## MCP tools (18 tools available via joyride-cli, stdio-only)
Market data: `list_instruments`, `get_quote`, `get_orderbook`, `get_options_chain`, `get_ticker`, `get_all_tickers`, `get_market_config`
Spot: `get_index_price`
Trading: `place_order`, `cancel_order`, `cancel_all_orders`, `get_open_orders`, `get_order_status`
Account: `get_balance`, `get_account`, `get_positions`, `get_trade_history`
Wallet: `create_wallet`
Removed at core cutover (no core surface): `get_greeks`, `get_price_history`, `get_positions_with_metrics`, `get_order_history`, `get_profiles`.
Tools accept USD prices and contract sizes; the core wire carries decimal strings (8dp).
## Links
- Docs: https://docs.joyride.exchange
- Exchange: https://joyride.exchange
- npm: https://www.npmjs.com/package/joyride-cli
- GitHub (oracle, public): https://github.com/JoyrideExchange/oracle