A TypeScript SDK for the Questrade API, built with Bun. Provides type-safe access to:
- Accounts - Get account information, balances, positions, activities, executions, and orders
- Market Data - Search symbols, get quotes, candles (OHLC), option chains, and market info
Refer to the Questrade API documentation for detailed endpoint information.
- ✅ Full TypeScript support with comprehensive type definitions
- 🔄 Automatic token rotation - Questrade refresh tokens are automatically updated
- 🔐 Token persistence - Save rotated tokens automatically via callbacks
- 🧪 Comprehensive test coverage with unit and integration tests
- 📦 Zero dependencies (except Zod for validation)
- ⚡ Built with Bun for maximum performance
Before you can use this SDK, you need:
- Questrade Account - Create one at questrade.com
- API Key - Register your application at apphub.questrade.com to get your refresh token
bun add kest-trade-sdkimport { QuestradeClient } from 'kest-trade-sdk'
// Simple initialization - tokens are saved to .env automatically!
const client = new QuestradeClient({
refreshToken: process.env.QUESTRADE_REFRESH_TOKEN,
})
await client.initialize()
// Get accounts
const accounts = await client.accounts.getAccounts()
console.log(accounts)
// Get market quotes
const quotes = await client.market.getQuotes([8049]) // AAPL symbol ID
console.log(quotes)Questrade rotates refresh tokens on every use. When you exchange a refresh token for an access token, you receive a new refresh token. The old one becomes invalid immediately.
The SDK handles this automatically:
- Updates the internal token state
- Saves the new token to
.envfile (default) - Calls your custom
onTokenRefreshcallback (if provided)
Important: You must persist the new refresh token, otherwise you'll need to manually generate a new one from the Questrade dashboard.
const client = new QuestradeClient({
refreshToken: process.env.QUESTRADE_REFRESH_TOKEN,
})
await client.initialize()const client = new QuestradeClient({
refreshToken: 'your_refresh_token',
// Optional: Custom token persistence
onTokenRefresh: async (token) => {
await db.saveRefreshToken(token.refresh_token)
},
// Optional: Auto-refresh before expiry (default: true)
autoRefresh: true,
refreshBuffer: 60,
})
await client.initialize()For practical usage patterns, see the examples/ folder:
basic-usage.ts- Getting started with accounts and market datalogging-example.ts- Advanced logging and debugging
# Install dependencies
bun install
# Run unit tests
bun run test:unit
# Run integration tests (requires valid QUESTRADE_REFRESH_TOKEN in .env)
bun run test:integration
# Run all tests
bun test
# Lint and format
bun run lint:fix
# Build
bun run buildThe SDK includes comprehensive test coverage:
- Unit tests: Mock-based tests for all functionality
- Integration tests: Real API tests (require valid token)
To run integration tests, create a .env file:
QUESTRADE_REFRESH_TOKEN=your_token_here- Authorization
- Streaming
- Rate Limiting
- Error Handling
- Security
- Account calls
- Market calls
- Enumerations
- Order calls
- Add authorization methods
- Add account calls methods
- Add market calls methods
- Improve security practices for token storage
- Add Streaming API support
- Add buy/sell order methods
BSD licensed. See the LICENSE file for details.