DOCS
Overview Documentation Pricing Dashboard Get API Key

Quickstart

Get your API key, install the SDK, and screen your first address in under five minutes.

Create your account at app.useveris.finance
Open Settings > API Keys in the dashboard
Click Generate Key and copy the value. Store it securely.

Install the SDK

bash
# Python pip install veris-sdk # TypeScript / Node.js npm install @veris/sdk

Screen your first address

python
from veris import Veris client = Veris(api_key="vrs_sk_live_...") result = client.screen( address="0x7Ff9...D4eA", chain="ethereum" ) print(result.status) # "match" or "clear" print(result.list) # "OFAC SDN" print(result.confidence) # 0.998

Check the risk score

python
risk = client.risk("0x7Ff9...D4eA", chain="ethereum") print(risk.score) # 0.94 print(risk.detectors) # 7 detector outputs print(risk.shap_values) # per-feature attribution

Authentication

All API requests require a key. Production requests also require HMAC-SHA256 signing.

API Key

Include your key in the Authorization header on every request.

http
Authorization: Bearer vrs_sk_live_...

HMAC-SHA256 Signing

Production requests must include three additional headers for request integrity.

HeaderDescription
X-Request-SignatureHMAC-SHA256 of the canonical request string
X-TimestampUnix epoch in seconds. 30-second tolerance window.
X-NonceUnique token per request. 30-second SETNX TTL in Redis.

Signing algorithm

Build the canonical string: METHOD + \n + PATH + \n + TIMESTAMP + \n + NONCE + \n + SHA256(BODY)
Sign with HMAC-SHA256 using your secret key
Hex-encode the signature
Include in the X-Request-Signature header
python
import hmac, hashlib, time, uuid, json secret = "vrs_secret_..." body = json.dumps({"address": "0x7Ff9...D4eA", "chain": "ethereum"}) timestamp = str(int(time.time())) nonce = str(uuid.uuid4()) body_hash = hashlib.sha256(body.encode()).hexdigest() canonical = f"POST\n/v1/screen\n{timestamp}\n{nonce}\n{body_hash}" signature = hmac.new(secret.encode(), canonical.encode(), hashlib.sha256).hexdigest() headers = { "Authorization": "Bearer vrs_sk_live_...", "X-Request-Signature": signature, "X-Timestamp": timestamp, "X-Nonce": nonce, }
The SDK handles signing automatically. Manual signing is only needed for direct HTTP calls.

SDKs

Official Python and TypeScript SDKs with typed models, async support, and automatic retry.

Python

bash
pip install veris-sdk
python
from veris import Veris, AsyncVeris # Synchronous client = Veris(api_key="vrs_sk_live_...") result = client.screen(address="0x7Ff9...D4eA", chain="ethereum") # Async async def main(): client = AsyncVeris(api_key="vrs_sk_live_...") result = await client.screen(address="0x7Ff9...D4eA", chain="ethereum")

TypeScript

bash
npm install @veris/sdk
typescript
import { Veris } from '@veris/sdk'; const client = new Veris({ apiKey: 'vrs_sk_live_...' }); const result = await client.screen({ address: '0x7Ff9...D4eA', chain: 'ethereum', }); console.log(result.status); // "match" | "clear" console.log(result.confidence); // 0.998

Configuration

Environment VariableDefaultDescription
VERIS_API_KEYNoneAPI key (overrides constructor param)
VERIS_BASE_URLhttps://api.useveris.financeAPI base URL
VERIS_TIMEOUT30Request timeout in seconds

Error Handling

python
from veris.exceptions import VerisError, VerisRateLimitError, VerisAuthError try: result = client.screen(address="0x...", chain="ethereum") except VerisAuthError: print("Invalid API key or signature") except VerisRateLimitError as e: print(f"Rate limited. Retry after {e.retry_after}s") except VerisError as e: print(f"API error: {e.status_code} {e.message}")

Sandbox

