goksei

package module
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2025 License: MIT Imports: 20 Imported by: 0

README

goksei

Unofficial client library for AKSES-KSEI

Go Reference Go Report Card

Project status

Unstable proof of concept

Features

  • Login with username and (salted) password
  • Cache token on disk with auto relogin when expired
  • Get balance overview
  • Get balance for Equities, Mutual Funds, Bonds, and "Others"
  • Get cash balance
  • Command-line interface

Using as library

Get it as dependency

go get -u github.com/chickenzord/goksei

Example usages:


import "github.com/chickenzord/goksei"

func main() {
	username := "myemail@domain.com"
	password := "myinsecurepassword"
	plainPassword := true

	authStore, err := goksei.NewFileAuthStore(".goksei-auth")
	if err != nil {
		panic(err)
	}

	client := goksei.NewClient(goksei.ClientOpts{
		Username:      username,
		Password:      password,
		PlainPassword: plainPassword,
		AuthStore:     authStore,
	})

	equityBalance, err := client.GetShareBalances(goksei.EquityType)
	if err != nil {
		panic(err)
	}

	// ...
}

Trying out the example

Create .env file with following content:

GOKSEI_USERNAME=youremail@domain.com
GOKSEI_PASSWORD=yoursaltedpassword

The salted password can be obtained by logging in with your account on https://akses.ksei.co.id/login and inspect the request payload sent by JS code.

(New feature) Alternatively, you can also supply your plaintext password in GOKSEI_PASSWORD then set GOKSEI_PLAIN_PASSWORD to true. Goksei will automate the hashing process for every login attempts.

GOKSEI_USERNAME=youremail@domain.com
GOKSEI_PASSWORD=yourplainpassword
GOKSEI_PLAIN_PASSWORD=true

Then you can run the example using this command:

cd ./cmd/example
go run .

Disclaimer

This project is only for personal and educational purpose. Use on your own risk, there is no guarantee this project will always work when KSEI changed their API or policies.

Documentation

Overview

Package goksei provides an unofficial Go client library for AKSES-KSEI, the Indonesian Central Securities Depository API.

This library allows programmatic access to portfolio information including:

  • Cash balances across different custodian banks and currencies
  • Share/security holdings for equities, mutual funds, bonds, and other assets
  • Portfolio summaries with total values and asset breakdowns
  • Account identity information

The client handles authentication automatically, including token caching and renewal. It supports both plain text passwords (automatically hashed) and pre-hashed passwords.

Basic usage:

authStore, err := goksei.NewFileAuthStore(".goksei-auth")
if err != nil {
	log.Fatal(err)
}

client := goksei.NewClient(goksei.ClientOpts{
	Username:      "your.email@domain.com",
	Password:      "your-password",
	PlainPassword: true,
	AuthStore:     authStore,
	Timeout:       30 * time.Second, // optional: default is 30s
})

summary, err := client.GetPortfolioSummary()
if err != nil {
	log.Fatal(err)
}

Security note: This library uses SHA1 for password hashing as required by the KSEI API. This is a requirement from KSEI and cannot be changed.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CustodianBankNameByCode added in v0.7.1

func CustodianBankNameByCode(code string) (name string, ok bool)

CustodianBankNameByCode looks up a custodian bank name by its code. The function strips numeric suffixes from codes for matching. Returns the bank name and true if found, empty string and false otherwise.

func CustodianBankNameByID deprecated added in v0.6.0

func CustodianBankNameByID(id string) (name string, ok bool)

CustodianBankNameByID returns bank name by ID

Deprecated: use CustodianBankNameByCode instead

Types

type AuthStore

type AuthStore gokv.Store

AuthStore provides an interface for persisting authentication tokens. It extends the gokv.Store interface to allow different storage backends for caching JWT tokens between client sessions.

func NewFileAuthStore

func NewFileAuthStore(dir string) (AuthStore, error)

NewFileAuthStore creates a new file-based authentication token store. The dir parameter specifies the directory where token files will be stored. Each username will have its own file within this directory.

type CashBalance added in v0.5.0

type CashBalance struct {
	ID            int     `json:"id"`
	AccountNumber string  `json:"rekening"`
	BankID        string  `json:"bank"`
	Currency      string  `json:"currCode"`
	Balance       float64 `json:"saldo"`
	BalanceIDR    float64 `json:"saldoIdr"`
	Status        int     `json:"status"`
}

CashBalance represents a cash balance in a specific account and currency.

func (*CashBalance) CurrentBalance added in v0.5.0

