siftingio

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: May 24, 2026 License: MIT Imports: 15 Imported by: 0

README

siftingio (Go)

Official Go SDK for the SiftingIO market data API — REST plus a live WebSocket client, idiomatic and context-aware.

  • context.Context everywhere, functional options, typed structs.
  • Resource-mapped. Method names mirror the API docs 1:1.
  • Batteries included. Auto-retry on 429/5xx, transparent gzip, cursor auto-pagination via Go 1.23 iterators, and an auto-reconnecting WebSocket client.
  • One dependencygithub.com/coder/websocket (REST uses only the standard library).

Install

go get github.com/siftingio/sdk-go@latest

Requires Go 1.23+ (for range-over-func pagination).

Quick start

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	siftingio "github.com/siftingio/sdk-go"
)

func main() {
	client := siftingio.New(siftingio.WithAPIKey(os.Getenv("SIFTING_API_KEY")))
	ctx := context.Background()

	trade, err := client.Last.Trade(ctx, "crypto", "BTCUSD")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(trade.Price, trade.Time)

	profile, _ := client.Stocks.Profile(ctx, "AAPL")
	fmt.Println(profile.Name, profile.SICDescription)

	bars, _ := client.Crypto.Bars(ctx, "BTCUSD", &siftingio.BarsParams{Start: "2024-01-01", Interval: "1h"})
	fmt.Printf("%d bars\n", len(bars.Data))
}

The import path is github.com/siftingio/sdk-go; the package name is siftingio. Add an explicit alias (siftingio "github.com/siftingio/sdk-go") if your tooling wants it.

Configuration

client := siftingio.New(
	siftingio.WithAPIKey("sft_..."),                 // X-API-Key header
	siftingio.WithAPIKeyProvider(func(ctx context.Context) (string, error) { // dynamic alternative
		return fetchToken(ctx)
	}),
	siftingio.WithBaseURL("https://api.sifting.io"), // override for proxies/staging
	siftingio.WithWSURL("wss://stream.sifting.io/ws/v1"),
	siftingio.WithHTTPClient(myHTTPClient),           // custom *http.Client
	siftingio.WithTimeout(30*time.Second),            // per-request timeout (via context)
	siftingio.WithMaxRetries(2),                      // retries for 429 / 5xx
	siftingio.WithHeader("X-Trace", "..."),           // header on every request
)

Resources

