Skip to main content

MangroveAI SDKs: Python and TypeScript

Discord PyPI Downloads

Python and TypeScript clients for the public MangroveAI services. Choose the client for your product and language; the Markets SDK is a separate product, not the TypeScript version of this API.

Choose a client

Product and language Registry package Import Guide
MangroveAI Python PyPI mangroveai from mangrove_ai import MangroveAI Python install
MangroveAI TypeScript / Node.js 20+ npm @mangrove-ai/sdk 1.x import { MangroveAI } from '@mangrove-ai/sdk' TypeScript SDK guide
MangroveMarkets TypeScript npm @mangrove-ai/markets import { MangroveClient } from '@mangrove-ai/markets' Markets SDK guide

Check the AI 1.0.0 npm release target and TypeScript GitHub Release for availability; a source version does not establish publication. The TypeScript guide covers registry and reviewed archive installation. Dated publication checkpoints are in the release handoff. Python mangroveai 2.1.0 is published on PyPI.

Breaking product boundary: published @mangrove-ai/sdk 0.1.2, 0.2.0 and 0.3.0 are historical Markets clients. The new 1.0.0 package is MangroveAI and does not preserve the Markets API. Markets applications must move to @mangrove-ai/markets, not upgrade to the AI SDK. See the migration notice and dated release handoff. The former @mangrove-ai/client name was an unpublished AI candidate and will not be published.

The TypeScript client has named users, signals, strategyWorkflow and backtesting helpers plus a generic typed request(operation, options) surface. The current public contract classifies 264 method/path operations across core and Oracle proxy REST, including 10 v2 operations; this is generated declaration coverage, not live endpoint acceptance. Of these, 261 use JSON/no-content, one requires a separate redirect flow and two require a streaming/non-JSON client. It is not a drop-in copy of Python's service methods. It does not supply MCP/OAuth discovery, the separate legacy KB-host client, x402 signing or SSE consumption. See the operation classification.

Credentials and base URLs belong to the selected product. When using both AI and Markets clients, pass separately configured credentials and URLs explicitly; do not assume their keys are interchangeable or share one MANGROVE_BASE_URL. Python AI expects a versioned /api/v1 base, Python Markets expects an origin, and AI TypeScript accepts an origin or a versioned base. The SDKs carry requests and preserve Mangrove decisions; Mangrove owns deterministic risk management based on live market and account conditions.

Install

pip install mangroveai

The package imports as mangrove_ai (e.g. from mangrove_ai import MangroveAI). The legacy import mangroveai path also still works for backwards compatibility.

Setup

  1. Create an account at mangrovedeveloper.ai
  2. Navigate to Settings > API Keys
  3. Generate a new API key
  4. Set it as an environment variable:

macOS / Linux (bash/zsh):

export MANGROVE_API_KEY=prod_your_key_here

Windows (PowerShell):

$env:MANGROVE_API_KEY = "prod_your_key_here"

Windows (cmd.exe):

set MANGROVE_API_KEY=prod_your_key_here

Private configuration

For an agent or local script, keep the key in private configuration outside your repository. examples/first_call.py reads a JSON file containing api_key and optional base_url, disables dotenv loading, and makes one usage request. Restrict the file's permissions and do not commit it. Existing environment variable and optional mangroveai[dotenv] loading remain supported for compatibility; use load_dotenv=False to disable file discovery.

First API call

Python

from mangrove_ai import MangroveAI

# api_key comes from private configuration; do not paste it into source.
with MangroveAI(api_key=api_key, load_dotenv=False, timeout=15, auto_retry=False) as client:
    metrics = client.users.get_my_metrics()
    print(metrics.messages_count)

This calls GET /api/v1/users/me/metrics with Bearer authentication. It does not create a strategy or launch a backtest. The SDK surfaces 401, 402, 403, 429 and 503 as typed errors, including available retry and correlation fields. It does not purchase access or pay automatically.

TypeScript

Install the reviewed package as described in the TypeScript guide, then use its public ESM import:

