@quentinadam/ibkr
v0.1.2
Published
A client for the Interactive Brokers (IBKR) Web API with OAuth 1.0a authentication
Readme
@quentinadam/ibkr
A client for the Interactive Brokers (IBKR) Web API with OAuth 1.0a authentication.
Installation
# Deno
deno add jsr:@quentinadam/ibkr
# npm
npm install @quentinadam/ibkrCredential generation
To set up OAuth credentials for the IBKR Web API, access the OAuth Self-Service Portal and log in with the username you want to use for your API sessions.
Setup steps
Choose a consumer key (9 characters)
Generate and upload RSA key pairs for signing and encryption:
# Signature key pair openssl genrsa -out private_signature.pem 2048 openssl rsa -in private_signature.pem -outform PEM -pubout -out public_signature.pem # Encryption key pair openssl genrsa -out private_encryption.pem 2048 openssl rsa -in private_encryption.pem -outform PEM -pubout -out public_encryption.pemUpload the public keys (
public_signature.pemandpublic_encryption.pem) to the portal.Generate and upload a Diffie-Hellman prime:
openssl dhparam -outform PEM 2048 -out dhparam.pemUpload the generated
dhparam.pemfile to the portal.Generate the access token and encrypted access token secret via the portal.
Preparing credentials for use
After generating credentials through the portal, you need to prepare them for use with this library.
Converting the signature key to PKCS8 format
The signaturePrivateKey must be provided in PKCS8 format. The private_signature.pem file generated above is in
PKCS1 format by default. Convert it to PKCS8 format using:
openssl pkcs8 -topk8 -inform PEM -outform PEM -in private_signature.pem -nocryptA PKCS8 private key starts with -----BEGIN PRIVATE KEY----- and ends with -----END PRIVATE KEY----- (note: no "RSA"
in the header and footer, unlike PKCS1 format).
The private key can be provided in three ways:
Full PEM format (including header and footer):
const signaturePrivateKey = '-----BEGIN PRIVATE KEY-----\MIICdwIBADANBgkq...\n-----END PRIVATE KEY-----';Base64-encoded key only (without header and footer):
const signaturePrivateKey = 'MIICdwIBADANBgkq...';Uint8Array (raw PKCS8 bytes):
const signaturePrivateKey = Uint8Array.fromBase64('MIICdwIBADANBgkq...');
Decrypting the access token secret
Decrypt the encrypted access token secret from the portal using:
echo -n "ACCESS_TOKEN_SECRET" | base64 -d | openssl pkeyutl -decrypt -inkey private_encryption.pem | xxd -p -c 0Replace ACCESS_TOKEN_SECRET with the actual encrypted secret from the portal. This outputs the decrypted secret as a
hex string.
The accessTokenSecret can be provided in two ways:
Hex string (output from the decryption command):
const accessTokenSecret = 'a1b2c3d4e5f6...'; // hex string from the decryption commandUint8Array (raw bytes):
const accessTokenSecret = Uint8Array.fromHex('a1b2c3d4e5f6...');
Extracting the Diffie-Hellman prime
The diffieHellmanPrime must be provided as a big-endian hex string or as a bigint. Extract the hex string from
the dhparam.pem file using:
openssl dhparam -in dhparam.pem -text -noout \
| sed -n '/prime:/,/generator:/p' \
| grep -Ev 'prime|generator' \
| tr -d ' :\n' \
| sed 's/^00//'The prime can be provided in two ways:
Hex string (big-endian):
const diffieHellmanPrime = 'ed016e7a503ade7c...'; // hex string from above commandBigInt:
const diffieHellmanPrime = 0xed016e7a503ade7c...n; // bigint literal
Usage
Requirements
- Deno: Requires Deno v2.5 or higher.
- Node.js: Requires Node.js v25 or higher.
This library uses Uint8Array methods (toHex, toBase64, fromHex, fromBase64) which are only available in Deno
v2.5+ and Node.js v25+.
Importing the library
import ApiClient from '@quentinadam/ibkr';Creating an API client
const apiClient = new ApiClient({
baseUrl, // optional - defaults to 'https://api.ibkr.com/v1/api'
consumerKey, // required - your 9-character consumer key
accessToken, // required - the access token from the portal
accessTokenSecret, // required - the decrypted access token secret (hex string or Uint8Array)
signaturePrivateKey, // required - your private signature key in PKCS8 format (string or Uint8Array)
diffieHellmanPrime, // required - the DH prime as a big-endian hex string or bigint
realm, // optional - the OAuth realm, defaults to 'limited_poa'
logger, // optional - custom logger implementation
randomNonceGenerator, // optional - custom nonce generator (mostly for testing purposes)
randomBigIntGenerator, // optional - custom BigInt generator (mostly for testing purposes)
timeProvider, // optional - custom time provider (mostly for testing purposes)
});Making API requests
The request method is used to make authenticated API requests. It accepts the following options:
method(optional): HTTP method -'GET','POST', or'DELETE'(defaults to'GET')headers(optional): Additional HTTP headersbody(optional): Request body as a stringsignal(optional): AnAbortSignalto cancel the requestparseFn(required): Function to parse and validate the response body
Example:
const result = await apiClient.request('/iserver/accounts', {
parseFn(body) {
// Parse and validate the response body
return body;
},
});Initializing the brokerage session
Before making other API requests, you must initialize the brokerage session:
await apiClient.request('/iserver/auth/ssodh/init', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ publish: true, compete: true }),
parseFn(body) {
// Parse and validate the response body
return body;
},
});