Full API access with simulated data. Same endpoints, same auth, test data only.

Base URL: https://sandbox.api.useveris.finance

Test Addresses

AddressChainResultRisk Score
0x7Ff9...D4eAEthereumOFAC Match0.94
0xd71c...0f4aBaseClear0.12
0x3a4b...5c6dPolygonMixer Exposure0.78
TXk8...Lm3dTronClear0.08
7Kfm...x9WdSolanaThreat Intel0.67

Limits

Sandbox allows 1,000 API calls per day. The counter resets at 00:00 UTC. Webhook delivery is simulated but payloads are not sent to your endpoint.

Differences from Production

FeatureSandboxProduction
Sanctions dataSimulated (5 test addresses)Live OFAC SDN + threat intel
Risk scoresDeterministic (same input = same output)Live ML ensemble (15 models)
SAR filingSimulated (no FinCEN transmission)SFTP batch to FinCEN
WebhooksLogged but not deliveredDelivered with 5 retry attempts

POST /v1/screen

Screen an address against OFAC SDN, mixer registry, and threat intelligence labels.

POST/v1/screen

Parameters

NameTypeDescription
address RequiredstringBlockchain address to screen
chain RequiredstringChain identifier (ethereum, base, polygon, arbitrum, solana, tron, avalanche, bsc, optimism, celo)
include_risk OptionalbooleanInclude risk score in response. Default: false

Response

json
{ "status": "match", "list": "OFAC SDN", "confidence": 0.998, "blocked": true, "risk_score": 0.94, "cached": false, "latency_ms": 47 }

GET /v1/risk/{address}

Get a calibrated risk probability from the 15-model ML ensemble.

GET/v1/risk/{address}?chain=ethereum
NameTypeDescription
chain Requiredquery stringChain identifier

Response

json
{ "score": 0.94, "confidence_interval": [0.91, 0.97], "detectors": { "statistical_deviation": 0.91, "isolation_forest": 0.84, "temporal_pattern": 0.78, "velocity_shift": 0.92, "graph_topology": 0.65, "dormant_reactivation": 0.88, "regime_change": 0.71 }, "shap_values": { "velocity_7d": 0.23, "counterparty_diversity": 0.18, "mixer_exposure": 0.31 } }

GET /v1/entities/{id}

Retrieve an entity cluster with linked addresses, chain coverage, and confidence scores.

GET/v1/entities/{id}
json
{ "id": 1847, "entity_type": "high_risk", "risk_level": "critical", "addresses": [ {"address": "0x4a3f...c82d", "chain": "ethereum", "method": "behavioral", "confidence": 0.961}, {"address": "0xd71c...0f4a", "chain": "base", "method": "graph", "confidence": 0.887} ], "chains": ["ethereum", "base", "arbitrum", "polygon"], "total_volume_usd": 2400000, "cluster_confidence": 0.942 }

GET /v1/alerts

List compliance alerts with filtering by status, risk level, and chain.

GET/v1/alerts?status=open&risk_level=high&limit=20
NameTypeDescription
status Optionalstringopen, triaged, escalated, closed
risk_level Optionalstringlow, medium, high, critical
chain OptionalstringFilter by chain
limit OptionalintegerMax results (default 20, max 100)
offset OptionalintegerPagination offset

POST /v1/alerts/{id}/triage

Trigger the AI triage agent on an alert. Returns classification within 3 seconds.

POST/v1/alerts/{id}/triage
json
{ "classification": "needs_investigation", "confidence": 0.87, "reasoning": "High velocity transfers to mixer-adjacent addresses detected over 72-hour window.", "latency_ms": 2340 }

GET /v1/cases/{id}

Retrieve a compliance case with investigation results and SAR status.

GET/v1/cases/{id}
json
{ "id": 2847, "status": "pending_sar", "alert_ids": [4521, 4523], "investigation": { "summary": "Structured deposits below $10,000 across 3 chains...", "evidence_count": 14, "recommendation": "file_sar" }, "sar_status": "draft" }