import { MangroveAI } from '@mangrove-ai/sdk';

const client = new MangroveAI({
  apiKey: process.env.MANGROVE_API_KEY,
  timeoutMs: 15_000,
});
const metrics = await client.users.getMyMetrics();
console.log({ messages: metrics.messages_count });

This makes the same single usage read with no automatic retry or payment. For dev_ and test_ keys, configure the intended AI base URL explicitly; see each language guide for its format. Keep keys in private server-side configuration, not source, browser bundles or prompts. Publication does not deploy an API.

The remaining examples and service reference below describe the Python SDK; use the TypeScript guide for its helper and generic request interfaces.

Quickstart

from mangrove_ai import MangroveAI

client = MangroveAI()  # reads MANGROVE_API_KEY from environment

# List trading signals
signals = client.signals.list(limit=10)
for s in signals.items:
    print(f"{s.name} ({s.category}, {s.signal_type})")

# Get market data
btc = client.crypto_assets.get_market_data("BTC")
print(f"BTC: ${btc.data['current_price']:,.2f}")

# Create a strategy
from mangrove_ai.models import CreateStrategyRequest

strategy = client.strategies.create(CreateStrategyRequest(
    name="RSI Momentum",
    asset="BTC",
    entry=[{"name": "rsi_oversold", "signal_type": "TRIGGER",
            "timeframe": "1d", "params": {"window": 14, "threshold": 30}}],
))

# Run a backtest (blocks until done; async-backed since v1.14, so long
# lookbacks work -- it submits to the async surface and polls internally)
import json
from mangrove_ai.models import BacktestRequest

result = client.backtesting.run(BacktestRequest(
    asset="BTC",
    interval="1d",
    strategy_json=json.dumps({"name": "test", "asset": "BTC",
        "entry": [{"name": "rsi_oversold", "signal_type": "TRIGGER",
                    "timeframe": "1d", "params": {"window": 14, "threshold": 30}}],
        "exit": []}),
    lookback_months=3,
    initial_balance=10000,
    min_balance_threshold=0.1, min_trade_amount=25,
    max_open_positions=3, max_trades_per_day=10,
    max_risk_per_trade=0.02, max_units_per_trade=1000000,
    max_trade_amount=10000000, volatility_window=24,
    target_volatility=0.1,
    # Partial trades-model overrides retain the other server defaults.
    # Loss pauses default to 36 bars, clamped to 24 hours through 14 days.
    execution_config={
        "circuit_breaker": {
            "consecutive_loss_limit": 4,
            "pause_bars": 36,
        }
    },
))
print(f"Trades: {result.trade_count}, Sharpe: {result.metrics.get('sharpe_ratio')}")

Compare circuit-breaker settings by submitting a complete new backtest for each setting over the same original history and seed. Reusing or filtering a prior trade list cannot measure the changed signals, sizing, fees, exits, and account balances produced by a full run.

The regular and Oracle single/bulk backtest request models accept cooldown_model, max_drawdown_limit, and max_drawdown_halt_limit. The SDK places explicitly supplied values in execution_config, where the engine reads them. Omitting a threshold accepts the server default; explicitly passing None disables that guard. Conflicting values in both locations raise ValueError before sending. Disabling drawdown guards alone does not disable loss pauses: a fully unprotected control also needs the explicit bars model and zero short_cooldown_bars and long_cooldown_bars for every active timeframe. Keep valid positive loss limits and window sizes. Legacy cooldown_config supplied on an SDK request is also placed inside execution_config. Align these settings with any configuration embedded in strategy_json or individual bulk strategy configs: Oracle's per-strategy configuration precedence still applies. Preserve all other strategy inputs, fees, and sizing between full runs.

Session authentication

API keys use Bearer authentication and do not refresh. client.auth.login() accepts a Firebase ID token and installs the returned access token for core v1 and v2 requests. Keep the same client open: refresh uses its scoped mg_refresh and mg_csrf cookies plus X-CSRF-Token, with no JSON body. Current login responses omit the body refresh token; older missing or null fields are accepted. auto_auth=True refreshes an expired JWT once, then retries once. Use auto_auth=False to handle expiration yourself. Supplying a body refresh token raises a local configuration error because the current API does not accept it.

