Official Python SDK for the Kresmion financial-intelligence API
Project description
Kresmion Python SDK
Official Python client for the Kresmion financial intelligence API: prediction markets, on-chain crypto flows, equities signals, macro regime, cross-market signals, and bulk historical data.
The SDK targets the versioned /v1 API. It depends only on the Python
standard library plus requests.
It returns data for you to work with; it never returns advice.
Version 0.2.1. Python 3.9 and newer.
Install
Two ways, pick one.
From PyPI:
pip install kresmion
Single file download (no packaging):
curl -O https://kresmion.com/sdk/kresmion.py
pip install "requests>=2.28"
Drop kresmion.py next to your script and import kresmion works.
Install from source (pip, from a git checkout):
pip install "git+https://github.com/kresmion/kresmion-python.git#subdirectory=sdk/python"
# or, from a local clone of the repo:
pip install ./sdk/python
Both forms expose the identical kresmion module. The single file is a
verbatim build of the package (build_singlefile.py keeps them in sync).
Quickstart
from kresmion import Kresmion
# api_key falls back to the KRESMION_API_KEY environment variable.
k = Kresmion(api_key="krm_your_key_here")
markets = k.prediction.markets(category="crypto", limit=10)
for m in markets:
print(m["question"], m.get("yes_probability"))
# List results are a plain list plus .count and .as_of metadata.
print("returned", len(markets), "of", markets.count, "as of", markets.as_of)
# Single-object results are a plain dict plus .as_of.
regime = k.macro.regime()
print(regime["bucket"], "as of", regime.as_of)
Every list method returns an ApiList (a list subclass carrying
.count and .as_of). Every single-object method returns an ApiDict
(a dict subclass carrying .as_of). You can treat them as ordinary
list / dict and reach for the metadata attributes when you need them.
Compound brief (start here)
k.brief(asset_class, symbol) is the fastest way in: one call assembles
the full cross-product digest for a single symbol from every relevant
product family, so you do not have to stitch the family endpoints
together yourself.
btc = k.brief("crypto", "BTC")
# crypto: derivatives + cross-exchange funding, liquidations, on-chain /
# stablecoin flows, ETF flows, related prediction markets, macro regime.
nvda = k.brief("equity", "NVDA")
# equity: signals, insider + congress, 13F, modeled dealer gamma, related
# prediction markets.
Each sub-section carries its own as_of, so you can tell which legs are
fresh and which are stale. The digest is descriptive and event-framed,
never advice. Reach for the family methods below when you need to drill
deeper than the digest returns.
Configuration
k = Kresmion(
api_key=None, # else env KRESMION_API_KEY
base_url="https://kresmion.com/api",
timeout=30, # seconds per request
max_retries=3, # extra attempts on 429 / 5xx / connection error
)
The client keeps a persistent HTTP session for connection reuse. Use it as a context manager to close the session automatically:
with Kresmion() as k:
print(k.status())
Namespaces
One example per namespace. Every method has a full docstring, so
help(k.prediction.markets) is your inline reference.
k.prediction - prediction markets
k.prediction.markets(category="crypto", min_volume=10000, q="fed", limit=50)
k.prediction.market("0xabc123") # one market
k.prediction.history("0xabc123", days=7) # probability history
k.prediction.book("0xabc123") # order book
k.prediction.book_history("0xabc123", hours=24) # depth/spread over time
k.prediction.execution_cost("0xabc123", notionals=[100, 1000, 10000]) # one-leg fill cost
k.prediction.algo_flags("0xabc123") # algorithmic-flow flags
k.prediction.flow("0xabc123") # recent flow
k.prediction.movers(limit=25)
k.prediction.consensus()
k.prediction.divergence(executable_size=1000) # cross-venue gaps, netted vs Polymarket-leg cost at $1k
k.prediction.options_divergence(currency="BTC", min_abs_spread=0.05) # Polymarket vs Deribit options-implied spread
k.prediction.options_divergence_history("0xabc123", days=30) # that spread over time
k.prediction.calendar(days=14) # upcoming resolutions (scheduled dates)
k.prediction.calibration()
k.prediction.resolutions(limit=25)
k.crypto - on-chain flows, ETFs, derivatives, options
whales = k.crypto.whales(min_usd=1_000_000, hours=24)
k.crypto.exchange_holdings()
k.crypto.exchange_history("binance", days=30)
k.crypto.etf_flows()
k.crypto.etf_history("IBIT", days=30)
k.crypto.derivatives("BTC")
k.crypto.funding() # cross-exchange funding surface
k.crypto.funding("BTC") # one symbol's funding history
k.crypto.liquidations("BTC", hours=24) # forced deleveraging (single venue, OKX)
k.crypto.stablecoins() # aggregate stablecoin supply / issuance
k.crypto.unlocks(days=90) # forward token-unlock calendar
k.crypto.funding_history("BTC", days=30)
k.crypto.oi_history("BTC", days=30)
k.crypto.options("BTC")
k.equities - signals, insiders, congress, 13F
k.equities.signals(limit=50)
k.equities.insider_clusters(limit=50)
k.equities.congress(limit=50)
k.equities.institutional(limit=50)
k.equities.price_history("AAPL", days=90)
k.equities.gamma() # modeled dealer-gamma surface
k.equities.gamma("NVDA") # one ticker: gamma by strike, flip level, walls
k.equities.smart_money(min_families=2, direction="long") # per-ticker positioning composite, legs listed
k.equities.smart_money_ticker("NVDA") # one ticker: live composite + snapshot trend
k.macro - regime, COT, TIC, BIS
k.macro.regime() # current cross-asset Risk-On/Off score and factors
k.macro.regime_history(days=365) # the regime score time series
k.macro.correlations() # cross-asset correlation breaks (latest snapshot)
k.macro.cot()
k.macro.tic()
k.macro.bis()
k.signals - cross-market signal feed
The signals namespace is callable, and it carries an accuracy method:
feed = k.signals(limit=50, severity="high") # GET /v1/signals
stats = k.signals.accuracy() # GET /v1/signals/accuracy
k.track_record - signal forward-return track record
How the live production signals were actually followed by price at 1, 7, and 30 days, unfiltered, so losing signal types show their negative medians too. Entry is the next daily close after the signal day.
k.track_record.aggregates(asset_class="crypto", min_n=5) # per-type/direction aggregates
k.track_record.types() # which detectors have history
k.track_record.for_type("funding_stress", symbol="BTC") # per-symbol + recent occurrences
k.confluence - cross-family confluence + divergence
Symbols where several independent signal families line up on a direction
(confluence) or strongly disagree (divergence), each contributing leg
listed under legs.
k.confluence.list(conviction="HIGH", hours=48) # active composites, newest first
k.confluence.for_symbol("BTC", hours=168) # current + history for one symbol
k.billing - paid quota top-ups (Solana USDC)
plans = k.billing.plans() # catalog: plan, usdc price, calls, days
q = k.billing.quote("boost_100k") # -> payment_id, amount_usdc, recipient, reference, ...
st = k.billing.status(q["payment_id"]) # poll: pending -> confirmed -> credited
See "Paying for quota with Solana USDC" below for the full flow.
k.status() and k.openapi()
k.status() # service status and your quota snapshot
k.openapi() # the raw OpenAPI 3 document for /v1
k.changes(...) - cross-family delta feed for polling
One poll returns only the rows in each product family that are newer than
your since cursor, so a running agent stays current for a tiny token
cost instead of re-fetching whole family payloads. The endpoint holds no
server-side cursor: the returned dict's .as_of is the next cursor (it
equals meta.next_since), so pass it straight back as since. Valid
families: signals, whale, prediction, funding, etf_flow,
gamma, confluence. since is capped at 7 days old.
snap = k.changes(since="2026-07-17T00:00:00Z", families=["signals", "whale"])
for sig in snap["signals"]:
print(sig["asset_symbol"], sig["signal_type"])
snap = k.changes(since=snap.as_of, families=["signals", "whale"]) # next poll
k.bulk - bulk historical downloads
Streams a gzip-compressed CSV for a date range straight to disk, with an optional progress callback:
import gzip, csv
def show(done, total):
print(done, "/", total, "bytes")
k.bulk.download("prediction_markets", "2026-01-01", "2026-06-30",
"pm.csv.gz", progress=show)
with gzip.open("pm.csv.gz", "rt") as fh:
for row in csv.DictReader(fh):
print(row)
Webhook verification
Kresmion signs every webhook delivery with HMAC-SHA256 over the raw
request body and sends the result in the X-Kresmion-Signature header as
sha256=<hex>. Verify it with the shared secret you received when you
created the webhook. Always hash the exact raw bytes, never re-serialized
JSON.
from kresmion import verify_webhook
# secret: the value handed to you once at webhook-create time.
# raw: the exact request body bytes.
# sig: the X-Kresmion-Signature request header.
if verify_webhook(secret, raw, sig):
handle(raw)
else:
reject() # 400
verify_webhook does a constant-time comparison and returns False
(never raises) on a bad or missing signature. See
examples/webhook_receiver.py for a complete stdlib receiver.
Global market events
Subscribe a webhook to any of these global market events (envelope
{"event", "fired_at", "data"}). The authoritative catalog, with an
example body and expected cadence per event, is served live at
GET /v1/webhooks/events.
| Event | Fires when |
|---|---|
signal.created |
A new cross-asset signal fires at the top (critical) severity tier. |
whale.transfer |
A single on-chain transfer >= $1M (self-transfer artifacts excluded). |
prediction.repricing |
A market (>= $50k volume) whose YES probability moved >= 10pp in 24h. |
prediction.divergence |
A linked Polymarket/Kalshi pair whose cross-venue |spread| crossed >= 5pp. |
prediction.resolution_imminent |
A contested market (>= $50k volume) whose scheduled close is within 48h. |
prediction.algo_flow |
A high-conviction algorithmic-flow flag on a market (confidence >= 85, notional >= $25k). |
etf.flow |
A new daily crypto-ETF flow print (once per new date per asset). |
regime.change |
The daily macro Risk-On/Off regime crossed into a new bucket. |
Rate limits and error handling
Keyed responses carry rate-limit headers. After every call, the client
refreshes k.last_rate_status:
k.prediction.markets(limit=1)
print(k.last_rate_status)
# {'limit_minute': 60, 'remaining_minute': 59,
# 'monthly_limit': 10000, 'monthly_used': 42}
The client retries transient failures for you with exponential backoff
and jitter, up to max_retries:
- On
429, it honors theRetry-Afterheader exactly when the server sends one, otherwise it backs off exponentially. - On
5xxand connection errors, it backs off exponentially.
When retries are exhausted, or on an error that is not retried, the client raises a typed exception:
| Exception | Raised on | Carries |
|---|---|---|
KresmionAuthError |
401 (not retried) |
.status, .detail |
KresmionRateLimitError |
429 after retries |
.retry_after, .rate_status |
KresmionAPIError |
other 4xx / 5xx, or connection failure |
.status, .detail |
All three subclass KresmionError, so you can catch broadly or narrowly:
from kresmion import (
KresmionAuthError, KresmionRateLimitError, KresmionAPIError, KresmionError,
)
try:
data = k.crypto.whales(min_usd=5_000_000)
except KresmionRateLimitError as exc:
print("slow down for", exc.retry_after, "seconds")
except KresmionAuthError:
print("check your API key")
except KresmionAPIError as exc:
print("api error", exc.status, exc.detail)
except KresmionError as exc:
print("kresmion error", exc)
Paying for quota with Solana USDC
When your key exhausts its monthly quota (a KresmionRateLimitError whose
detail names the monthly limit, not the per-minute window), you can buy more
calls by paying USDC on Solana mainnet. Four steps:
import time
plans = k.billing.plans() # 1. catalog: plan, usdc price, calls, days
q = k.billing.quote("boost_100k") # 2. create a payment for a plan
# 3. Send EXACTLY q["amount_usdc"] USDC (full 6-decimal precision, e.g.
# 5.000731; SPL mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) to
# q["recipient"] on Solana mainnet, from any wallet or exchange. The exact
# amount is what identifies your payment; including q["reference"] as an
# extra account is optional and merely speeds attribution. Then:
while k.billing.status(q["payment_id"])["status"] != "credited": # 4. poll
time.sleep(5)
The boosted quota applies to the key that created the quote the moment its
status reads credited. Payments are non-refundable, a quote expires 30
minutes after it is created, and only USDC on Solana mainnet is accepted.
One honest note: this SDK does not sign or send the transfer. You send it
yourself from any wallet or exchange, or programmatically with a Solana wallet
library such as solders or
solana (solana-py). The exact quoted
amount is what matches the transfer to your quote; the reference pubkey is
optional and only speeds attribution. Kresmion never holds your keys.
Examples
examples/divergence_monitor.pypolls prediction divergence every 60 seconds and prints crossings.examples/webhook_receiver.pyis a stdlibhttp.serverreceiver that verifies signatures.examples/backtest_download.pybulk-fetches a dataset and parses the gzip CSV into rows.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kresmion-0.2.1.tar.gz.
File metadata
- Download URL: kresmion-0.2.1.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2413cdca202a1f55837bec7107d83f311264c6ecdbd77c8b501b82a575395471
|
|
| MD5 |
976b93e38b1a058f22296073cf79af6c
|
|
| BLAKE2b-256 |
3d9c1f503423020649c34664e358b723ae367a091e528a729c0b440e125e1a39
|
File details
Details for the file kresmion-0.2.1-py3-none-any.whl.
File metadata
- Download URL: kresmion-0.2.1-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f3ee936795ff91f0cee8ac415b06c0bb9f4cb852c905c37dc3220768ae3013a
|
|
| MD5 |
7f766cd71912996e8321ce75792a2725
|
|
| BLAKE2b-256 |
f97eb17da4bb5f3ea96cce78e3d6a98fccbb833031a1fce7ea624908e3b51a5b
|