Endpoints
Everything is served from the public originhttps://joyride.exchange, with no separate API host.
The trading WebSocket speaks JSON-RPC 2.0. Every request carries
"jsonrpc": "2.0", an id, a method, and optional params; every response echoes the id. Server pushes arrive as "method": "subscription" notifications with no id.
Authentication
Identity is an ed25519 keypair. There are no API keys. An account is provisioned against a Solana wallet public key (see the venue pages linked at the end), and that keypair signs in from a bot, the CLI, or the web app. Sign-in uses three methods on the trading WebSocket.Request a nonce
Sign and authenticate
The message is built byte for byte as below: a blank line between the greeting and theWallet: line, a single newline before Nonce:.
wallet and the nonce inside message and rejects any deviation, including a trailing newline or reordered lines.
roles lists what the account may do. A quoter’s array contains rfq_quoter; a taker’s is empty. A wallet with no provisioned account is rejected with 1001. Signing in never creates an account.
Resume on reconnect
A storedsession_token authenticates a new socket without a fresh signature. Resume checks that the wallet still owns the account_id in the token and recomputes roles from live account state, so a role change takes effect on the next resume.
1001 on resume means the cached token is no longer valid; the full nonce, sign, auth sequence is required. public/session_resume on a socket already authenticated as the same account refreshes that session and evicts nothing.
Session token
The session token is the JWT that
public/auth returns after the wallet signs the nonce. There is no revocation list, so a leaked token can trade the account until its exp. Joyride never holds a maker’s private key, so the remedy is on the maker’s side: generate a new keypair and email support@joyride.exchange to bind the account to the new public key. Once the account is rebound, tokens issued to the old key are refused on public/session_resume, and any connection still open under one ends when it disconnects.
Sessions per account
Every session receives every account-scoped push, so a bot needs one authenticated socket. A client closed with
4001 and reason session_limit must not reconnect automatically: the reconnect evicts the newer session and the two clients evict each other in a loop. Reconnect only on an operator action.
Keepalive
The server never pings. The client sends a protocol-level WebSocket ping at least every 30 seconds to keep intermediaries from dropping a quiet flow, and the gateway answers each with a pong. An unauthenticated socket that sends nothing for 60 seconds is reaped with error
1001.
Rate budget
The budget is per account, so three sessions share it. Each request counts as one, whether it is a poll, a response, or a decline.
Error codes
Errors use the JSON-RPC envelope{ "code", "message", "data"? }. Close codes are WebSocket close frames, not JSON-RPC errors.
The
1200 frame:
-32700 parse, -32600 invalid request, -32601 method not found, -32602 invalid params, -32603 internal) follow the JSON-RPC 2.0 specification. An unknown instrument symbol in a request is rejected as -32602.
Support
Support for live makers is support@joyride.exchange. A report that includes theoperation_id from a 1200 error, the rfq_id or quote_id in question, and the UTC time of the event can be traced directly.
Next: Becoming an RFQ Quoter