Unsupported compatibility methods

execution.update_account, execution.get_position, crypto_assets.risk_analysis and the three retired WhaleAlert methods raise locally before HTTP because the current API does not expose those operations. Use the documented resources. execution.list_positions(open_only=False) includes both states. Legacy status="closed" filters the returned server page locally; offsets still refer to all server rows, so a filtered page can contain fewer than limit rows.

Caller-owned execution and confirmed fills

Mangrove owns enforcement of configured user limits and approval policy. The SDK submits documented requests and preserves Mangrove decisions and audit results; it does not implement a separate trading safety policy.

For an external executor, evaluate_by_object(..., persist=False) proposes orders from the caller's actual ledger. Even an order marked filled in an evaluation is an estimate until that executor confirms it. The result separates:

  • open_positions: the authoritative input book, unchanged by proposed fills.
  • proposed_positions: entry templates with stable position IDs and brackets.
  • proposed_closes: estimated net exit results.
  • closed_trades: confirmed engine-owned simulated fills only.

Both proposal fields carry execution_confirmed=False. Book an entry or close only from the executor's actual fill, including its actual fees and net P&L. Retain returned execution_state risk counters and candle cursors, then overlay the actual account balances and position book before evaluating again. Preserve gross cumulative deposits and the net funding reference separately.

Confirmed close delivery belongs inside the inline strategy:

# strategy contains rules/config plus persisted risk state overlaid with the
# actual ledger. ledger_* values below come from your executor's durable store.
payload = {
    **strategy,
    "closed_positions": ledger_closed_positions,
    "closed_positions_bootstrap_complete": ledger_history_is_complete,
}
result = client.execution.evaluate_by_object(
    payload, open_positions=ledger_open_positions, persist=False,
)

Each close has a stable position_id, exit_timestamp, actual realized_pnl, and the ledger's booked_at timestamp. Deliver the complete initial confirmed history before marking bootstrap complete; an empty complete history is valid for a new account. In the trades model, new entries are held until that initial history is acknowledged. Exits continue, and the returned risk state reports entry_block_reason="close_history_bootstrap_required". This also applies to inline drafts and requests that omit open_positions; omission does not attest an empty history. Keep delivering new closes until the returned risk state acknowledges their position IDs. Do not clear risk state, reset halts, or turn an unfilled proposal into history when retrying. When flat, send explicit open_positions=[].

For evaluate_bulk, put these same three fields, including open_positions, inside each strategy config. Check each result's success independently. persist=True with a saved strategy ID instead uses the engine's simulated fill ledger; it does not confirm execution at an external venue. persist=True without a strategy ID does not confirm fills.

Services

Layer 1: MangroveAI Core API

