Skip to main content

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 the Retry-After header exactly when the server sends one, otherwise it backs off exponentially.
  • On 5xx and 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.py polls prediction divergence every 60 seconds and prints crossings.
  • examples/webhook_receiver.py is a stdlib http.server receiver that verifies signatures.
  • examples/backtest_download.py bulk-fetches a dataset and parses the gzip CSV into rows.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kresmion-0.2.1.tar.gz (30.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kresmion-0.2.1-py3-none-any.whl (26.1 kB view details)

Uploaded Python 3

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

Hashes for kresmion-0.2.1.tar.gz
Algorithm Hash digest
SHA256 2413cdca202a1f55837bec7107d83f311264c6ecdbd77c8b501b82a575395471
MD5 976b93e38b1a058f22296073cf79af6c
BLAKE2b-256 3d9c1f503423020649c34664e358b723ae367a091e528a729c0b440e125e1a39

See more details on using hashes here.

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

Hashes for kresmion-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0f3ee936795ff91f0cee8ac415b06c0bb9f4cb852c905c37dc3220768ae3013a
MD5 7f766cd71912996e8321ce75792a2725
BLAKE2b-256 f97eb17da4bb5f3ea96cce78e3d6a98fccbb833031a1fce7ea624908e3b51a5b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page