Field Endpoints Highlights
client.Last /v1/last/* Trade, Quote, TVL — live snapshots
client.Stocks /v1/fnd/stocks/*, /v1/hist/stocks/* Search, Profile, Filings, Financials, Ratios, Insiders, Events, Screener, Bars, …
client.Filers /v1/fnd/filers/* Holdings — 13F positions
client.Markets /v1/fnd/markets/* List, Status, Hours, Calendar
client.Forex /v1/hist/forex/* Bars
client.Crypto /v1/hist/crypto/* Bars
client.Dex /v1/fnd/dex/* Wallet portfolios
client.EconomicCalendar /v1/fnd/economic-calendar List

Pagination

List endpoints return a *ListResponse[T] with Meta.NextCursor. Stream every page with the AutoPaginate iterator (Go 1.23+):

for filing, err := range siftingio.AutoPaginate(ctx,
	func(ctx context.Context, cursor string) ([]siftingio.Filing, string, error) {
		page, err := client.Stocks.Filings(ctx, "AAPL", &siftingio.FilingsParams{Cursor: cursor, Form: "10-K"})
		if err != nil {
			return nil, "", err
		}
		return page.Data, page.Meta.NextCursor, nil
	},
) {
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(filing.Accession, filing.FiledAt)
}

siftingio.CollectAll(...) gathers all pages into a slice.

Live WebSocket

sock := client.WS() // siftingio.WithAutoReconnect(false) to disable

sock.OnTick(func(t *siftingio.Tick) { fmt.Println(t.Symbol, t.Price) })
sock.OnTVL(func(v *siftingio.TVLUpdate) { fmt.Println(v.Symbol, v.USD) })
sock.OnError(func(e *siftingio.WSError) { log.Println("server error:", e.Code, e.Message) })
sock.OnReconnect(func(attempt int) { log.Println("reconnecting", attempt) })

if err := sock.Connect(ctx); err != nil {
	log.Fatal(err)
}
defer sock.Close()

sock.Subscribe(ctx, siftingio.ProductCEX, "BTCUSD", "ETHUSD") // cex|dex|fx|us|tvl
sock.Subscribe(ctx, siftingio.ProductTVL, "eth:WETH-USDC")

<-ctx.Done()

Subscriptions are tracked and replayed automatically on reconnect. Handlers run on the read goroutine — keep them quick or hand work to your own channels/goroutines.

Error handling

trade, err := client.Last.Trade(ctx, "crypto", "BTCUSD")
if err != nil {
	var apiErr *siftingio.APIError
	if errors.As(err, &apiErr) {
		// apiErr.Status, apiErr.Code, apiErr.RetryAfter, apiErr.RequestID, apiErr.Body
	}
	var connErr *siftingio.ConnectionError
	if errors.As(err, &connErr) {
		// connErr.Timeout, connErr.Err
	}
}

The client automatically retries 429 and 5xx up to WithMaxRetries, honoring Retry-After.

License

MIT

Documentation

Overview

Package siftingio is the official Go SDK for the SiftingIO market data API (https://sifting.io/docs) — REST plus a live WebSocket client.

Create a client with an API key and call resource methods, each of which takes a context.Context:

client := siftingio.New(siftingio.WithAPIKey(os.Getenv("SIFTING_API_KEY")))

trade, err := client.Last.Trade(ctx, "crypto", "BTCUSD")
profile, err := client.Stocks.Profile(ctx, "AAPL")

Resources mirror the API URL structure, so the docs map 1:1 onto methods: Last (live), Stocks, Filers, Markets, Forex, Crypto, Dex, and EconomicCalendar. Paginated list endpoints pair with AutoPaginate/CollectAll.

The client wraps the data-plane (API-key) endpoints only; account/billing (the /ops/v1 control plane) is intentionally out of scope.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AutoPaginate

func AutoPaginate[T any](
	ctx context.Context,
	fetch func(ctx context.Context, cursor string) (items []T, nextCursor string, err error),
) iter.Seq2[T, error]

AutoPaginate walks every page of a cursor-based endpoint, yielding items one at a time and fetching the next page transparently. The fetch closure receives the cursor (empty for the first page) and returns the page's items plus the next cursor ("" when there are no more pages).

for filing, err := range siftingio.AutoPaginate(ctx,
	func(ctx context.Context, cursor string) ([]siftingio.Filing, string, error) {
		page, err := client.Stocks.Filings(ctx, "AAPL", &siftingio.FilingsParams{Cursor: cursor, Form: "10-K"})
		if err != nil {
			return nil, "", err
		}
		return page.Data, page.Meta.NextCursor, nil
	},
) {
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(filing.Accession)
}
Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	siftingio "github.com/siftingio/sdk-go"
)

func main() {
	client := siftingio.New(siftingio.WithAPIKey(os.Getenv("SIFTING_API_KEY")))
	ctx := context.Background()

	for filing, err := range siftingio.AutoPaginate(ctx,
		func(ctx context.Context, cursor string) ([]siftingio.Filing, string, error) {
			page, err := client.Stocks.Filings(ctx, "AAPL", &siftingio.FilingsParams{Cursor: cursor, Form: "10-K"})
			if err != nil {
				return nil, "", err
			}
			return page.Data, page.Meta.NextCursor, nil
		},
	) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(filing.Accession, filing.FiledAt)
	}
}

func CollectAll

func CollectAll[T any](
	ctx context.Context,
	fetch func(ctx context.Context, cursor string) (items []T, nextCursor string, err error),
) ([]T, error)

CollectAll gathers every page of a cursor-based endpoint into a single slice. Mind the memory cost on large result sets; prefer AutoPaginate to stream.

Types

type APIError

type APIError struct {
	// Status is the HTTP status code (e.g. 401, 404, 429).
	Status int
	// Code is the machine-readable code from the response body's "error" field.
	Code string
	// Message is the human-readable detail, when provided.
	Message string
	// RequestID is the X-Request-Id response header, if present.
	RequestID string
	// RetryAfter is the number of seconds to wait before retrying (429), if known.
	RetryAfter float64
	// Body is the full parsed error body, including any non-standard fields.
	Body map[string]any
}

APIError is returned when the API responds with a non-2xx status. Inspect Code for the machine-readable reason and Status for the HTTP status.

func (*APIError) Error

func (e *APIError) Error() string

type Bar

type Bar struct {
	Time   int64   `json:"t"`
	Open   float64 `json:"o"`
	High   float64 `json:"h"`
	Low    float64 `json:"l"`
	Close  float64 `json:"c"`
	Volume float64 `json:"v"`
}

Bar is one OHLCV bar. Time is the bar's open time in Unix epoch milliseconds.

type BarsMeta

type BarsMeta struct {
	AsOf       string `json:"as_of"`
	NextCursor string `json:"next_cursor,omitempty"`
	Symbol     string `json:"symbol"`
	// Interval is the observed interval (may differ from requested for some venues).
	Interval string `json:"interval"`
}

BarsMeta is the meta block on /v1/hist/* bar responses.

type BarsParams

type BarsParams struct {
	// Start is the inclusive lower bound: YYYY-MM-DD or RFC3339. Required for
	// forex and crypto; optional for stocks.
	Start string
	// End is the inclusive upper bound. Defaults to now.
	End string
	// Interval is one of 1m, 5m, 15m, 30m, 1h. Default 1m.
	Interval string
	// Limit is bars per page. Each venue documents its own default and max.
	Limit int
	// Cursor is an opaque pagination cursor.
	Cursor string
}

BarsParams are the shared query params for historical bar endpoints.

type BarsResponse

type BarsResponse struct {
	Data []Bar    `json:"data"`
	Meta BarsMeta `json:"meta"`
}

BarsResponse is the OHLCV bars envelope.

type CalendarDay

type CalendarDay struct {
	Date       string `json:"date"`
	Name       string `json:"name"`
	Kind       string `json:"kind"`
	State      string `json:"state"`
	EarlyClose string `json:"early_close,omitempty"`
}

CalendarDay is a holiday or half-day on a market calendar.

type CalendarParams

type CalendarParams struct {
	From string // YYYY-MM-DD, default today
	To   string // YYYY-MM-DD, default from+90d, max range 730d
}

CalendarParams are query params for Calendar.

type Client

type Client struct {

	// Last is live market data: /v1/last/*.
	Last *LastService
	// Stocks is US equities fundamentals + history: /v1/fnd/stocks/*, /v1/hist/stocks/*.
	Stocks *StocksService
	// Filers is 13F institutional holdings: /v1/fnd/filers/*.
	Filers *FilersService
	// Markets is the market catalog, status, hours, calendars: /v1/fnd/markets/*.
	Markets *MarketsService
	// Forex is FX OHLC bars: /v1/hist/forex/*.
	Forex *ForexService
	// Crypto is crypto OHLCV bars: /v1/hist/crypto/*.
	Crypto *CryptoService
	// Dex is on-chain wallet portfolios: /v1/fnd/dex/*.
	Dex *DexService
	// EconomicCalendar is US macro events: /v1/fnd/economic-calendar.
	EconomicCalendar *EconomicCalendarService
	// contains filtered or unexported fields
}

Client is the SiftingIO API client. Construct it with New and use the resource fields (Last, Stocks, …). It is safe for concurrent use.

Example (Rest)
package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"os"

	siftingio "github.com/siftingio/sdk-go"
)

func main() {
	client := siftingio.New(siftingio.WithAPIKey(os.Getenv("SIFTING_API_KEY")))
	ctx := context.Background()

	trade, err := client.Last.Trade(ctx, "crypto", "BTCUSD")
	if err != nil {
		var apiErr *siftingio.APIError
		if errors.As(err, &apiErr) {
			log.Fatalf("api error %d %s", apiErr.Status, apiErr.Code)
		}
		log.Fatal(err)
	}
	fmt.Println(trade.Symbol, trade.Price)
}

func New

func New(opts ...Option) *Client

New creates a Client. Pass WithAPIKey (or WithAPIKeyProvider) to authenticate.

func (*Client) WS

func (c *Client) WS(opts ...SocketOption) *Socket

WS creates a live WebSocket client bound to this client's key and WS URL.

type CompanyProfile

type CompanyProfile struct {
	Ticker         string   `json:"ticker"`
	CIK            string   `json:"cik"`
	Name           string   `json:"name"`
	Exchanges      []string `json:"exchanges,omitempty"`
	OtherTickers   []string `json:"other_tickers,omitempty"`
	SICCode        string   `json:"sic_code,omitempty"`
	SICDescription string   `json:"sic_description,omitempty"`
	EntityType     string   `json:"entity_type,omitempty"`
	FiscalYearEnd  string   `json:"fiscal_year_end,omitempty"` // MMDD
}

CompanyProfile is a company profile from SEC submissions metadata.

type CompensationFiling

type CompensationFiling struct {
	Form               string `json:"form"`
	Accession          string `json:"accession"`
	FiledAt            string `json:"filed_at"`
	PeriodEnd          string `json:"period_end,omitempty"`
	PrimaryDocumentURL string `json:"primary_document_url,omitempty"`
}

CompensationFiling is a DEF 14A proxy/compensation filing.

type ConceptBlock

type ConceptBlock struct {
	Taxonomy    string        `json:"taxonomy"`
	Concept     string        `json:"concept"`
	Label       string        `json:"label,omitempty"`
	Description string        `json:"description,omitempty"`
	Series      []MetricValue `json:"series"`
}

ConceptBlock is a concept and its full reported time series.

type ConnectionError

type ConnectionError struct {
	// Err is the underlying cause.
	Err error
	// Timeout reports whether the failure was a deadline/timeout.
	Timeout bool
}

ConnectionError wraps a transport-level failure (network error or timeout) that produced no HTTP response. Use errors.As to detect it.

func (*ConnectionError) Error

func (e *ConnectionError) Error() string

func (*ConnectionError) Unwrap

func (e *ConnectionError) Unwrap() error

type CryptoService

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

CryptoService accesses historical OHLCV bars for USD-quoted crypto symbols: /v1/hist/crypto/*. Volume is fractional base-asset volume. Requires gzip.

When Start predates all upstreams' coverage the API returns HTTP 422 with code "data_unavailable"; the *APIError's Body["earliest"] holds the earliest available date.

func (*CryptoService) Bars

func (s *CryptoService) Bars(ctx context.Context, symbol string, params *BarsParams) (*BarsResponse, error)

Bars returns OHLCV bars for a crypto symbol, e.g. Bars(ctx, "BTCUSD", &BarsParams{Start: "2024-01-01"}). Start is required; the Limit cap here is 5000 (higher than other venues).

type DexService

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

DexService accesses on-chain wallet portfolios: /v1/fnd/dex/*.

func (*DexService) Wallet

func (s *DexService) Wallet(ctx context.Context, chain, address string) (*WalletPortfolio, error)

Wallet returns the token holdings for a wallet on a chain, e.g. Wallet(ctx, "eth", "0x...").

type DiffPair

type DiffPair struct {
	Before string `json:"before"`
	After  string `json:"after"`
}

DiffPair is a before/after pair in a section diff.

type EconomicCalendarParams

type EconomicCalendarParams struct {
	From    string // YYYY-MM-DD or RFC3339, default now
	To      string // default from+30d
	Country string // default US
	Impact  string // low | medium | high
	Agency  string // BLS | BEA | Census | Fed | DOL | EIA
	EventID string // e.g. us_cpi
	Limit   int    // 1–500, default 100
}

EconomicCalendarParams are query params for List.

type EconomicCalendarResponse

type EconomicCalendarResponse struct {
	Events []EconomicEvent `json:"events"`
	Count  int             `json:"count"`
	Filter map[string]any  `json:"filter"`
}

EconomicCalendarResponse is the economic-calendar payload.

type EconomicCalendarService

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

EconomicCalendarService accesses US macro events: /v1/fnd/economic-calendar.

func (*EconomicCalendarService) List

List queries the economic calendar. GET /v1/fnd/economic-calendar.

type EconomicEvent

type EconomicEvent struct {
	EventID     string   `json:"event_id"`
	Name        string   `json:"name"`
	Country     string   `json:"country"`
	Currency    string   `json:"currency"`
	Agency      string   `json:"agency"`
	Impact      string   `json:"impact"`
	ScheduledAt string   `json:"scheduled_at"`
	Actual      *float64 `json:"actual"`
	Previous    *float64 `json:"previous"`
	Consensus   *float64 `json:"consensus"`
	ReleasedAt  *string  `json:"released_at"`
}

EconomicEvent is a scheduled or released economic event. Actual/Previous/ Consensus are nil until known; ReleasedAt is nil while pending.

type EventFiling

type EventFiling struct {
	Accession          string   `json:"accession"`
	FiledAt            string   `json:"filed_at"`
	AcceptedAt         string   `json:"accepted_at,omitempty"`
	Items              []string `json:"items"`
	PrimaryDocumentURL string   `json:"primary_document_url,omitempty"`
	Description        string   `json:"description,omitempty"`
}

EventFiling is an 8-K material event or earnings-release filing.

type EventsParams

type EventsParams struct {
	Item   string // 8-K item code filter, e.g. "2.02"
	Cursor string
	Limit  int
}

EventsParams are query params for Events.

type FilersService

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

FilersService accesses 13F institutional holdings: /v1/fnd/filers/*.

func (*FilersService) Holdings

func (s *FilersService) Holdings(ctx context.Context, filer string, params *PageParams) (*Holdings, error)

Holdings returns the latest 13F-HR positions for an institutional filer. The filer argument accepts a CIK (numeric) or a ticker.

type Filing

type Filing struct {
	Accession          string `json:"accession"`
	Form               string `json:"form"`
	FiledAt            string `json:"filed_at"`
	PeriodEnd          string `json:"period_end,omitempty"`
	AcceptedAt         string `json:"accepted_at,omitempty"`
	Items              string `json:"items,omitempty"`
	PrimaryDocumentURL string `json:"primary_document_url,omitempty"`
	Description        string `json:"description,omitempty"`
	HasXBRL            bool   `json:"has_xbrl"`
}

Filing is a SEC filing summary.

type FilingDetail

type FilingDetail struct {
	Filing
	Ticker     string   `json:"ticker"`
	CIK        string   `json:"cik"`
	ArchiveURL string   `json:"archive_url"`
	Files      []string `json:"files,omitempty"`
}

FilingDetail is a single filing's detail, including its document file list.

type FilingRef

type FilingRef struct {
	Accession string `json:"accession"`
	Form      string `json:"form"`
	FiledAt   string `json:"filed_at"`
	PeriodEnd string `json:"period_end,omitempty"`
}

FilingRef is a lightweight reference to a filing.

type FilingSection

type FilingSection struct {
	Section string `json:"section"`
	Content string `json:"content"`
}

FilingSection is one extracted text section of a filing.

type FilingSectionDetail

type FilingSectionDetail struct {
	Ticker    string `json:"ticker"`
	CIK       string `json:"cik"`
	Accession string `json:"accession"`
	Form      string `json:"form"`
	FiledAt   string `json:"filed_at"`
	Section   string `json:"section"`
	Content   string `json:"content"`
}

FilingSectionDetail is a single section's full text.

type FilingSections

type FilingSections struct {
	Ticker    string          `json:"ticker"`
	CIK       string          `json:"cik"`
	Accession string          `json:"accession"`
	Form      string          `json:"form"`
	FiledAt   string          `json:"filed_at"`
	Sections  []FilingSection `json:"sections"`
}

FilingSections holds all extracted sections of a filing.

type FilingsParams

type FilingsParams struct {
	Form   string // comma-separated exact forms, e.g. "10-K,10-Q"
	From   string // YYYY-MM-DD lower bound on filed_at
	To     string // YYYY-MM-DD upper bound
	Cursor string
	Limit  int
}

FilingsParams are query params for Filings.

type FinancialConcept

type FinancialConcept struct {
	Ticker      string        `json:"ticker"`
	CIK         string        `json:"cik"`
	Taxonomy    string        `json:"taxonomy"`
	Concept     string        `json:"concept"`
	Label       string        `json:"label,omitempty"`
	Description string        `json:"description,omitempty"`
	Series      []MetricValue `json:"series"`
}

FinancialConcept is a single concept's time series for a company.

type FinancialRatio

type FinancialRatio struct {
	FiscalYear      int      `json:"fiscal_year"`
	FiscalPeriod    string   `json:"fiscal_period"`
	PeriodEnd       string   `json:"period_end"`
	Form            string   `json:"form"`
	Accession       string   `json:"accession"`
	GrossMargin     *float64 `json:"gross_margin,omitempty"`
	OperatingMargin *float64 `json:"operating_margin,omitempty"`
	NetMargin       *float64 `json:"net_margin,omitempty"`
	ReturnOnEquity  *float64 `json:"return_on_equity,omitempty"`
	ReturnOnAssets  *float64 `json:"return_on_assets,omitempty"`
	DebtToEquity    *float64 `json:"debt_to_equity,omitempty"`
	CurrentRatio    *float64 `json:"current_ratio,omitempty"`
	QuickRatio      *float64 `json:"quick_ratio,omitempty"`
	AssetTurnover   *float64 `json:"asset_turnover,omitempty"`
	FreeCashFlow    *float64 `json:"free_cash_flow,omitempty"`
	FCFMargin       *float64 `json:"fcf_margin,omitempty"`
}

FinancialRatio holds fundamental ratios for one fiscal period. Ratio fields are pointers and are nil when not computable.

type Financials

type Financials struct {
	Ticker   string         `json:"ticker"`
	CIK      string         `json:"cik"`
	Name     string         `json:"name"`
	Concepts []ConceptBlock `json:"concepts"`
}

Financials is the full XBRL bundle for a company.

type ForexService

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

ForexService accesses historical OHLC bars for FX pairs: /v1/hist/forex/*. Volume is always 0 for OTC spot forex. Requires gzip (handled automatically).

func (*ForexService) Bars

func (s *ForexService) Bars(ctx context.Context, pair string, params *BarsParams) (*BarsResponse, error)

Bars returns OHLC bars for a 6-char FX pair, e.g. Bars(ctx, "EURUSD", &BarsParams{Start: "2024-01-01"}). Start is required.

type ForexSession

type ForexSession struct {
	Name  string `json:"name"`
	Start string `json:"start"`
	End   string `json:"end"`
}

ForexSession is a named forex trading session (UTC, HH:MM).

type HoldingPosition

type HoldingPosition struct {
	Issuer       string  `json:"issuer"`
	SecurityType string  `json:"security_type"`
	CUSIP        string  `json:"cusip"`
	ValueUSD     float64 `json:"value_usd"`
	Shares       float64 `json:"shares"`
	SharesType   string  `json:"shares_type"`
	Discretion   string  `json:"discretion"`
}

HoldingPosition is one position in a 13F-HR filing.

type Holdings

type Holdings struct {
	FilerCIK      string            `json:"filer_cik"`
	FilerName     string            `json:"filer_name,omitempty"`
	Accession     string            `json:"accession"`
	FiledAt       string            `json:"filed_at"`
	PeriodEnd     string            `json:"period_end"`
	TotalValueUSD float64           `json:"total_value_usd"`
	Positions     []HoldingPosition `json:"positions"`
	Meta          ListMeta          `json:"meta"`
}

Holdings is a 13F filer's latest reported positions. Positions paginate via Meta.

type HoursBreak

type HoursBreak struct {
	Open  string `json:"open"`
	Close string `json:"close"`
}

HoursBreak is an intra-session break (e.g. lunch).

type HoursSpec

type HoursSpec struct {
	Open   string       `json:"open"`
	Close  string       `json:"close"`
	Breaks []HoursBreak `json:"breaks,omitempty"`
}

HoursSpec is a session's open/close (venue local, HH:MM).

type InsiderTransaction

type InsiderTransaction struct {
	Accession              string   `json:"accession"`
	FiledAt                string   `json:"filed_at"`
	Reporter               string   `json:"reporter"`
	ReporterCIK            string   `json:"reporter_cik"`
	Roles                  []string `json:"roles"`
	OfficerTitle           string   `json:"officer_title,omitempty"`
	Security               string   `json:"security"`
	TransactionDate        string   `json:"transaction_date"`
	TransactionCode        string   `json:"transaction_code"`
	TransactionDescription string   `json:"transaction_description"`
	Direction              string   `json:"direction"`
	Shares                 float64  `json:"shares"`
	PricePerShare          float64  `json:"price_per_share,omitempty"`
	NotionalUSD            float64  `json:"notional_usd,omitempty"`
	SharesOwnedAfter       float64  `json:"shares_owned_after"`
	Ownership              string   `json:"ownership"`
	Derivative             bool     `json:"derivative"`
}

InsiderTransaction is a Form 3/4/5 insider transaction.

type LastQuote

type LastQuote struct {
	Bid     string `json:"b"`
	BidSize string `json:"B"`
	Ask     string `json:"a"`
	AskSize string `json:"A"`
	Time    int64  `json:"t"`
}

LastQuote is the top-of-book quote.

type LastService

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

LastService accesses live market data: /v1/last/*.

func (*LastService) Quote

func (s *LastService) Quote(ctx context.Context, venue, symbol string) (*LastQuote, error)

Quote returns the top-of-book quote for a symbol on a venue.

func (*LastService) TVL

func (s *LastService) TVL(ctx context.Context, chain, pair string) (*LastTVL, error)

TVL returns aggregated TVL for a DEX pair, e.g. TVL(ctx, "eth", "WETH-USDC").

func (*LastService) Trade

func (s *LastService) Trade(ctx context.Context, venue, symbol string) (*LastTrade, error)

Trade returns the latest trade for a symbol on a venue (stocks, crypto, forex, dex).

type LastTVL

type LastTVL struct {
	Chain     string `json:"chain"`
	Pair      string `json:"pair"`
	USD       string `json:"usd"`
	Reserve0  string `json:"r0"`
	Reserve1  string `json:"r1"`
	PoolCount int    `json:"n"`
	Version   int    `json:"v"`
	Time      int64  `json:"t"`
}

LastTVL is aggregated DEX pool TVL for a chain/pair.

type LastTrade

type LastTrade struct {
	Symbol string `json:"s"`
	Price  string `json:"p"`
	Size   string `json:"P"`
	Time   int64  `json:"t"`
}

LastTrade is the latest trade snapshot. Price/Size are decimal strings (preserved exactly as published); Time is Unix epoch milliseconds.

type ListMeta

type ListMeta struct {
	// NextCursor is the cursor for the next page; empty when there is none.
	NextCursor string `json:"next_cursor,omitempty"`
	// AsOf is the RFC3339 timestamp of when the data was assembled.
	AsOf string `json:"as_of"`
	// Total is the count across all pages, when the endpoint computes it.
	Total *int `json:"total,omitempty"`
}

ListMeta is the meta block on paginated list endpoints.

type ListResponse

type ListResponse[T any] struct {
	Data []T      `json:"data"`
	Meta ListMeta `json:"meta"`
}

ListResponse is the envelope for paginated list endpoints: {data, meta}.

type Market

type Market struct {
	Market    string       `json:"market"`
	Name      string       `json:"name"`
	Type      string       `json:"type"`
	Timezone  string       `json:"timezone"`
	Region    string       `json:"region"`
	Exchanges []string     `json:"exchanges,omitempty"`
	Stats     *MarketStats `json:"stats,omitempty"`
}

Market is a supported market/venue in the catalog.

type MarketHours

type MarketHours struct {
	Market    string            `json:"market"`
	Type      string            `json:"type"`
	Timezone  string            `json:"timezone"`
	Hours     *MarketHoursBlock `json:"hours,omitempty"`
	OpensAt   string            `json:"opens_at,omitempty"`
	ClosesAt  string            `json:"closes_at,omitempty"`
	Sessions  []ForexSession    `json:"sessions,omitempty"`
	Exchanges []string          `json:"exchanges,omitempty"`
}

MarketHours is a market's trading-hours schedule. Exchange vs forex populate different fields.

type MarketHoursBlock

type MarketHoursBlock struct {
	Regular    *HoursSpec `json:"regular,omitempty"`
	PreMarket  *HoursSpec `json:"pre_market,omitempty"`
	PostMarket *HoursSpec `json:"post_market,omitempty"`
}

MarketHoursBlock holds an exchange's regular/pre/post sessions.

type MarketStats

type MarketStats struct {
	MarketCapUSD    int64  `json:"market_cap_usd"`
	ListedCompanies int    `json:"listed_companies"`
	Currency        string `json:"currency"`
	AsOf            string `json:"as_of"`
}

MarketStats are exchange-level statistics.

type MarketStatus

type MarketStatus struct {
	Market    string       `json:"market"`
	Type      string       `json:"type"`
	IsOpen    bool         `json:"is_open"`
	State     string       `json:"state"`
	Session   string       `json:"session,omitempty"`
	NextOpen  string       `json:"next_open,omitempty"`
	NextClose string       `json:"next_close,omitempty"`
	Timezone  string       `json:"timezone"`
	Stats     *MarketStats `json:"stats,omitempty"`
}

MarketStatus is the open/closed snapshot for one market.

type MarketsEnvelope

type MarketsEnvelope[T any] struct {
	Data T              `json:"data"`
	Meta map[string]any `json:"meta"`
}

MarketsEnvelope wraps markets responses: {data, meta}. Meta varies by endpoint (always carries as_of; calendar also carries market/from/to).

type MarketsService

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

MarketsService accesses the market catalog, status, hours and calendars: /v1/fnd/markets/*.

func (*MarketsService) Calendar

func (s *MarketsService) Calendar(ctx context.Context, market string, params *CalendarParams) (*MarketsEnvelope[[]CalendarDay], error)

Calendar returns the holiday/half-day calendar for a date range.

func (*MarketsService) Hours

Hours returns the weekly trading-hours schedule for a market.

func (*MarketsService) List

func (s *MarketsService) List(ctx context.Context, region string) (*MarketsEnvelope[[]Market], error)

List returns all supported markets. Pass region to filter (or "").

func (*MarketsService) Status

Status returns the open/closed snapshot for one market.

func (*MarketsService) StatusAll

func (s *MarketsService) StatusAll(ctx context.Context, region string) (*MarketsEnvelope[[]MarketStatus], error)

StatusAll returns the open/closed snapshot for every market.

type MetricValue

type MetricValue struct {
	Value        float64 `json:"value"`
	Unit         string  `json:"unit"`
	PeriodStart  string  `json:"period_start,omitempty"`
	PeriodEnd    string  `json:"period_end,omitempty"`
	FiscalYear   int     `json:"fiscal_year,omitempty"`
	FiscalPeriod string  `json:"fiscal_period,omitempty"`
	Form         string  `json:"form,omitempty"`
	Accession    string  `json:"accession,omitempty"`
	FiledAt      string  `json:"filed_at,omitempty"`
}

MetricValue is one XBRL fact: a value for a concept in a period.

type Option

type Option func(*Client)

Option configures a Client.

func WithAPIKey

func WithAPIKey(key string) Option

WithAPIKey sets the API key sent as the X-API-Key header.

func WithAPIKeyProvider

func WithAPIKeyProvider(f func(context.Context) (string, error)) Option

WithAPIKeyProvider sets a function resolving the API key per request. It takes precedence over WithAPIKey — useful for short-lived or rotating keys.

func WithBaseURL

func WithBaseURL(u string) Option

WithBaseURL overrides the REST base URL (no trailing /v1). Useful for proxies and staging. Default: https://api.sifting.io.

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient supplies a custom *http.Client (for proxies, transports, tests).

func WithHeader

func WithHeader(key, value string) Option

WithHeader adds a header sent on every request.

func WithMaxRetries

func WithMaxRetries(n int) Option

WithMaxRetries sets the number of automatic retries for 429 and 5xx responses.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the per-request timeout (applied via context). 0 disables it.

func WithWSURL

func WithWSURL(u string) Option

WithWSURL overrides the WebSocket URL. Default: wss://stream.sifting.io/ws/v1.

type OwnershipFiling

type OwnershipFiling struct {
	Form               string `json:"form"`
	Accession          string `json:"accession"`
	FiledAt            string `json:"filed_at"`
	PrimaryDocumentURL string `json:"primary_document_url,omitempty"`
	Description        string `json:"description,omitempty"`
}

OwnershipFiling is a Schedule 13D/13G beneficial-ownership filing.

type PageParams

type PageParams struct {
	Cursor string
	Limit  int
}

PageParams are the common cursor-pagination params.

type Ratios

type Ratios struct {
	Ticker  string           `json:"ticker"`
	CIK     string           `json:"cik"`
	Latest  *FinancialRatio  `json:"latest,omitempty"`
	History []FinancialRatio `json:"history"`
}

Ratios holds the latest ratios plus history (newest first).

type RiskFactorsDiff

type RiskFactorsDiff struct {
	Ticker   string      `json:"ticker"`
	CIK      string      `json:"cik"`
	Current  FilingRef   `json:"current"`
	Previous FilingRef   `json:"previous"`
	Diff     SectionDiff `json:"diff"`
}

RiskFactorsDiff is a year-over-year Item 1A comparison between two 10-Ks.

type ScreenerParams

type ScreenerParams struct {
	Taxonomy string // default "us-gaap"
	Unit     string // default "USD"
	Cursor   string
	Limit    int
}

ScreenerParams are query params for Screener.

type ScreenerResult

type ScreenerResult struct {
	Taxonomy string        `json:"taxonomy"`
	Concept  string        `json:"concept"`
	Period   string        `json:"period"`
	Unit     string        `json:"unit"`
	Label    string        `json:"label,omitempty"`
	Rows     []ScreenerRow `json:"rows"`
	Meta     ListMeta      `json:"meta"`
}

ScreenerResult is one concept/period across many companies.

type ScreenerRow

type ScreenerRow struct {
	CIK       string  `json:"cik"`
	Name      string  `json:"name"`
	Value     float64 `json:"value"`
	Unit      string  `json:"unit"`
	PeriodEnd string  `json:"period_end"`
	Accession string  `json:"accession"`
}

ScreenerRow is one company's value in a cross-sectional screen.

type SearchParams

type SearchParams struct {
	Limit int // default 25, max 100
}

SearchParams are query params for Search.

type SectionDiff

type SectionDiff struct {
	Added    []string         `json:"added"`
	Removed  []string         `json:"removed"`
	Modified []DiffPair       `json:"modified"`
	Stats    SectionDiffStats `json:"stats"`
}

SectionDiff is the diff between two filing sections.

type SectionDiffStats

type SectionDiffStats struct {
	BeforeParagraphs int `json:"before_paragraphs"`
	AfterParagraphs  int `json:"after_paragraphs"`
	UnchangedCount   int `json:"unchanged_count"`
	AddedCount       int `json:"added_count"`
	RemovedCount     int `json:"removed_count"`
	ModifiedCount    int `json:"modified_count"`
}

SectionDiffStats summarizes a section diff.

type Socket

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

Socket is a typed, auto-reconnecting WebSocket client for the live stream. Register handlers, call Connect, then Subscribe. Subscriptions are tracked and replayed on reconnect. Handlers run on the read goroutine; keep them quick or hand off to your own workers.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	siftingio "github.com/siftingio/sdk-go"
)

func main() {
	client := siftingio.New(siftingio.WithAPIKey(os.Getenv("SIFTING_API_KEY")))
	ctx := context.Background()

	sock := client.WS()
	sock.OnTick(func(t *siftingio.Tick) { fmt.Println(t.Symbol, t.Price) })
	if err := sock.Connect(ctx); err != nil {
		log.Fatal(err)
	}
	defer sock.Close()

	_ = sock.Subscribe(ctx, siftingio.ProductCEX, "BTCUSD", "ETHUSD")
	<-ctx.Done()
}

func (*Socket) Close

func (s *Socket) Close() error

Close stops the socket and any reconnection.

func (*Socket) Connect

func (s *Socket) Connect(ctx context.Context) error

Connect dials the server and starts the read/reconnect loop. It returns once the first connection is established (or fails).

func (*Socket) Connected

func (s *Socket) Connected() bool

Connected reports whether the socket currently has an open connection.

func (*Socket) OnAck

func (s *Socket) OnAck(f func(json.RawMessage)) *Socket

func (*Socket) OnClose

func (s *Socket) OnClose(f func()) *Socket

func (*Socket) OnError

func (s *Socket) OnError(f func(*WSError)) *Socket

func (*Socket) OnMessage

func (s *Socket) OnMessage(f func(json.RawMessage)) *Socket

func (*Socket) OnOpen

func (s *Socket) OnOpen(f func()) *Socket

func (*Socket) OnPong

func (s *Socket) OnPong(f func()) *Socket

func (*Socket) OnReconnect

func (s *Socket) OnReconnect(f func(int)) *Socket

func (*Socket) OnTVL

func (s *Socket) OnTVL(f func(*TVLUpdate)) *Socket

func (*Socket) OnTick

func (s *Socket) OnTick(f func(*Tick)) *Socket

func (*Socket) Ping

func (s *Socket) Ping(ctx context.Context) error

Ping sends an application-level ping; the server replies with a pong frame.

func (*Socket) Subscribe

func (s *Socket) Subscribe(ctx context.Context, product WSProduct, symbols ...string) error

Subscribe subscribes to symbols on a product channel. Safe to call before Connect or while disconnected — the request is tracked and (re)sent on open.

func (*Socket) Unsubscribe

func (s *Socket) Unsubscribe(ctx context.Context, product WSProduct, symbols ...string) error

Unsubscribe removes symbols from a product channel.

type SocketOption

type SocketOption func(*Socket)

SocketOption configures a Socket.

func WithAutoReconnect

func WithAutoReconnect(enabled bool) SocketOption

WithAutoReconnect toggles automatic reconnection (default true).

type StockSearchResult

type StockSearchResult struct {
	Ticker   string `json:"ticker"`
	Name     string `json:"name"`
	CIK      string `json:"cik"`
	Exchange string `json:"exchange,omitempty"`
}

StockSearchResult is one hit from the ticker/company search index.

type StocksService

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

StocksService accesses US-equity fundamentals and history: /v1/fnd/stocks/* and /v1/hist/stocks/*.

func (*StocksService) Bars

func (s *StocksService) Bars(ctx context.Context, ticker string, params *BarsParams) (*BarsResponse, error)

Bars returns historical OHLCV bars for a US equity. Requires gzip.

func (*StocksService) Compensation

func (s *StocksService) Compensation(ctx context.Context, ticker string, params *PageParams) (*ListResponse[CompensationFiling], error)

Compensation returns DEF 14A proxy/compensation filings, paginated.

func (*StocksService) Earnings

func (s *StocksService) Earnings(ctx context.Context, ticker string, params *PageParams) (*ListResponse[EventFiling], error)

Earnings returns earnings-release history (8-K item 2.02), paginated.

func (*StocksService) Events

func (s *StocksService) Events(ctx context.Context, ticker string, params *EventsParams) (*ListResponse[EventFiling], error)

Events returns 8-K material events, paginated.

func (*StocksService) Filing

func (s *StocksService) Filing(ctx context.Context, ticker, accession string) (*FilingDetail, error)

Filing returns one filing's detail. GET /v1/fnd/stocks/:ticker/filings/:accession.

func (*StocksService) Filings

func (s *StocksService) Filings(ctx context.Context, ticker string, params *FilingsParams) (*ListResponse[Filing], error)

Filings lists SEC filings (paginated). GET /v1/fnd/stocks/:ticker/filings.

func (*StocksService) FinancialConcept

func (s *StocksService) FinancialConcept(ctx context.Context, ticker, concept, taxonomy string) (*FinancialConcept, error)

FinancialConcept returns one XBRL concept across all periods. Requires gzip.

func (*StocksService) Financials

func (s *StocksService) Financials(ctx context.Context, ticker string) (*Financials, error)

Financials returns the full XBRL bundle. Requires gzip (handled automatically).

func (*StocksService) Insiders

func (s *StocksService) Insiders(ctx context.Context, ticker string, params *PageParams) (*ListResponse[InsiderTransaction], error)

Insiders returns Form 3/4/5 transactions (default limit 10, max 25).

func (*StocksService) Ownership

func (s *StocksService) Ownership(ctx context.Context, ticker string, params *PageParams) (*ListResponse[OwnershipFiling], error)

Ownership returns Schedule 13D/13G filings, paginated.

func (*StocksService) Profile

func (s *StocksService) Profile(ctx context.Context, ticker string) (*CompanyProfile, error)

Profile returns a company profile. GET /v1/fnd/stocks/:ticker/profile.

func (*StocksService) Ratios

func (s *StocksService) Ratios(ctx context.Context, ticker string) (*Ratios, error)

Ratios returns fundamental ratios (latest + history).

func (*StocksService) RiskFactorsDiff

func (s *StocksService) RiskFactorsDiff(ctx context.Context, ticker string) (*RiskFactorsDiff, error)

RiskFactorsDiff returns the year-over-year Item 1A diff.

func (*StocksService) Screener

func (s *StocksService) Screener(ctx context.Context, concept, period string, params *ScreenerParams) (*ScreenerResult, error)

Screener returns one concept/period across all filers. Requires gzip.

func (*StocksService) Search

Search looks up tickers/companies. GET /v1/fnd/stocks/search.

func (*StocksService) Section

func (s *StocksService) Section(ctx context.Context, ticker, accession, section string) (*FilingSectionDetail, error)

Section returns one extracted section's full text.

func (*StocksService) Sections

func (s *StocksService) Sections(ctx context.Context, ticker, accession string) (*FilingSections, error)

Sections returns all extracted text sections of a filing.

type TVLUpdate

type TVLUpdate struct {
	Symbol   string `json:"s"`
	USD      string `json:"usd"`
	Reserve0 string `json:"r0"`
	Reserve1 string `json:"r1"`
	Pools    int    `json:"n"`
	Time     int64  `json:"t"`
}

TVLUpdate is a TVL update frame for a DEX pool.

type Tick

type Tick struct {
	Symbol  string `json:"s"`
	Price   string `json:"p,omitempty"`
	Size    string `json:"P,omitempty"`
	Bid     string `json:"b,omitempty"`
	BidSize string `json:"B,omitempty"`
	Ask     string `json:"a,omitempty"`
	AskSize string `json:"A,omitempty"`
	Time    int64  `json:"t"`
	Class   string `json:"class,omitempty"`
}

Tick is a price update frame. Fields mirror the REST live shapes.

type WSError

type WSError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Limit   int    `json:"limit,omitempty"`
}

WSError is a server-side error frame.

type WSProduct

type WSProduct string

WSProduct is a subscribable product channel.

const (
	ProductCEX WSProduct = "cex"
	ProductDEX WSProduct = "dex"
	ProductFX  WSProduct = "fx"
	ProductUS  WSProduct = "us"
	ProductTVL WSProduct = "tvl"
)

type WalletPortfolio

type WalletPortfolio struct {
	Chain     string        `json:"chain"`
	Address   string        `json:"address"`
	Tokens    []WalletToken `json:"tokens"`
	Count     int           `json:"count"`
	UpdatedAt int64         `json:"updated_at"` // Unix epoch seconds
}

WalletPortfolio is a wallet's token holdings on a chain.

type WalletToken

type WalletToken struct {
	ContractAddress string `json:"contract_address,omitempty"`
	Symbol          string `json:"symbol"`
	Name            string `json:"name"`
	Decimals        int    `json:"decimals"`
	RawBalance      string `json:"raw_balance"`
	Balance         string `json:"balance"`
	Native          bool   `json:"native,omitempty"`
}

WalletToken is a single token balance in a wallet portfolio.

Jump to

Keyboard shortcuts

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