Service Access Methods Description
client.auth auth.* 5 Login, refresh, API key management
client.strategies strategies.* 9 Strategy CRUD, status, execution state, verify_strategy (pre-backtest conformance check)
client.backtesting backtesting.* 8 Sync/async/bulk backtesting, get_benchmark (buy-and-hold over a window)
client.market_data market_data.* 2 get_market_regime (direction over 90/180/365d + volatility + the lookback in sweep-catalog labels, for crypto and listed stocks, ETFs, commodities and bonds such as SPY, GOLD and CRUDE), classify_market_segment (one named stretch in sweep-catalog labels)
client.config config.* 3 Trading/execution defaults, get_execution_config_schema (each parameter's default, effect, bounds, status)
client.oracle oracle.* 28 SIEVE scoring, parameter sweeps/experiments, corpus data queries, backtests, simulation, leaderboard
client.signals signals.* 8 Signal discovery, evaluation, validation, query_signal_behavior (measured selectivity / firing rate by parameter setting)
client.crypto_assets crypto_assets.* 10 Assets, approved universe, per-asset exchanges, OHLCV, market data
client.execution execution.* 8 Accounts, positions, trades, evaluation
client.on_chain on_chain.* 11 Smart-money flows, DEX/perp trades and token holders (Nansen); retired WhaleAlert compatibility methods fail locally
client.defi defi.* 8 TVL/chain/stablecoins (any plan); token unlocks, perp funding, treasuries, ETF flows, lending rates (DeFiLlama Pro -- requires Pro/Startup/Enterprise, capped at 1,000 calls/account/month)
client.social social.* 4 Topic sentiment, mentions, user influence, get_x_post_counts (hourly or daily X post counts, the input of the x_attention signals)
client.docs docs.* 2 Documentation listing and content

client.config.get_execution_config_schema() makes an explicit server request and exposes the canonical normalized authoring schema as result.json_schema, alongside defaults and the parameter glossary. Older servers may omit this additive field, in which case it is None. Nested glossary metadata includes cooldown fields and the backend's required-field declarations. The SDK does not fetch this metadata automatically or use it to impose trading policy. Authoring guidance is separate from accepted legacy transport shapes; the HTTP boundary does not enforce the entire nested authoring schema.

Layer 2: Knowledge Base API

Service Access Methods Description
client.kb.documents kb.documents.* 3 Document listing, content, sections
client.kb.search kb.search.* 1 Full-text search with BM25 ranking
client.kb.tags kb.tags.* 2 Tag listing and filtering
client.kb.glossary kb.glossary.* 3 Glossary terms and backlinks
client.kb.signals kb.signals.* 2 Signal metadata from KB
client.kb.indicators kb.indicators.* 2 Indicator metadata from KB
client.kb.compute kb.compute.* 2 x402 paid signal/indicator computation

On-chain capability surface

client.on_chain covers Mangrove's supported Nansen Pro operations. Three WhaleAlert methods remain as compatibility stubs and raise locally without making a request:

Method Source What it returns
get_onchain_series(symbol, metrics, date_from, date_to, interval, provider) Nansen Per-bar metric time series (SmartMoneyNetflow, SmartMoneyHoldings, ExchangeNetflow, WhaleNetInflow, HolderConcentration) — one column per metric
get_smart_money_sentiment(symbol) Nansen Single-token accumulation/distribution score
screen_smart_money(chains, timeframe) Nansen Tokens with high smart-money activity
get_smart_money_historical_holdings(chains, date_range, filters, order_by) Nansen Date-stamped holdings snapshots
get_smart_money_dex_trades(chains, filters, order_by) Nansen Live DEX trades by smart-money wallets
get_smart_money_perp_trades(filters, order_by) Nansen (Hyperliquid) Perpetual-futures trades by smart-money wallets
get_token_holders(symbol) Nansen Holder distribution + concentration
get_token_dex_trades(symbol, chain, date_range, filters, order_by) Nansen Single-token DEX trades across all participants
get_token_flows(symbol, chain, date_range, label, filters, order_by) Nansen Per-wallet-category hourly flow rows (label scopes to smart_money/exchange/whale/…; excludes stablecoins)

On-chain time series → signals. get_onchain_series returns a per-bar series for any window — the same call serves a live trailing window (e.g. last 10 days, ending now) or a long historical range. Build a DataFrame with pd.DataFrame(resp.series).set_index("timestamp") and feed it to a mangrove-kb on-chain signal. End-to-end walkthrough: examples/onchain_signals_demo.py.

filters and order_by pass through directly to the upstream Nansen API — restrict by include_smart_money_labels, set value_usd min/max bounds, sort by any field. See examples/on_chain_nansen.py for raw-method snippets.

X attention signals

client.social.get_x_post_counts(symbol, days_back=7, granularity="hour", x_query="all") returns closed buckets of X posts matching the asset's cashtag ($BTC), oldest first; days_back is 1-31. They feed three signals in the social category: x_post_count_spike, x_attention_elevated and x_attention_price_divergence, on any timeframe. These measure how much people post, not what they say. All three take x_query ("all" or "en_original"); a strategy uses one value across its X rules. Counts are hourly, stamped on the bar open time, and a bucket becomes visible to a bar only once it has ended plus a 5-minute ingest lag before that bar closes, live and in backtests alike; sub-hourly bars reuse the latest visible hourly bucket and any gap evaluates False. Counts come from the X API, billed per request ($0.005 for the last 7 days, $0.010 for the full archive; one request covers up to 31 days of hourly buckets). They are backfilled on demand and cached, so x_requests == 0 means the call cost no X request and a repeat backtest over cached ranges costs nothing. Backfills stop when the shared credit balance falls under a floor. The read then returns 503 (as it does when X signals are off or X is not configured), and a strategy's X rules evaluate False and are logged. End-to-end walkthrough: examples/x_attention_signals_demo.py.

Oracle — SIEVE + sweep

client.oracle.* is Mangrove's strategy-research engine. Two headline tools:

  • SIEVE scores up to 99 strategy ideas in one call and returns binary go/no-go probabilities (p_trades vs p_no_trades) for whether a strategy will trade. The retired four_class outcome head is None on current responses; do not use it to predict performance or rank strategies.
  • Sweep fans a parameter search into one managed experiment of many backtests and ranks the results.

Score ideas with SIEVE

from mangrove_ai import MangroveAI
from mangrove_ai.models.oracle import SieveScoreRequest, StrategyInput, SignalSpec

client = MangroveAI()  # reads MANGROVE_API_KEY

resp = client.oracle.sieve_score(SieveScoreRequest(strategies=[
    StrategyInput(
        asset="BTC",
        entry=[SignalSpec(name="ema_crossover", signal_type="TRIGGER", timeframe="1h")],
        exit=[SignalSpec(name="rsi", signal_type="FILTER", timeframe="1h")],
    ),
    # ...up to 99 strategies per request
]))

print(f"scored {resp.count} | model {resp.model_version}")
for p in resp.predictions:
    print(f"  go/no-go: {p.binary}")  # {'p_no_trades': .., 'p_trades': ..}
# SIEVE is a go/no-go gate (will it trade?), not a performance prediction:
# backtest the strategies it expects to trade. `four_class` is retired (None).

Run a parameter sweep (experiment lifecycle)

A sweep is a draft experiment you validate, then launch; it fans out into backtests asynchronously. Poll get_experiment / list_results to track it.

# Pick a dataset + execution defaults from the API, then build a config
ds = client.oracle.list_datasets()[0]
exec_config = client.oracle.exec_config_defaults()

config = {
    "name": "ema-sweep-demo",
    "kind": "single",
    "search_mode": "random",
    "seed": 42,
    "n_random": 50,                 # number of random strategies to draw
    "datasets": [ds],
    "random_signals": {
        "n_entry_triggers": 1, "min_entry_filters": 0, "max_entry_filters": 2,
        "min_exit_triggers": 0, "max_exit_triggers": 1,
        "min_exit_filters": 0, "max_exit_filters": 1,
        "n_param_draws": 3, "allowed_categories": None,
    },
    "execution_config": exec_config,
}

created = client.oracle.create_experiment(config)            # -> status "draft"
val = client.oracle.validate_experiment(created.experiment_id)
print(f"valid={val.valid} total_runs={val.total_runs} errors={val.errors}")

if val.valid:                                                # must pass before launch
    client.oracle.launch_experiment(created.experiment_id)   # fans out asynchronously
    status = client.oracle.get_experiment(created.experiment_id)
    print(f"status={status['status']} completed={status.get('completed_runs')}")
    # client.oracle.pause_experiment(id) / delete_experiment(id) to stop or clean up

results = client.oracle.list_results(experiment_id=created.experiment_id, limit=20)

Canonical Sieve and sweep workflows

For the same Sieve and sweep operations advertised by MangroveAI MCP, use client.strategy_workflow.screen_candidates, list_sweep_markets, size_sweep, get_sweep_limits, create_sweep, launch_sweep, get_sweep, list_sweeps, find_sweep_runs, list_run_filters, get_sweep_run, and pause_sweep. These methods call /strategy-workflow/<name> and leave composition, sizing, ranking, ownership and pricing to the server. Load sweeps or sweep-results with client.strategy_workflow.load_skill for the current workflow. Creating a sweep does not launch it; launch only after agreeing to the server's run count. The SDK uses its existing authenticated HTTP transport; it does not add a wallet or sign x402 payments. The agent's existing MCP payer handles wallet access. The lower-level client.oracle.* methods retain their existing raw-engine contracts.

Other client.oracle.* methods

  • Backtests: backtest, backtest_async + backtest_poll, backtest_bulk
  • Corpus query: data_query (curated BigQuery proxy over the results corpus)
  • Simulation: simulate_run, simulate_generate, simulate_presets, simulate_history
  • Results & catalogs: list_results, list_datasets, list_signals, list_templates, exec_config_defaults
  • Leaderboard & live: leaderboard, list_deployed_strategies, get_deployed_strategy_state, get_deployed_strategy_events

Full reference: SIEVE pre-filter guide, SIEVE end-to-end, and the Experiments API reference.

Environment Detection

The SDK auto-detects the environment from your API key prefix:

Prefix Environment API Base URL
prod_ Production https://api.mangrovedeveloper.ai/api/v1
dev_ Development Explicit base_url or MANGROVE_BASE_URL required

Development never falls back to production. A test_ key also requires an explicit base URL or local environment. Base URL overrides apply to v1 and v2; pass a base ending in /api/v1. The Knowledge Base has its own kb_base_url.

Override with explicit parameters:

client = MangroveAI(api_key="...", base_url="http://localhost:5001/api/v1")

Error Handling

from mangrove_ai import MangroveAI, NotFoundError, RateLimitError, APIError

client = MangroveAI()

try:
    strategy = client.strategies.get("nonexistent-id")
except NotFoundError as e:
    print(f"Not found: {e.message} (correlation_id={e.correlation_id})")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after}s")
