Skip to main content
Platform alerts for sanctions matches, river level warnings, dark fleet events, and more. The alert system includes a unified cross-product inbox, a rule engine for custom filtering, multi-channel notifications, and a delivery audit trail.

GET /api/v1/alerts

Requires API key.
Get active platform alerts. Filter by severity or type. Parameters
NameTypeRequiredDescription
severitystringcritical, warning, or info
typestringsanctions_match, river_level, dark_fleet
unacknowledgedstringtrue to only show unread alerts
cursorstringISO timestamp for cursor pagination
limitnumberDefault 20, capped by your access tier
Response
{
  "alerts": [...],
  "count": 12,
  "unacknowledged": 3,
  "tier": "pro",
  "pagination": { "limit": 20, "has_more": true, "next_cursor": "2026-04-17T08:00:00Z" }
}
Example
curl -H "X-API-Key: YOUR_KEY" \
  https://axiomoverwatch.io/api/v1/alerts?severity=critical

GET /api/v1/alerts/unified

Requires API key.
Unified cross-product inbox combining maritime and Locus alerts in a single chronological feed. Aggregates platform alerts, dark events, spoofing detections, and Locus score-change alerts. Parameters
NameTypeRequiredDescription
productstringall (default), overwatch, or locus
severitystringcritical, warning, or info
watchliststringtrue to only include watched vessels
portfoliostringLocus portfolio id filter
statestringall (default), open, read, resolved, snoozed
cursorstringISO timestamp for cursor pagination
limitnumberDefault 25, max 100
Response
{
  "alerts": [
    {
      "id": "dark_event:456",
      "source": "dark_event",
      "product": "overwatch",
      "severity": "critical",
      "title": "AIS gap detected — MV Meridian",
      "description": "Signal lost for 18 hours in Gulf of Guinea",
      "occurred_at": "2026-04-18T03:22:00Z",
      "state": "open",
      "metadata": { "imo_number": "9622629", "gap_hours": 18 }
    }
  ],
  "count": 1,
  "pagination": { "limit": 25, "has_more": false, "next_cursor": null },
  "filters": { "product": "all", "severity": null, "watchlist": false, "portfolio": null, "state": "all" }
}
Example
curl -H "X-API-Key: YOUR_KEY" \
  https://axiomoverwatch.io/api/v1/alerts/unified?product=overwatch&state=open

POST /api/v1/alerts/unified/state

Requires API key.
Set per-user state for a unified alert—mark it as read, resolved, snoozed, or reopen it. Parameters
NameTypeRequiredDescription
alert_idstringAlert id in source:id format (e.g. dark_event:456)
actionstringread, resolve, snooze, or open
snooze_untilstringISO timestamp; defaults to +24 hours for snooze
Response
{
  "ok": true,
  "alert_id": "dark_event:456",
  "action": "resolve",
  "state": { "read_at": "2026-04-18T10:00:00Z", "resolved_at": "2026-04-18T10:00:00Z", "snoozed_until": null }
}
Example
curl -X POST -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  https://axiomoverwatch.io/api/v1/alerts/unified/state \
  -d '{"alert_id": "dark_event:456", "action": "resolve"}'

Alert rules

Define custom rules that filter the unified alert stream using boolean expressions. Rules support nested and/or groups and can match on product, severity, event type, vessel IMO, or any metadata field. Every rule change is versioned so you can audit who changed what and when.

GET /api/v1/alerts/rules

Requires API key.
List your alert rules. Response
{
  "rules": [
    {
      "id": 1,
      "name": "Critical dark events",
      "description": "Flag critical AIS gaps on watchlisted tankers",
      "expression": {
        "kind": "group",
        "operator": "and",
        "conditions": [
          { "kind": "condition", "field": "severity", "op": "eq", "value": "critical" },
          { "kind": "condition", "field": "source", "op": "eq", "value": "dark_event" }
        ]
      },
      "severity_override": null,
      "active": true,
      "dedupe_window_minutes": 60,
      "version": 3,
      "created_at": "2026-04-10T09:00:00Z",
      "updated_at": "2026-04-18T14:30:00Z"
    }
  ]
}
Example
curl -H "X-API-Key: YOUR_KEY" \
  https://axiomoverwatch.io/api/v1/alerts/rules

POST /api/v1/alerts/rules

Requires API key.
Create a new alert rule. Parameters
NameTypeRequiredDescription
namestringRule name
descriptionstringHuman-readable description
expressionobjectBoolean expression tree (see below)
severity_overridestringOverride the alert’s severity when this rule matches
dedupe_window_minutesnumberSuppress duplicate matches within this window (1–1440, default 60)
activebooleanWhether the rule is active (default true)

Expression format

Expressions are recursive trees of groups and conditions:
{
  "kind": "group",
  "operator": "and",
  "conditions": [
    { "kind": "condition", "field": "product", "op": "eq", "value": "overwatch" },
    {
      "kind": "group",
      "operator": "or",
      "conditions": [
        { "kind": "condition", "field": "source", "op": "eq", "value": "dark_event" },
        { "kind": "condition", "field": "source", "op": "eq", "value": "spoofing_alert" }
      ]
    }
  ]
}
Supported condition fields
FieldDescription
productoverwatch or locus
severitycritical, warning, or info
sourceplatform, dark_event, spoofing_alert, locus_alert
event_typeAlert event type string
entity_idEntity identifier
imo_number7-digit IMO number
metadata.*Any key in the alert’s metadata object (e.g. metadata.gap_hours)
Supported operators: eq, neq, in, contains, gte, lte Example
curl -X POST -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  https://axiomoverwatch.io/api/v1/alerts/rules \
  -d '{
    "name": "Critical dark events",
    "expression": {
      "kind": "group",
      "operator": "and",
      "conditions": [
        { "kind": "condition", "field": "severity", "op": "eq", "value": "critical" },
        { "kind": "condition", "field": "source", "op": "eq", "value": "dark_event" }
      ]
    },
    "dedupe_window_minutes": 120
  }'

