Install
openclaw skills install @psyb0t/go-ibkrTyped Go client for Interactive Brokers Web API to manage accounts, positions, market data, and orders via Client Portal Gateway or OAuth token.
openclaw skills install @psyb0t/go-ibkrUnofficial, typed Go client for the Interactive Brokers Web API, in package ibkr at the module root.
For install, both auth setups, operation lookup and response handling, see references/setup.md.
https://api.ibkr.com. Skip TLS verification only for a gateway on the user's own machine, which serves a self-signed certificate. Never skip it for any other host.SubmitNewOrder, ModifyOpenOrder, CancelOpenOrder, ConfirmOrderReply, the model order endpoints and Logout act on a real brokerage account. Call them only when the user asked for that exact action, and prefer a paper trading login while developing.github.com/psyb0t/go-ibkr.AGENTS.md in the repo.The spec paths carry their full prefix (/v1/api/...), so the base URL is only the scheme and host.
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net/http"
"github.com/psyb0t/go-ibkr"
)
// A Client Portal Gateway on this machine serves a self-signed certificate.
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
client, err := ibkr.NewClientWithResponses(
"https://localhost:5000",
ibkr.WithHTTPClient(httpClient),
)
if err != nil {
return err
}
status, err := client.GetBrokerageStatusWithResponse(ctx)
if err != nil {
return err // transport failure
}
if status.JSON200 == nil || status.JSON200.Authenticated == nil ||
!*status.JSON200.Authenticated {
return errors.New("log in to the gateway at https://localhost:5000")
}
accounts, err := client.GetBrokerageAccountsWithResponse(ctx)
if err != nil {
return err
}
if accounts.JSON200 == nil || accounts.JSON200.Accounts == nil {
return fmt.Errorf("accounts: %s", accounts.Status())
}
accountID := (*accounts.JSON200.Accounts)[0]
positions, err := client.GetPaginatedPositionsWithResponse(
ctx,
accountID,
0, // page
&ibkr.GetPaginatedPositionsParams{},
)
if err != nil {
return err
}
if positions.JSON200 != nil {
for _, position := range *positions.JSON200 {
fmt.Println(*position.Conid, *position.ContractDesc)
}
}
Keep a gateway session alive by calling GetSessionTokenWithResponse (POST /v1/api/tickle) about once a minute.
With OAuth, use https://api.ibkr.com as the base URL and add the token in a request editor:
auth := ibkr.WithRequestEditorFn(
func(_ context.Context, req *http.Request) error {
req.Header.Set("Authorization", "Bearer "+accessToken)
return nil
},
)
client, err := ibkr.NewClientWithResponses("https://api.ibkr.com", auth)
Most response fields are pointers; check for nil before dereferencing. The error return covers only transport and decoding failures. An API error comes back with JSON200 nil: check StatusCode() and Body.