cabalspy-id package covers everything: the OpenID Connect login with PKCE and ID token verification, a typed Data API client with pagination helpers and retries, the live streams, token theses, webhook verification and, in TypeScript, the login button and thesis widget for the browser and React.
Packages
Need only part of it? Three smaller packages re-export parts ofcabalspy-id, with the same classes, behaviour and types. Their versions follow cabalspy-id.
Entry points
Insidecabalspy-id, import only what you use. Classes are shared between entry points.
Overview
The TypeScript SDK has no runtime dependencies and runs on Node 18+, browsers, Deno, Bun and edge runtimes, as ESM and CommonJS. The Python SDK needs Python 3.10+, has sync and async clients, and types every response withTypedDicts. The live stream in Python needs one extra: pip install "cabalspy-id[stream]".
Both read the Data API key from
CABALSPY_ID_API_KEY, then CABALSPY_API_KEY. It is the same key as the CabalSpy API with CabalSpy ID enabled, see Authentication.
Data API
If your account has several CabalSpy ID instances, pass
instance (the client_id) to the constructor. The Python async client works the same way with await:
Python async
Pagination
Iterators follownext_cursor for you.
Errors
Every failure is a subclass ofCabalSpyIDError with the error code, the HTTP status, the request id, a docs link to the error reference and, for validation errors, parameter and allowed. 429, 5xx and network errors are retried with exponential backoff (2 retries by default), and Retry-After is respected.
Live stream
Every trade of your users the moment it is indexed (Pro plan and up), see Trades stream. The client reconnects with exponential backoff after a dropped connection or when heartbeats stop. Configuration errors (invalid_api_key, plan_required, scope_not_allowed) are fatal and stop reconnecting.
trade, subscribed, heartbeat, open, close, reconnecting, error. Browsers, Deno, Bun and Node 22+ have a global WebSocket. On Node 18 to 21, install ws and pass it as csid.stream({ WebSocketImpl: WebSocket }).
Server-side login
Authorization code flow with PKCE S256, state and nonce, see OpenID Connect.handleCallback checks the error, state and issuer, exchanges the code and verifies the ID token and its nonce.
AsyncCabalSpyIDAuth in Python has the same methods as coroutines.
Verify an ID token
Browser apps let the login button run PKCE and receive anidToken. Send it to your backend and verify it there before you trust it.
React
cabalspy-id/react wraps the login button. <CabalSpyLogin> loads widget.js once and maps its props to the widget’s data-* attributes.
React
useCabalSpyID({ clientId }) returns { user, idToken, accessToken, limited, ready, login(), signOut() }.
Theses
Both SDKs cover token theses: the Data API endpoints, the theses stream (ThesesStream, every plan, see the chart markers cookbook), thesis events on the general stream, a client for the public browser API and, in TypeScript, the thesis widget. Writing needs the scope thesis in your login.
Data API
Reading works with any key. Writes happen in the name of one of your users, passed ascsid_id. Writes are retried only after the API’s own rate_limit_exceeded, never after a server or network error, so a post cannot be duplicated.
Stream
Passevents and optionally mint to receive thesis, thesis.reply, thesis.reaction and thesis.removed, or iterate stream.theses().
Public browser API: ThesisClient
ThesisClient wraps the browser API on id.cabalspy.xyz: no API key, open reads, writes with the user’s access token (scope thesis), and live() for the public per-token websocket. Python also has AsyncThesisClient.
list, iterate, summary, get, replies, byUser / by_user, me, post, reply, react, report, delete, live, setAccessToken / set_access_token.
React widget
<CabalSpyTheses> from cabalspy-id/react renders the thesis widget. Pass the signed-in user’s access token so they can write right away.
React
chain, mint, theme, height, radius, accessToken.
Webhooks
Pass the raw request body exactly as received. Deliveries older than 5 minutes are rejected, any signature of a secret roll is accepted, and the parsed event is returned. Deduplicate on the eventid. See Webhooks.
signWebhook() / sign_webhook() build signed test requests for your receiver.
More
TypeScript SDK on GitHub
Source, runnable examples for login, Data API, stream, webhooks and React.
Python SDK on GitHub
Source and runnable examples, sync and async.