except APIError as e:
    print(f"[{e.status_code}] {e.code}: {e.message}")

Pagination

Paginated endpoints return PaginatedResponse[T]:

# Single page
page = client.strategies.list(skip=0, limit=10)
print(f"Showing {len(page.items)} of {page.total}")

# Auto-paginate all items
for strategy in client.strategies.list_iter():
    print(strategy.name)

Examples

See the examples/ directory for working scripts.

Development

git clone https://github.com/MangroveTechnologies/MangroveAI-SDK.git
cd MangroveAI-SDK
pip install -e ".[dev]"
pytest tests/ --ignore=tests/integration  # unit tests
MANGROVE_API_KEY=... pytest tests/integration/ -m integration  # live tests

Metadata

Release files for mangroveai 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mangroveai 2.2.0
File Size Uploaded Provenance Actions
mangroveai-2.2.0.tar.gz 455.9 kB Without provenance Details for mangroveai-2.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mangroveai 2.2.0
File Interpreter ABI Platform Actions
mangroveai-2.2.0-py3-none-any.whl Python 3 none any Details for mangroveai-2.2.0-py3-none-any.whl

Total release size: 562.8 kB

Release files / mangroveai-2.2.0.tar.gz

Download URL mangroveai-2.2.0.tar.gz
Size 455.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6e0b22a6352ed679d08dc24afb89e867bd12e31d1d691f17ec7dd7073512fa81
BLAKE2b-256 checksum
How to use checksums
16efad3a998d544e93f75098302995e73a47471876a4e7b9ed329ba3287b8815
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / mangroveai-2.2.0-py3-none-any.whl

Download URL mangroveai-2.2.0-py3-none-any.whl
Size 106.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a00853d03f38f9e1ac062294fe982ae6d2eeb6963fa5a387031db75c476f7391
BLAKE2b-256 checksum
How to use checksums
94ee76576e04581434def7ef9d89a01800fb96ce45f51e5a3fcc2cabbb2043d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for mangroveai 2.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page