func (c *CashBalance) CurrentBalance() float64

CurrentBalance returns the current balance, choosing the maximum between Balance and BalanceIDR.

type CashBalanceResponse added in v0.5.0

type CashBalanceResponse struct {
	Data []CashBalance `json:"data"`
}

CashBalanceResponse represents the response from the cash balance API endpoint.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides access to the KSEI (Indonesian Central Securities Depository) API. It handles authentication, token management, and provides methods to retrieve portfolio information including cash balances, share holdings, and account details. It uses singleflight to prevent duplicate concurrent requests to the same endpoint.

func NewClient

func NewClient(opts ClientOpts) *Client

NewClient creates a new KSEI API client with the provided options. The client will use the provided AuthStore for token caching and automatic re-authentication.

func (*Client) Get added in v0.5.0

func (c *Client) Get(path string, dst any) error

Get performs an authenticated GET request to the specified API path and decodes the JSON response into dst. It automatically handles authentication and token refresh. Uses singleflight to prevent duplicate concurrent requests to the same endpoint.

func (*Client) GetCashBalances added in v0.5.0

func (c *Client) GetCashBalances() (*CashBalanceResponse, error)

GetCashBalances retrieves detailed cash balance information across all accounts, including different currencies and custodian banks.

func (*Client) GetGlobalIdentity

func (c *Client) GetGlobalIdentity() (*GlobalIdentityResponse, error)

GetGlobalIdentity retrieves detailed account and identity information including investor ID, tax numbers, and other personal details.

func (*Client) GetPortfolioSummary

func (c *Client) GetPortfolioSummary() (*PortfolioSummaryResponse, error)

GetPortfolioSummary retrieves a summary of all portfolio holdings including total values and breakdown by asset type (equity, mutual funds, bonds, etc.).

func (*Client) GetShareBalances

func (c *Client) GetShareBalances(portfolioType PortfolioType) (*ShareBalanceResponse, error)

GetShareBalances retrieves detailed share/security holdings for the specified portfolio type. Valid portfolio types are EquityType, MutualFundType, BondType, and OtherType. Use GetCashBalances() for cash holdings instead.

func (*Client) SetAuth

func (c *Client) SetAuth(username, password string)

SetAuth updates the client's authentication credentials. This will invalidate any cached tokens and require re-authentication on the next API call.

func (*Client) SetBaseURL added in v0.10.0

func (c *Client) SetBaseURL(baseURL string)

SetBaseURL updates the base URL for API requests. This is primarily useful for testing or if KSEI changes their API endpoint.

func (*Client) SetPlainPassword added in v0.10.0

func (c *Client) SetPlainPassword(plainPassword bool)

SetPlainPassword configures whether the password should be automatically hashed. When true, the client will hash plain text passwords using KSEI's hashing service. When false, the password is expected to be pre-hashed.

func (*Client) SetTimeout added in v0.11.0

func (c *Client) SetTimeout(timeout time.Duration)

SetTimeout configures the HTTP request timeout for all API calls. A timeout of 0 means no timeout. The default timeout is 30 seconds.

type ClientOpts

type ClientOpts struct {
	AuthStore     AuthStore // directory path to store cached authentication data
	Username      string
	Password      string
	PlainPassword bool
	Timeout       time.Duration // HTTP request timeout (default: 30s)
}

ClientOpts contains configuration options for creating a new Client.

type CustodianBank added in v0.5.0

type CustodianBank struct {
	Code string
	Name string
}

CustodianBank contains information about a custodian bank including its code and full name.

func CustodianBankByCode added in v0.7.1

func CustodianBankByCode(code string) (custodianBank *CustodianBank, ok bool)

CustodianBankByCode looks up a custodian bank by its code. The function strips numeric suffixes from codes for matching. Returns the bank information and true if found, nil and false otherwise.

func CustodianBanks added in v0.7.0

func CustodianBanks() []CustodianBank

CustodianBanks returns all custodian bank data sorted by code. The data is loaded from embedded CSV files from the KSEI website.

type GlobalIdentity

type GlobalIdentity struct {
	LoginID  string `json:"idLogin"`
	Username string `json:"username"`
	Email    string `json:"email"`
	Phone    string `json:"phone"`
	FullName string `json:"fullName"`

	InvestorID   string `json:"investorId"`
	InvestorName string `json:"sidName"`
	CitizenID    string `json:"nikId"`
	PassportID   string `json:"passportId"`
	TaxID        string `json:"npwp"`   // Indonesian Tax number (NPWP)
	CardID       string `json:"cardId"` // KSEI card ID
}

