> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xinsider.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Review suspicious trades

> Build a review queue from flagged trades, wallet history, market flow, and graded holders.

Use this recipe to review trades that 0xinsider's suspicion scorers flagged. You will inspect the stored evidence, the wallet's grade, the market's net flow, and other graded holders.

A flag is a reason to investigate. It does not prove insider activity. The score uses wallet age, trade size, conviction, clustering, and fill patterns; it does not read news or know a future result.

You need a [Pro API key](/authentication) and Python with `requests` installed. Run `python -m pip install requests` if needed. The snippets share the variables defined in step 1.

<span id="1-pull-suspicious-live-trades" />

## 1. Read flagged large trades

Request [Large trades](/api-reference/endpoint/get-large-trades) with `suspicious_only=true`. This keeps trades whose recorded suspicion score is at least 60.

```python theme={null}
import os

import requests

BASE = "https://api.0xinsider.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['OXINSIDER_API_KEY']}"}

def get(path, **params):
    response = requests.get(f"{BASE}{path}", params=params, headers=H, timeout=30)
    response.raise_for_status()
    return response.json()


trades = get("/large-trades", suspicious_only="true", limit=50)

for tr in trades["data"]:
    who = tr["trader"].get("username") or tr["trader"]["address"][:10]
    print(
        tr["suspicion_score"], tr["suspicion_track"], who, tr["side"],
        tr["outcome"], tr["size_usd"], tr["market"]["title"],
    )
```

`suspicion_track` identifies the scorer:

| Track | What it detects |
| - | - |
| `whale` | A large trade combined with at least 2 further signals, such as a new wallet, a low-priced outcome against the crowd, or other new wallets in the market. |
| `fresh_conviction` | A new wallet taking a low-priced outcome against the crowd with a trade below the large-trade threshold. |
| `sliced_position` | A wallet building one large position through many small fills in a short period. |

<span id="2-pull-the-flagged-trades" />

## 2. Read the scorer's evidence

[Suspicious trades](/api-reference/endpoint/get-suspicious-trades) sorts stored flags by suspicion score and includes the recorded `scores` and `evidence`. Use [Suspicious trade](/api-reference/endpoint/get-suspicious-trade) to read one flag by its `rf_` ID.

```python theme={null}
flags = get("/suspicious-trades", severity="flag", min_suspicion=70, limit=50)

for f in flags["data"]:
    s = f["scores"]
    who = f["trader"].get("username") or f["trader"]["address"][:10]
    print(f["id"], f["suspicion_score"], who, f["market"]["title"], "size", s["size"], "fresh", s["fresh_wallet"])
```

| Parameter or field | Meaning |
| - | - |
| `min_suspicion` | Sets a score filter from 0 to 100. The flag threshold of 60 still applies. |
| `severity` | Use `flag`. `watch` returns no rows because watch-level records are not stored. |
| `mode=live` | Uses pages cached for up to 120 seconds. This is the default. |
| `mode=stable` | Keeps one set of published scores across pages. A score or filter change can return `cursor_expired`; restart that traversal. |
| `scores.size`, `scores.fresh_wallet` | Stored score components, or `null` when the scorer did not record them. |
| `scores.timing`, `scores.edge` | Always `null`; the live scorer does not record them. |
| `evidence` | The signals stored for this trade. |
| `created_at` | When the trade happened, rather than when it was flagged. |

<span id="3-add-the-wallet-and-the-market" />

## 3. Check the wallet and market

A flagged trade includes the wallet's identity, but not its grade. Read [Trader](/api-reference/endpoint/get-trader) for `grade`, `stats.markets_traded`, and `sync_status`.

Read [Market flow](/api-reference/endpoint/get-market-flow) to compare the trade with net large-trade flow over the last 24 hours. The `sharp_money.direction` field is `YES` or `NO`, and `net_flow_usd` is the signed flow in the selected window.

```python theme={null}
if not flags["data"]:
    print("No flags matched the filters.")
else:
    flag = flags["data"][0]
    address = flag["trader"]["address"]
    condition_id = flag["market"]["condition_id"]
    trader = get(f"/trader/{address}")["data"]
    flow = get(f"/market/{condition_id}/flow", timeframe="24h")["data"]
    print("grade:", trader.get("grade"), "markets:", trader["stats"]["markets_traded"])
    print("sync status:", trader["sync_status"])
    print("net flow:", flow["sharp_money"]["direction"], flow["sharp_money"]["net_flow_usd"])
```

A wallet that 0xinsider does not track returns `200` with `sync_status: "unknown"`. It can have no grade; keep that absence visible. The deprecated market intel route and `smart_money` field remain aliases, but use market flow and `sharp_money` for new code.

Compare both `side` and `outcome` on the trade with the flow direction. Buying YES and selling NO can affect net flow in the same direction.

<span id="4-check-who-else-holds-that-side" />

## 4. Check other graded holders

[Market holders](/api-reference/endpoint/get-market-holders) returns the S-, A-, and B-grade wallets with open shares in the market. It uses a complete provider holder scan and fails with `503` if that scan cannot produce a complete roster.

```bash theme={null}
curl -H "Authorization: Bearer $OXINSIDER_API_KEY" \
  "https://api.0xinsider.com/api/v1/market/0x123.../holders?outcome=yes&min_grade=A"
```

Use `outcome=yes` or `outcome=no` for one side. `min_grade=A` keeps S and A; its default, `B`, also includes B. Follow the cursor if the roster spans more than one page.

Each row includes `side`, `grade`, `shares`, and `current_value_usd`. A wallet holding both outcomes appears once, on its net side.

`is_new_wallet` appears only when the wallet earns a badge. It counts from the first trade recorded by 0xinsider, not the first on-chain transaction, and is `true` for a recorded first trade less than 30 days ago.

<span id="5-get-push-alerts" />

## 5. Receive new flags by webhook

Subscribe to `suspicious_trade_flagged`. It fires when a trade first crosses the flag threshold. The older `insider_radar_flag_raised` spelling remains supported for existing subscribers.

The event includes `trade_id`, `wallet`, `trader_id`, `condition_id`, `suspicion_score`, `track`, `side`, `size`, and `price`. Here, `side` is the traded outcome (`yes` or `no`), and `size` is shares. Those meanings differ from `BUY`/`SELL` and `size_usd` on the large-trade object.

Follow [Webhooks](/guides/webhooks) to register a destination and verify delivery signatures.

<span id="what-this-does-not-do" />

<span id="related" />

## Limits

* The suspicion score is a heuristic, not proof of inside knowledge.
* The flag does not include a wallet grade. Request the trader separately.
* The API does not store watch-level flags or place orders.
* A recorded first-trade date does not establish the wallet's on-chain age.
* `review_score` is a separate score with a different purpose; see [Scores](/concepts/signal-scoring).

Use [Alert bot](/recipes/alert-bot) for a durable large-trade notification consumer.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.