API Reference

Every endpoint, documented.

Multi-chain deposit and withdrawal monitoring, signed webhooks, a non-custodial HD payment gateway, a real-time stream, and AML screening. All JSON is camelCase; list endpoints return a paged envelope.

Base URL & authentication

Base: https://api.arguspulse.net + /api/v1. Two tenant-scoped schemes: a Keycloak JWT (Authorization: Bearer <token>) for user/admin sessions, or an API key (X-API-Key: <key>) for machine-to-machine. Scoped keys carry read and/or write; a read-only key making a write gets 403.

# list endpoints return a paged envelope (pageSize clamped to 100)
{ "items": [...], "totalCount": 0, "page": 1, "pageSize": 20,
  "totalPages": 0, "hasNextPage": false, "hasPreviousPage": false }

# errors: 4xx → { "error": "<message>" }, 429 on quota/rate limit. Stack traces never leaked.

Wallets

/api/v1/wallets - track addresses; detections fire webhooks and the live stream

GET
/api/v1/wallets
Paged list of watched addresses.
POST
/api/v1/wallets/
{ network, address, label?, direction? } - direction: Both | IncomingOnly | OutgoingOnly.
POST
/api/v1/wallets/{id}/enable · /disable
Toggle monitoring without deleting the row.
DELETE
/api/v1/wallets/{id}
Soft-delete a watched address.

Webhooks

/api/v1/webhooks - HMAC-SHA256 signed, retried, dead-lettered. Verify every delivery.

GET
/api/v1/webhooks
Paged list of endpoints.
POST
/api/v1/webhooks/
{ network?, url, secret, deliveryMode?, channelType?, directionFilter?, assetFilter? }. channelType: 0 Webhook · 1 Slack · 2 Telegram. URLs are SSRF-validated; secrets AES-GCM encrypted at rest.
POST
/api/v1/webhooks/{id}/test
Send a signed test event → { success, statusCode, error?, eventId }.
POST
/api/v1/webhooks/{id}/enable · /disable
Active toggle.
DELETE
/api/v1/webhooks/{id}
Soft-delete.
GET
/api/v1/webhooks/deliveries
Delivery audit (filter ?network=). Replay: POST /deliveries/{id}/replay.
GET
/api/v1/webhooks/dead-letters
Permanently failed deliveries.
Webhook / callback signature (verify the raw body)
# headers on every delivery
X-ArgusPulse-Event-Id:   <event id>
X-ArgusPulse-Timestamp:  <unix seconds>
X-ArgusPulse-Signature:  sha256=<hex>

hex = lowercase( HMAC_SHA256( secret, `${timestamp}.${rawBody}` ) )
# reject if computed != header, or |now - timestamp| > 300s (replay guard)

Payment gateway (HD addresses)

/api/v1/payments - non-custodial: xpub once per network, a fresh BIP32 address per session. EVM / TRON / Bitcoin (Solana ed25519 not supported).

PUT
/api/v1/payments/config
{ network, xpub, callbackSecret? } - validated by a test derivation; returns masked xpub.
GET
/api/v1/payments/config
List configs (xpub masked; secret never returned).
POST
/api/v1/payments/
{ network, asset?, expectedAmount?, reference?, callbackUrl? } → session with a unique address. reference makes it idempotent. Lifecycle: Pending → Detected → Confirmed (or Expired).
GET
/api/v1/payments · /{id}
List / get sessions.
POST
/api/v1/payments/{id}/cancel
Cancel a pending session.

Real-time stream, analytics & chain reads

live detections, reconciliation export, on-chain balances

GET
/api/v1/stream
text/event-stream of new detections (event: detection). Use fetch-streaming (not EventSource) for the auth header; optional ?since=<ISO> backfill. The SDK's streamDetections() async generator handles it.
GET
/api/v1/analytics/deposits?from=&to=
Count-based summary: totals + by-day / by-network / by-token (default last 30d).
GET
/api/v1/analytics/reconciliation.csv?from=&to=
CSV statement for accounting.
GET
/api/v1/chains/{network}/balance/{address}?token=
On-chain balance (EVM): native + optional ERC-20. Non-EVM → 400.

Compliance (AML)

every counterparty auto-screened against a sanctions / OFAC SDN blocklist, with a 0-100 risk score

GET
/api/v1/aml/alerts
Paged; ?status=Open|Resolved|Dismissed; each alert carries a riskScore (0-100). Badge: /aml/alerts/open-count.
POST
/api/v1/aml/alerts/{id}/resolve · /dismiss
{ notes? }. Every counterparty is screened automatically; you triage your own alerts.
Interactive reference

An interactive OpenAPI / Swagger explorer is served at GET /swagger on a development instance (intentionally disabled in production so the API surface is not exposed). For code samples in TypeScript, Python, and PHP, see the Quickstart.