Create a strategy
MCP tool: save_strategy
Deploys a rule that survived testing. The strategy records every matching trade from now on and notifies you in a daily digest.
Create-only by design: an agent that can delete or rewrite strategies can destroy an account's history in one confused turn, and there is no undo. Editing stays in the app.
Body parameters
namestringrequiredA short name you will recognise, 1 to 60 characters.
criteriaobjectrequiredThe rule: which trades to include. The same shape a saved strategy uses, so a rule you test is a rule you can deploy without translation.
platformsstring[]Venues to include: "polymarket", "kalshi". Omit for both, which is usually right.
categoriesstring[]Market categories: "sports", "politics", "crypto", "finance", "culture". Omit for all.
sportsLeaguesstring[]Leagues, e.g. ["NBA", "NFL"]. Only applies to sports markets. Max 20.
minAmountUsdnumberMinimum trade size in USD. Typical values are 10000 to 50000.
maxAmountUsdnumberMaximum trade size in USD. Must be at least minAmountUsd when both are set.
priceMinnumberMinimum entry price, 0 to 1. 0.75 and up is heavy favourites.
priceMaxnumberMaximum entry price, 0 to 1. 0.20 and below is longshots. Must be at least priceMin when both are set.
eventTypesstring[]How the trade changed the trader's position: "open", "add", "flip", "trim", "close", "unknown". Entries only is ["open", "add", "flip"], which is the usual choice. Trims and closes are exits and never settle, so they cannot be scored.
directionsstring[]Trade direction: "buy_yes", "buy_no", "sell_yes", "sell_no". Only buys are ever scored; sells never resolve.
keywordsstring[]Case-insensitive substrings matched against the market name. Any one matching is enough. Max 10.
backfillbooleandefault: falseClaim matching history immediately so the strategy has a record from day one. Off by default so a clean forward-only run is possible.
backfillDaysintegerdefault: 90How far back a backfill reaches, 1 to 365 days.
defaultStakeUsdnumber | nulldefault: 100Hypothetical stake per trade. Pass null explicitly to size every trade at whatever the whale bet.
endsAtstring | nullISO datetime or YYYY-MM-DD. When set, the strategy stops claiming trades and sends a final summary.
Response
backfill is null when backfill was not requested. truncated is true when the scan hit its row limit, meaning older matching history exists that this backfill did not claim.
curl -X POST https://api.rivo.markets/v1/strategies \
-H "Authorization: Bearer rivo_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Longshot Hunters",
"criteria": {
"priceMax": 0.2,
"minAmountUsd": 10000,
"eventTypes": [
"open",
"add",
"flip"
]
},
"backfill": true
}'import requests
r = requests.post(
"https://api.rivo.markets/v1/strategies",
headers={"Authorization": "Bearer rivo_live_..."},
json={
"name": "Longshot Hunters",
"criteria": {
"priceMax": 0.2,
"minAmountUsd": 10000,
"eventTypes": ["open", "add", "flip"],
},
"backfill": True,
},
)
print(r.json()["data"])const res = await fetch("https://api.rivo.markets/v1/strategies", {
method: "POST",
headers: {
Authorization: "Bearer rivo_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Longshot Hunters",
criteria: {
priceMax: 0.2,
minAmountUsd: 10000,
eventTypes: ["open", "add", "flip"],
},
backfill: true,
}),
});
const { data } = await res.json();{
"success": true,
"data": {
"id": "b4a4f7a0-4a5e-4e9d-9c1e-2f6d8f3a1c77",
"name": "Longshot Hunters",
"backfill": {
"scanned": 57412,
"matched": 489,
"truncated": false,
"oldestScannedAt": 1747300364000
}
}
}