Market Abuse
On-chain market-abuse scans.
Read-only view of the alerts raised by the legacy market-abuse engine for your
organization, returned verbatim. No legacy account gives org_id: null, count: 0,
alerts: [].
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
Clamped to 1..200.
1 <= value <= 20050Response Body
application/json
application/json
application/json
curl -X GET "https://example.com/v1/mabu/retro/alerts"{ "org_id": null, "count": 0, "alerts": [ {} ]}Read-only view of the identities held by the legacy market-abuse engine for your
organization, returned verbatim. No legacy account gives org_id: null, count: 0,
identities: [].
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
Clamped to 1..200.
1 <= value <= 20050Response Body
application/json
application/json
application/json
curl -X GET "https://example.com/v1/mabu/retro/identities"{ "org_id": null, "count": 0, "identities": [ {} ]}Read-only view of the scans your organization ran on the legacy market-abuse engine,
returned as the legacy engine sends them. Your organization is resolved server side; if
it has no legacy account the call succeeds with org_id: null, count: 0 and an empty
scans array. Legacy data exists for the production workspace only.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
Only scans of this wallet. Letters and digits only; any other value is ignored.
^[A-Za-z0-9]+$length <= 190Clamped to 1..200.
1 <= value <= 20050Response Body
application/json
application/json
application/json
curl -X GET "https://example.com/v1/mabu/retro/scans"{ "org_id": null, "count": 0, "scans": []}Creates a scan run and hands it off for execution. The returned job_id is the run id
and also the scan_id its report is filed under, so it is the only identifier you need
to keep.
chain accepts the full chain name or the short code used by the wallet module (case
insensitive): ethereum/eth, bitcoin/btc, solana/sol, bsc/bnb,
polygon/matic, arbitrum/arb, optimism/op, base. Any other chain is refused
by name, for example Market abuse scans do not cover TRX - supported chains: ....
The wallet is added to your organization's wallets if it is not there yet (best effort, never blocks the launch). The scan uses your organization's current thresholds.
Scans are asynchronous: the run is DISPATCHED when this call returns, and its report
appears later on GET /v1/mabu/runs/result.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/mabu/runs" \ -H "Content-Type: application/json" \ -d '{ "wallet": "0xd90e2f925da726b50c4ed8d0fb90ad053324f31b", "chain": "ethereum" }'{ "status": "ok", "job_id": "2966a324-2b67-48ee-a0e1-3fe6b123e1b2"}Lifecycle record of one run of your organization. It never contains findings; fetch the report with GET /v1/mabu/runs/result.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
Run id (the job_id returned at launch). Must be a UUID v4.
uuidResponse Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/mabu/runs/detail?id=497f6eca-6276-4993-bfeb-53cbbbba6f08"{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "wallet": "string", "chain": "ethereum", "status": "PENDING", "dispatch_error": "string", "created_at": "2026-09-20 10:12:03", "started_at": "string", "finished_at": "string"}The report of a finished scan, returned exactly as the scanner filed it. A 404 means
the scan has not published anything yet, which is the normal state of a run that is
still going: poll (every 30 seconds is plenty), do not treat it as an error. A run that
has published nothing 10 minutes after dispatch is marked FAILED.
Fetching a report also settles the run: a run of yours still PENDING, DISPATCHED or
RUNNING becomes DONE once its report is found, and an alert is raised at that moment
if a pattern reaches your threshold.
The payload is the ingestion envelope; the report itself is under data. Read
data.summary first, then data.patterns for the detail of each detector. The
flagged flag inside a pattern is the scanner's own verdict against its built-in bar;
compare score with your configured threshold to get your organization's verdict.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
The job_id returned at launch.
^[A-Za-z0-9_-]+$length <= 64Response Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/mabu/runs/result?scan_id=string"{ "eventId": "d6703cc8-9e79-415d-ac03-a4dc7f6ab43c", "type": "job.success.mabu", "source": "string", "timestamp": "2019-08-24T14:15:22Z", "ingestedAt": "2019-08-24T14:15:22Z", "meta": {}, "data": { "tool": "string", "version": "string", "scanId": "string", "wallet": "string", "blockchain": "string", "generatedAt": "2019-08-24T14:15:22Z", "durationMs": 0, "api": {}, "fetch": {}, "walletStats": {}, "graph": {}, "riskCounterparties": [ {} ], "market": {}, "traversal": {}, "tokens": [ {} ], "patterns": { "property1": { "title": "string", "score": 0, "flagThreshold": 0, "flagged": true, "docMaxScore": 0, "evaluableMaxScore": 0, "pointsNotEvaluable": 0, "scoringCoveragePct": 0, "confidence": 0, "notes": [ "string" ], "signals": [ { "id": "string", "label": "string", "points": 0, "status": "confirmed", "reason": "string", "evidence": null, "exclusiveGroup": "string" } ] }, "property2": { "title": "string", "score": 0, "flagThreshold": 0, "flagged": true, "docMaxScore": 0, "evaluableMaxScore": 0, "pointsNotEvaluable": 0, "scoringCoveragePct": 0, "confidence": 0, "notes": [ "string" ], "signals": [ { "id": "string", "label": "string", "points": 0, "status": "confirmed", "reason": "string", "evidence": null, "exclusiveGroup": "string" } ] } }, "summary": {}, "_truncated": null }}Runs of your organization, newest first. All filters are optional and combined with AND. A filter with an unrecognised value is ignored rather than rejected.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
Run status. Case insensitive.
Value in
- "PENDING"
- "DISPATCHED"
- "RUNNING"
- "DONE"
- "FAILED"
- "CANCELLED"
Full chain name only (short codes like eth are not accepted here).
Value in
- "ethereum"
- "bitcoin"
- "bsc"
- "polygon"
- "arbitrum"
- "optimism"
- "base"
- "solana"
Exact wallet address.
length <= 190Prefix of a run id (hex digits and - only).
^[0-9a-fA-F-]+$length <= 36Page size, clamped to 1..200.
1 <= value <= 20025Rows to skip. Negative values become 0.
0 <= value0Response Body
application/json
application/json
curl -X GET "https://example.com/v1/mabu/runs/search"{ "runs": [ { "id": "2966a324-2b67-48ee-a0e1-3fe6b123e1b2", "wallet": "0xd90e2f925da726b50c4ed8d0fb90ad053324f31b", "chain": "ethereum", "status": "DONE", "dispatch_error": "", "created_at": "2026-09-20 10:12:03", "started_at": "2026-09-20 10:12:04", "finished_at": "2026-09-20 10:17:41" } ], "total": 1, "limit": 25, "offset": 0}The score each detector must reach to flag, per pattern. Values you have not customised
fall back to the defaults: pump_dump 60, insider_trading 70, smurfing 60,
wash_trading 70. These bars decide alerting: a scan raises an alert when a pattern's
score reaches your threshold, whatever the scanner's own flagged says.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Response Body
application/json
application/json
curl -X GET "https://example.com/v1/mabu/thresholds"{ "thresholds": [ { "pattern": "pump_dump", "label": "Pump & Dump", "default": 60, "threshold": 55, "customised": true }, { "pattern": "insider_trading", "label": "Insider Trading", "default": 70, "threshold": 70, "customised": false }, { "pattern": "smurfing", "label": "Smurfing", "default": 60, "threshold": 60, "customised": false }, { "pattern": "wash_trading", "label": "Wash Trading", "default": 70, "threshold": 80, "customised": true } ]}Only the patterns you send are changed; the others keep their current value. The whole
body is validated before anything is written: an unknown pattern, a non-integer, or a
value outside 0..100 rejects the request and changes nothing. Returns the effective
thresholds, same shape as GET /v1/mabu/thresholds.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/mabu/thresholds" \ -H "Content-Type: application/json" \ -d '{ "thresholds": { "pump_dump": 55, "wash_trading": 80 } }'{ "thresholds": [ { "pattern": "pump_dump", "label": "Pump & Dump", "default": 0, "threshold": 0, "customised": true } ]}Drops every customised value, restoring the defaults. The action takes no fields, but
the body must still be JSON: send {} (an empty body returns 404). Returns the
effective thresholds.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "https://example.com/v1/mabu/thresholds/reset" \ -H "Content-Type: application/json" \ -d '{}'{ "thresholds": [ { "pattern": "pump_dump", "label": "Pump & Dump", "default": 0, "threshold": 0, "customised": true } ]}