POST /v1/sar/{case_id}

Generate a FinCEN Part V narrative from case evidence. The hallucination gate verifies every fact.

POST/v1/sar/{case_id}
json
{ "sar_id": "SAR-2847-001", "status": "draft", "narrative_preview": "Wallet 0x4a3f...c82d transacted $847,200 in USDC across 14 transfers...", "typology_codes": ["FIN-2019-A003", "31 USC 5318"], "facts_verified": 47, "fabricated_facts": 0 }

GET /v1/transfers

Query transfer history for an address with date range filtering.

GET/v1/transfers?address=0x...&chain=ethereum&limit=50
NameTypeDescription
address RequiredstringBlockchain address
chain RequiredstringChain identifier
start_date OptionalISO 8601Start of date range
end_date OptionalISO 8601End of date range
limit OptionalintegerMax results (default 50, max 500)

POST /v1/webhooks

Create a webhook subscription. Events deliver with HMAC-SHA256 signed payloads and exponential backoff retry.

POST/v1/webhooks

Request

json
{ "url": "https://your-app.com/webhooks/veris", "events": ["alert.created", "alert.triaged", "sar.filed"], "secret": "whsec_..." }

Available Events

EventDescription
alert.createdNew compliance alert generated
alert.triagedAlert classified by triage agent
case.escalatedAlert escalated to investigation case
sar.draftedSAR narrative generated
sar.filedSAR transmitted to FinCEN

WebSocket /v1/stream

Real-time transfer events across all 10 chains. Each event includes a pre-computed risk score.

WSwss://api.useveris.finance/v1/stream

Connection

javascript
const ws = new WebSocket('wss://api.useveris.finance/v1/stream', { headers: { 'Authorization': 'Bearer vrs_sk_live_...' } }); ws.on('message', (data) => { const event = JSON.parse(data); console.log(event.chain, event.amount_usd, event.risk_score); });

Filter Parameters

Send a JSON filter message after connection to narrow the stream.

json
{ "chains": ["ethereum", "base"], "min_amount_usd": 10000, "stablecoins": ["USDC", "USDT"] }

Error Codes

All errors return a JSON body with status code, error type, and human-readable message.

CodeTypeDescription
400bad_requestMissing or invalid parameter
401unauthorizedInvalid or missing API key
403forbiddenHMAC signature mismatch or expired nonce
404not_foundResource does not exist
429rate_limitedToo many requests. Check Retry-After header.
500internal_errorServer error. Retry with exponential backoff.
json
{ "error": { "type": "unauthorized", "message": "Invalid API key. Check your Authorization header.", "status": 401 } }

Rate Limits

Limits vary by plan. The API returns rate limit headers on every response.

PlanLimitWindow
Sandbox1,000 callsPer day
Growth1,000 callsPer minute
EnterpriseCustomCustom

Response Headers

HeaderDescription
X-RateLimit-LimitMaximum calls in the current window
X-RateLimit-RemainingCalls remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait (only on 429 responses)

Changelog

API version history and release notes.

v1.4.0March 2026
  • Added /v1/stream WebSocket endpoint for real-time transfer events
  • Added chain filter parameter to /v1/alerts
  • Risk scoring response now includes confidence intervals
v1.3.0February 2026
  • Entity resolution API returns 64-dimensional embeddings
  • Added confidence scores to cluster membership
  • New behavioral fingerprint method for address linking
v1.2.0January 2026
  • SAR generation endpoint includes typology codes
  • Hallucination gate verification added to SAR pipeline
  • Added sar.filed webhook event
v1.1.0December 2025
  • HMAC-SHA256 request signing required for production
  • Nonce window set to 30 seconds
  • Added rate limit response headers
v1.0.0November 2025
  • Initial API release with 16 REST endpoints
  • Python and TypeScript SDKs published
  • Sandbox environment launched