GlobalIdentity contains detailed identity information for a user account.

type GlobalIdentityResponse

type GlobalIdentityResponse struct {
	Code       string
	Status     string
	Identities []GlobalIdentity
}

GlobalIdentityResponse represents the response from the global identity API endpoint.

type LoginRequest

type LoginRequest struct {
	ID       string `json:"id"`
	AppType  string `json:"appType"`
	Username string `json:"username"`
	Password string `json:"password"`
}

LoginRequest represents the request payload for the login API endpoint.

type LoginResponse

type LoginResponse struct {
	Validation string `json:"validation"`
}

LoginResponse represents the response from the login API endpoint.

type MutualFund added in v0.4.0

type MutualFund struct {
	Code              string
	ProductName       string
	FundType          string
	InvestmentManager string
}

MutualFund contains information about a mutual fund product including its code, name, type, and investment manager.

func MutualFundByCode added in v0.4.0

func MutualFundByCode(code string) (mutualFund *MutualFund, ok bool)

MutualFundByCode looks up a mutual fund by its code. Returns the mutual fund information and true if found, nil and false otherwise.

func MutualFunds added in v0.7.0

func MutualFunds() []MutualFund

MutualFunds returns all mutual fund data sorted by code. The data is loaded from embedded CSV files containing OJK and KSEI mutual fund information.

type PortfolioSummaryDetails

type PortfolioSummaryDetails struct {
	Type    string  `json:"type"`
	Amount  float64 `json:"summaryAmount"`
	Percent float64 `json:"percent"`
}

PortfolioSummaryDetails contains detailed information about a specific portfolio type.

type PortfolioSummaryResponse

type PortfolioSummaryResponse struct {
	Total   float64                   `json:"summaryValue"`
	Details []PortfolioSummaryDetails `json:"summaryResponse"`
}

PortfolioSummaryResponse represents the response from the portfolio summary API endpoint.

type PortfolioType

type PortfolioType string

PortfolioType represents the type of portfolio asset (equity, mutual fund, cash, bond, or other).

var (
	// EquityType represents stock/equity portfolios.
	EquityType PortfolioType = "EKUITAS"

	// MutualFundType represents mutual fund portfolios.
	MutualFundType PortfolioType = "REKSADANA"

	// CashType represents cash balances.
	CashType PortfolioType = "KAS"

	// BondType represents bond portfolios.
	BondType PortfolioType = "OBLIGASI"

	// OtherType represents other types of portfolios.
	OtherType PortfolioType = "LAINNYA"
)

Predefined portfolio types used by the KSEI API.

func (PortfolioType) Name

func (t PortfolioType) Name() string

Name returns a lowercase English name for the portfolio type.

type ShareBalance

type ShareBalance struct {
	Account      string  `json:"rekening"`   // Security account number. Example: "XL001CANE000000"
	FullName     string  `json:"efek"`       // Name of the asset. Example: "GOTO - GOTO GOJEK TOKOPEDIA Tbk"
	Participant  string  `json:"partisipan"` // Security or Asset Management name. Example: "MAHAKARYA ARTHA SEKURITAS, PT "
	BalanceType  string  `json:"tipeSaldo"`  // Example: "available"
	Currency     string  `json:"curr"`       // Example: "IDR"
	Amount       float64 `json:"jumlah"`     // units owned
	ClosingPrice float64 `json:"harga"`      // last closing price
	// contains filtered or unexported fields
}

ShareBalance represents a balance of shares/securities in a specific account.

func (*ShareBalance) CurrentValue

func (c *ShareBalance) CurrentValue() float64

CurrentValue calculates the current market value by multiplying Amount by ClosingPrice.

func (*ShareBalance) Name added in v0.3.1

func (c *ShareBalance) Name() string

Name extracts the security name from the FullName field (part after " - ").

func (*ShareBalance) Symbol

func (c *ShareBalance) Symbol() string

Symbol extracts the security symbol from the FullName field (part before " - ").

func (*ShareBalance) Valid

func (c *ShareBalance) Valid() bool

Valid returns true if the share balance has required fields (Account and FullName).

type ShareBalanceResponse

type ShareBalanceResponse struct {
	Total float64        `json:"summaryValue"`
	Data  []ShareBalance `json:"data"`
}

ShareBalanceResponse represents the response from the share balance API endpoint.

func (*ShareBalanceResponse) RemoveInvalidData

func (r *ShareBalanceResponse) RemoveInvalidData()

RemoveInvalidData removes invalid entries from the share balance data in-place.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL