Alerts
Raise, triage and annotate the alerts Seqlense produces about your wallets, identities and order-book clients.
An alert is something Seqlense wants you to look at. It carries a severity, a source, optionally the subject it concerns, and a status you move as you work through it.
Alerts come from two places: Seqlense raises them itself, when a
market abuse scan (market_abuse) or
an order-book abuse run (orderbook_abuse) finds something, and you can raise
your own through the API. Both kinds behave identically once created.
Alerts belong to the workspace of the API key on the request. A dev
scoped key reads and writes the development workspace, whose alerts and
channels are separate from production.
The shape of an alert
| Field | Meaning |
|---|---|
severity | INFO, MEDIUM, HIGH or CRITICAL, nothing else |
source | who raised it: market_abuse, orderbook_abuse, or your own string (1-100 characters) |
title / message | the headline (1-200 characters) and the detail (not empty) |
entity_type / entity_id | what it is about, for example WALLET or IDENTITY plus the UUID. Empty strings when not set |
metadata | free-form JSON, kept as sent |
status | OPEN, ACKNOWLEDGED or RESOLVED (MUTED exists in storage, but no API call sets it) |
created_at | UTC, formatted YYYY-MM-DD HH:MM:SS |
source matters more than it looks: it is what notification channels filter
on, so pick one stable value per producer rather than a per-event one.
Raising one
POST /v1/alerts/ with source, severity, title and message:
curl -X POST https://monitoring.seqlense.com/api/v1/alerts/ \
-H "Authorization: Bearer sq_..." \
-H "Content-Type: application/json" \
-d '{
"source": "my-risk-engine",
"severity": "HIGH",
"title": "Unusual counterparty",
"message": "Wallet 0xabc... received funds from a newly created address.",
"entity_type": "WALLET",
"entity_id": "9a0c3e2b-7d41-4f5a-b6e8-1c2d3e4f5a6b",
"metadata": { "tx_hash": "0x1234...", "amount": "150" }
}'{ "status": "ok", "id": "5b1f7c1e-2a4d-4c8e-9f3a-8d2e6b0c1a47" }A few rules the endpoint applies:
severityandentity_typeare upper-cased, sohighis stored asHIGH.entity_id, when present, must be a UUID v4.- There is no de-duplication: posting the same alert twice creates two.
- The call waits for the notification channels to be delivered (see Notification channels) before it answers. Each outbound request has a 10 second timeout, and a failed delivery never fails the call.
Linking an alert to a subject is worth the effort: for WALLET and IDENTITY
alerts, the detail endpoint resolves the subject into a readable label and a
link, and lists the other alerts on the same wallet.
Finding them
GET /v1/alerts/ returns one page, newest first:
curl "https://monitoring.seqlense.com/api/v1/alerts/?status=OPEN&severity=CRITICAL&limit=50" \
-H "Authorization: Bearer sq_..."| Parameter | Effect |
|---|---|
status, severity, source, entity_type | exact match |
tag_id | only alerts carrying this tag (ignored if not a UUID) |
from, to | day bounds YYYY-MM-DD, both inclusive |
q | substring of title, message or source (ignored above 100 characters) |
page | 1-based, default 1 |
limit | page size, default 20, clamped to 10-100 |
The response is { "alerts": [...], "total": 42, "page": 1, "limit": 50 },
where total counts every alert matching the filters.
GET /v1/alerts/count returns total, open and critical_open for the whole
workspace, the numbers you would put on a dashboard badge. open counts only
OPEN alerts, not acknowledged ones.
GET /v1/alerts/detail?id=... returns one alert with:
| Field | Content |
|---|---|
metadata | parsed back into JSON |
subject | { kind, label, url, identity } for wallet, identity and order-book client alerts, otherwise null |
related | up to 10 other alerts on the same wallet or order-book client |
acknowledged_by / resolved_by | user id, 0 when done with an API key |
deliveries | every webhook, Discord or Slack delivery attempt and its result |
Working through them
| Call | Effect |
|---|---|
POST /v1/alerts/acknowledge { "id": ... } | OPEN becomes ACKNOWLEDGED |
POST /v1/alerts/resolve { "id": ... } | OPEN or ACKNOWLEDGED becomes RESOLVED |
POST /v1/alerts/bulk-action { "action": "resolve", "ids": [...] } | the same on up to 100 alerts |
DELETE /v1/alerts/?id=... | removes the alert and its delivery records |
These calls answer {"status":"ok"} even when nothing changed: an unknown id,
an alert that is already resolved, or acknowledging something that is not
OPEN. Read the alert back if you need to know its state. A resolved alert
cannot be reopened.
Notes
Investigators can attach notes to an alert:
curl -X POST https://monitoring.seqlense.com/api/v1/alerts/notes \
-H "Authorization: Bearer sq_..." \
-H "Content-Type: application/json" \
-d '{ "alert_id": "5b1f7c1e-2a4d-4c8e-9f3a-8d2e6b0c1a47", "text": "Known OTC desk, checking with the client." }'GET /v1/alerts/notes?alert_id=...lists them newest first, each withid,text,created_by,created_by_nameandcreated_at.POSTneedstextof 1-2000 characters and returns404if the alert is not in your workspace.DELETE /v1/alerts/notes?id=...takes the note id and returns404if it does not exist.
History
GET /v1/alerts/history is the append-only event log: one event per alert
raised, as it was at that moment. It is filtered by severity and source,
paginated with limit (default 50, max 200) and offset, and returns
{ "events": [...], "total", "limit", "offset" }.
Events are never updated: their status is always OPEN, and events of
deleted alerts remain. Use it to answer "what was raised, and when". It is not
a delivery log; delivery results live in the deliveries of each alert.
Signal heatmap
GET /v1/alerts/heatmap?source=market_abuse&days=30 shows which detector
signals fire most across all your scans, including scans that raised no alert.
source is market_abuse or orderbook_abuse; days defaults to 30, 0
means all time.
{
"runs": 12,
"patterns": [
{
"pattern": "wash_trading",
"title": "Wash trading",
"hits": 20,
"rate": 0.5,
"quiet": [],
"signals": [
{ "id": "w1", "label": "Self-matched trades", "hits": 20, "evaluated": 40, "rate": 0.5 }
]
}
]
}hits is how often a signal was confirmed, evaluated how often it could be
assessed, and rate is their ratio rounded to 3 decimals. Signals that never
fired are listed by label in quiet.
Where alerts go
Every new alert is forwarded to the workspace's active notification channels whose filters it matches: a signed webhook, Discord, or Slack. See Notification channels.
For every field and error message, see the API reference.