Order Book Abuse
Order-book market-abuse runs.
Creates a run over your organization's order flow and hands it off for execution. Every
field is optional: send {} to scan every book of your own organization over the
automatic window.
Scope. venue and instrument narrow the run to one venue, one instrument, or one
book. Leaving both empty is the normal case: a run narrowed to one book cannot see
cross-venue smurfing.
Window. If you give from and/or to they are used as given (a missing side is
unbounded). If you give neither, the window chains onto the last DONE run with exactly
the same scope: to is now, and from is that run's window_to minus 24 hours, or 7
days ago if that reaches further back. The first run on a scope is unbounded: it reads
as much history as the scanner's 500 000-event budget allows.
The run uses your organization's current thresholds. Runs are asynchronous: the run is
DISPATCHED when this call returns, and its report appears later on
GET /v1/obmabu/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
application/json
curl -X POST "https://example.com/v1/obmabu/runs" \ -H "Content-Type: application/json" \ -d '{ "venue": "BYBIT", "from": "2026-09-01T00:00:00Z", "to": "2026-09-08T00:00:00Z" }'{ "status": "ok", "run_id": "0f9a1c2e-3b4d-4e5f-8a9b-0c1d2e3f4a5b", "window": { "from": "2026-09-01 00:00:00", "to": "2026-09-08 00:00:00" }}Lifecycle record of one run of your organization, with its scope and window. It never contains findings; fetch the report with GET /v1/obmabu/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 run_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/obmabu/runs/detail?id=string"{ "id": "0f9a1c2e-3b4d-4e5f-8a9b-0c1d2e3f4a5b", "organization": "acme", "venue": "BYBIT", "instrument": "", "scope": "acme · BYBIT", "window_from": "2026-09-01 00:00:00", "window_to": "2026-09-08 00:00:00", "status": "DONE", "dispatch_error": "", "created_by": 0, "created_at": "2026-09-08 09:00:12", "started_at": "2026-09-08 09:00:13", "finished_at": "2026-09-08 09:21:40"}The report of a finished run, returned exactly as the scanner filed it. A 404 means
either that the run has not published anything yet (the normal state of a run still
going: poll, do not treat it as an error) or that the run is not one of yours. A run that
has published nothing 45 minutes after dispatch is marked FAILED.
Fetching a report also settles the run: a run still PENDING or DISPATCHED becomes
DONE, and alerts are raised at that moment for every (client, book) whose score
reaches your threshold on some pattern.
The payload is the ingestion envelope; the report is under data. Read data.adequacy
and data.summary.dataLimitations first (they say what the feed allowed the scanner to
see), then data.findings.
Authorization
ApiKeyAuth Send your API key as a bearer token: Authorization: Bearer sq_YOUR_API_KEY.
In: header
Query Parameters
The run_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/obmabu/runs/result?run_id=string"{ "eventId": "string", "type": "job.success.obmabu", "source": "string", "ingestedAt": "2019-08-24T14:15:22Z", "meta": {}, "data": { "tool": "monit-runner-marketabuse-orderbook", "version": "string", "runId": "string", "organization": "string", "generatedAt": "2019-08-24T14:15:22Z", "durationMs": 0, "api": {}, "fetch": {}, "adequacy": {}, "books": [ {} ], "clients": [ {} ], "findings": [ { "pattern": "wash_trading", "title": "string", "clientId": "string", "venue": "string", "instrument": "string", "profile": "MARKET_MAKER", "score": 0, "flagThreshold": 0, "flagged": true, "methodMaxScore": 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": {} }}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"
- "DONE"
- "FAILED"
Exact organization (tenancy key) the run scanned.
length <= 255Exact venue. Uppercased before matching.
^[A-Za-z0-9/_.-]+$length <= 60Prefix of a run id (letters, digits and -).
^[A-Za-z0-9-]+$length <= 64Page size, clamped to 1..100.
1 <= value <= 10025Rows to skip, capped at 100000.
0 <= value <= 1000000Response Body
application/json
application/json
curl -X GET "https://example.com/v1/obmabu/runs/search"{ "runs": [ { "id": "string", "organization": "string", "venue": "string", "instrument": "string", "scope": "string", "window_from": "string", "window_to": "string", "status": "PENDING", "dispatch_error": "string", "created_by": 0, "created_at": "string", "started_at": "string", "finished_at": "string" } ], "total": 0, "limit": 0, "offset": 0}The score each detector must reach to flag, per pattern. Values you have not customised
fall back to the defaults: wash_trading 70, order_lifecycle 70, ramping 70,
smurfing 60. These bars decide alerting, 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/obmabu/thresholds"{ "thresholds": [ { "pattern": "wash_trading", "label": "Wash trading", "default": 70, "threshold": 70, "customised": false }, { "pattern": "order_lifecycle", "label": "Order lifecycle", "default": 70, "threshold": 65, "customised": true }, { "pattern": "ramping", "label": "Ramping", "default": 70, "threshold": 70, "customised": false }, { "pattern": "smurfing", "label": "Smurfing", "default": 60, "threshold": 60, "customised": false } ]}Only the patterns you send are changed. The whole body is validated before anything is written: an unknown pattern or a non-integer value rejects the request and changes nothing. Integers outside 0..100 are clamped into range, not rejected. 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
application/json
curl -X POST "https://example.com/v1/obmabu/thresholds" \ -H "Content-Type: application/json" \ -d '{ "thresholds": { "order_lifecycle": 65 } }'{ "thresholds": [ { "pattern": "wash_trading", "label": "Order lifecycle", "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
application/json
curl -X POST "https://example.com/v1/obmabu/thresholds/reset" \ -H "Content-Type: application/json" \ -d '{}'{ "thresholds": [ { "pattern": "wash_trading", "label": "Order lifecycle", "default": 0, "threshold": 0, "customised": true } ]}