PATCH /api/v1/alerts/rules

Requires API key.
Update an existing rule. Changes are versioned—pass an optional notes field to record why the change was made. Parameters
NameTypeRequiredDescription
idnumberRule id
namestringUpdated name
expressionobjectUpdated expression
activebooleanEnable or disable the rule
notesstringVersion history note
Example
curl -X PATCH -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  https://axiomoverwatch.io/api/v1/alerts/rules \
  -d '{"id": 1, "active": false, "notes": "Pausing during port maintenance window"}'

DELETE /api/v1/alerts/rules

Requires API key.
Delete a rule. Parameters
NameTypeRequiredDescription
idnumberRule id (query param)
Example
curl -X DELETE -H "X-API-Key: YOUR_KEY" \
  "https://axiomoverwatch.io/api/v1/alerts/rules?id=1"

POST /api/v1/alerts/rules/dry-run

Requires API key.
Test a rule expression against recent alerts without saving it. Use this to preview how many alerts a rule would match before creating it. Parameters
NameTypeRequiredDescription
expressionobjectRule expression to test
productstringall (default), overwatch, or locus
severitystringFilter by severity before evaluation
watchlistOnlybooleanOnly test against watchlisted vessel alerts
portfolioIdstringScope to a Locus portfolio
limitnumberMax alerts to evaluate (1–200, default 100)
Response
{
  "evaluated": 87,
  "matched": 12,
  "alerts": [...]
}
Example
curl -X POST -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  https://axiomoverwatch.io/api/v1/alerts/rules/dry-run \
  -d '{
    "expression": {
      "kind": "group",
      "operator": "and",
      "conditions": [
        { "kind": "condition", "field": "severity", "op": "eq", "value": "critical" },
        { "kind": "condition", "field": "source", "op": "in", "value": ["dark_event", "spoofing_alert"] }
      ]
    },
    "product": "overwatch"
  }'

Alert channels

Configure where alert notifications are delivered. You can enable multiple channels simultaneously—each channel is independently toggled and tested. Supported channels: Slack, Microsoft Teams, email, and custom webhook.

GET /api/v1/alerts/channels

Requires API key.
List your configured alert channels. Secrets and webhook URLs are partially masked in the response. Response
{
  "channels": [
    {
      "channel": "slack",
      "enabled": true,
      "config": { "webhook_url": "https://hooks.slack.com/services/T00.../B00.../xxxx" }
    },
    {
      "channel": "webhook",
      "enabled": true,
      "config": { "url": "https://example.com/hooks/axiom", "secret": "****" }
    }
  ]
}
Example
curl -H "X-API-Key: YOUR_KEY" \
  https://axiomoverwatch.io/api/v1/alerts/channels

PUT /api/v1/alerts/channels

Requires API key.
Create or update a channel configuration. Parameters
NameTypeRequiredDescription
channelstringslack, email, teams, or webhook
enabledbooleanWhether the channel is active
configobjectChannel-specific configuration (see below)
Channel configuration
ChannelConfig fields
slackwebhook_url — must be a https://hooks.slack.com/services/... URL
teamswebhook_url — any valid HTTPS URL
emailto — comma-separated email addresses
webhookurl — HTTPS endpoint; secret (optional) — HMAC-SHA256 signing key, sent as X-Axiom-Signature header
Example
curl -X PUT -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  https://axiomoverwatch.io/api/v1/alerts/channels \
  -d '{
    "channel": "slack",
    "enabled": true,
    "config": { "webhook_url": "https://hooks.slack.com/services/T00.../B00.../xxxx" }
  }'

DELETE /api/v1/alerts/channels

Requires API key.
Remove a channel configuration. Parameters
NameTypeRequiredDescription
channelstringChannel to remove (query param)
Example
curl -X DELETE -H "X-API-Key: YOUR_KEY" \
  "https://axiomoverwatch.io/api/v1/alerts/channels?channel=teams"

POST /api/v1/alerts/channels/test

Requires API key.
Send a test notification through a configured channel. The test message uses sample vessel data so you can verify formatting and delivery. Parameters
NameTypeRequiredDescription
channelstringslack, email, teams, or webhook
Example
curl -X POST -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  https://axiomoverwatch.io/api/v1/alerts/channels/test \
  -d '{"channel": "slack"}'

Alert deliveries

Track the status of every alert notification sent through your configured channels. The delivery ledger records each attempt, retries with exponential backoff, and moves permanently failed deliveries to a dead-letter queue.

GET /api/v1/alerts/deliveries

Requires API key.
List recent alert deliveries and any dead-lettered failures. Parameters
NameTypeRequiredDescription
channelstringFilter by channel type
statusstringFilter by delivery status
limitnumberDefault 50, max 200
Response
{
  "deliveries": [
    {
      "id": 42,
      "channel": "slack",
      "event_key": "dark_event:456",
      "event_type": "dark_event",
      "status": "delivered",
      "attempts": 1,
      "delivered_at": "2026-04-18T03:23:01Z",
      "last_error": null,
      "created_at": "2026-04-18T03:22:58Z"
    }
  ],
  "dead_letters": [],
  "count": 1
}
Example
curl -H "X-API-Key: YOUR_KEY" \
  https://axiomoverwatch.io/api/v1/alerts/deliveries?channel=slack