Seqlense docs

Market Abuse

Scan a wallet for on-chain manipulation patterns, and read the report the scanner produces.

A market abuse scan looks at a wallet's on-chain behaviour and scores it against four manipulation patterns: pump and dump, insider trading, smurfing and wash trading. Each detector produces a score, a threshold, and the detail of every signal it examined.

Scans are asynchronous. Launching one returns immediately with a job_id; the report appears later, under that same id. There is no callback: poll the result endpoint.

Launching a scan

POST /v1/mabu/runs with a wallet and a chain:

{ "wallet": "0xd90e2f925da726b50c4ed8d0fb90ad053324f31b", "chain": "ethereum" }

The response carries the only identifier you need to keep:

{ "status": "ok", "job_id": "2966a324-2b67-48ee-a0e1-3fe6b123e1b2" }

That job_id is both the run id and the scan_id its report is filed under.

chain accepts either the full name or your wallet's own chain code, so ethereum and ETH both work. Supported: ethereum, bitcoin, bsc, polygon, arbitrum, optimism, base, solana.

The scanned wallet is added to your organization's wallets if it is not already there.

Following a run

A run moves through a small set of states:

StatusMeaning
PENDINGcreated, not yet handed off
DISPATCHEDhanded off and running
DONEits report exists
FAILEDthe hand-off failed, or nothing was published in time

Use GET /v1/mabu/runs/search to list runs, filtered by status, chain, wallet, or a prefix of the run id. GET /v1/mabu/runs/detail?id=… returns a single run.

Reading a report

GET /v1/mabu/runs/result?scan_id=… returns the report.

A 404 means the scan has not published anything yet. That is the normal state of a run still in progress, not an error: poll until it answers.

The payload is the ingestion envelope; the report itself sits under data. Start with data.summary, then open data.patterns for the detail.

Signal statuses are the important part

Every detector reports a list of signals, and each signal carries one of three statuses:

StatusMeaning
confirmedthe signal fired, and its points count toward the score
not_confirmedassessed, and absent
not_evaluablecould not be assessed at all

not_evaluable is not a negative result. A signal that needs data the scan could not obtain is reported as unanswerable rather than as clean, so a low score never silently means "nothing found" when it actually means "nothing was looked at". Read coveragePct and confidence on a pattern to see how much of its scoring was reachable.

Counterparties that are a finding in themselves

Mixers and phishing addresses are excluded from the counterparty graph so they cannot inflate a score. They are listed separately under riskCounterparties, with their entity and interaction count: excluding them from the scoring is not the same as hiding them from you.

Scanning on a schedule

A wallet can carry a recurring scan, so you do not have to launch one yourself each time. Schedules live on the wallet, not on the scan:

POST /v1/wallet/schedules
{ "wallet_id": "…", "kind": "MABU", "interval_days": 7, "enabled": true }

interval_days runs from 1 to 90: daily at the tightest, quarterly at the loosest. Enabling a schedule makes its first run due straight away.

GET /v1/wallet/schedules?wallet_id=… lists what a wallet has, and DELETE /v1/wallet/schedules?wallet_id=…&kind=MABU removes one.

The endpoint is generic on purpose: kind names what recurs, so other kinds of recurring work will use the same three calls. MABU is the only kind today.

A schedule keeps its cadence even when a launch fails: the reason is kept in last_error and the next occurrence still stands, because one failed launch is not a reason to stop watching a wallet. A schedule on a chain the scanner cannot read is refused when you create it, rather than failing quietly on every occurrence.

Being told when something is found

A scan that flags raises an alert, which then travels through the notification channels your organization already configured.

Sourcemarket_abuse
SeverityHIGH, or CRITICAL when the worst pattern reaches 1.5x its threshold
Entitythe wallet, so the alert links back to it
Metadatathe scan id, every flagged pattern with its score and threshold, risk counterparties, and a link to the scan

A clean scan raises nothing: an alert for every scan would train everyone to ignore them.

A channel that filters on specific sources will not receive these until market_abuse is added to its list. A channel with no source filter receives them straight away.

Thresholds

Each detector raises a flag when its score reaches a threshold. GET /v1/mabu/thresholds returns the values in force, with the platform default and whether you have overridden it.

POST /v1/mabu/thresholds changes only the patterns you send:

{ "thresholds": { "pump_dump": 55, "wash_trading": 80 } }

POST /v1/mabu/thresholds/reset drops every override.

Limits worth knowing

A scan reads a bounded window of the wallet's history, not all of it. The report states exactly how much it read, in data.fetch, and which parts of the method it could not evaluate, in data.summary. Both are worth reading before drawing a conclusion from a score.

On this page