Code samples
The five flows you actually run: auth probe, list events, bulk export, register a webhook, and verify a webhook delivery. Every tab is copy-paste-runnable against https://api.velora.health.
The cURL tabs target a POSIX shell. The Python tabs use httpx (pip install httpx). The Node tabs target Node ≥ 20 (built-in fetch, no dependencies).
VELORA_API_KEY— yourvlk_live_...key from Authentication.VELORA_BASE_URL—https://api.velora.healthfor prod.
1. Auth probe
Hit a cheap read endpoint to confirm the key, scopes, and base URL are all wired correctly before anything else. Expect a 200 with an events array.
# Probe the audit-events endpoint with a tiny page.
# 200 → key is valid + has audit:read.
# 401 → header missing/malformed.
# 403 → key valid but missing audit:read scope.
curl -fsS \
-H "Authorization: Bearer $VELORA_API_KEY" \
"$VELORA_BASE_URL/api/v2/public/audit/events?limit=1"2. List PHI events in a window
Walk every PHI-flagged event from one window, paginating with next_cursor. The full reference is in Audit events.
# Pull the first page; capture next_cursor with jq and loop until done.
# Requires: jq (https://stedolan.github.io/jq/).
cursor=""
while :; do
resp=$(curl -fsS -G \
-H "Authorization: Bearer $VELORA_API_KEY" \
--data-urlencode "since=2026-05-01T00:00:00+00:00" \
--data-urlencode "until=2026-05-08T00:00:00+00:00" \
--data-urlencode "phi_involved=true" \
--data-urlencode "limit=1000" \
${cursor:+--data-urlencode "cursor=$cursor"} \
"$VELORA_BASE_URL/api/v2/public/audit/events")
echo "$resp" | jq -c '.events[]'
has_more=$(echo "$resp" | jq -r '.page.has_more')
[[ "$has_more" == "true" ]] || break
cursor=$(echo "$resp" | jq -r '.page.next_cursor')
done3. Export to NDJSON
Synchronous bulk export to NDJSON, capped at 10,000 rows per call. Inspect X-Velora-Truncated in the response headers to detect the cap and split the window.
curl -fsS -X POST \
-H "Authorization: Bearer $VELORA_API_KEY" \
-H "Content-Type: application/json" \
-D headers.txt \
-o events.ndjson \
"$VELORA_BASE_URL/api/v2/public/audit/export?format=ndjson" \
-d '{
"since": "2026-05-01T00:00:00+00:00",
"until": "2026-05-08T00:00:00+00:00",
"phi_involved": true
}'
# Check the truncation flag.
grep -i '^x-velora-truncated:' headers.txt4. Register a webhook
Subscribe a URL to every PHI + admin event. The response includes a one-shot secret; capture it before doing anything else.
curl -fsS -X POST \
-H "Authorization: Bearer $VELORA_API_KEY" \
-H "Content-Type: application/json" \
"$VELORA_BASE_URL/api/v2/public/audit/webhooks" \
-d '{
"url": "https://your-app.example.com/velora-webhook",
"event_filter": ["phi.", "admin."],
"description": "Production SIEM"
}'
# Response includes "secret": "..." — store it immediately.5. Verify a webhook delivery
Capture the raw body, parse the X-Velora-Signature header, reject stale deliveries (5-minute replay window), and constant-time compare the HMAC. The full signature spec is in Webhooks.
import hashlib
import hmac
import os
import time
from fastapi import FastAPI, HTTPException, Request
SECRET = os.environ["VELORA_WEBHOOK_SECRET"]
app = FastAPI()
def verify(body: bytes, header: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts["t"])
if abs(int(time.time()) - t) > 300:
return False
expected = hmac.new(
SECRET.encode(),
f"t={t}.".encode() + body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
@app.post("/velora-webhook")
async def receive(request: Request):
body = await request.body()
sig = request.headers.get("X-Velora-Signature", "")
if not verify(body, sig):
raise HTTPException(status_code=401, detail="bad signature")
# Idempotency: dedupe on (event.id, event.type).
event = await request.json()
return {"ok": True, "id": event["id"]}Full demo bundle
The Velora demo bundle (50-row synthetic claims CSV + byte-equivalent reference output + end-to-end bash/Python/Node quickstarts) is bundled alongside the API and smoke-tested in CI. To request a copy, email support@velora.health with your tenant ID — we'll send the tarball directly.
Handling errors at the call site
Production code wraps each call in a guard that distinguishes recoverable errors (429, 5xx) from terminal ones (401, 403, 422).
import random
import time
import httpx
def call_with_retry(client: httpx.Client, request: httpx.Request, *, max_attempts: int = 5) -> httpx.Response:
"""Call once; on 429/5xx, exponential backoff with jitter."""
for attempt in range(max_attempts):
r = client.send(request)
if r.status_code < 400:
return r
if r.status_code in (401, 403, 422):
r.raise_for_status() # terminal — bubble up.
# 429 honors Retry-After if present.
if r.status_code == 429 and "Retry-After" in r.headers:
time.sleep(int(r.headers["Retry-After"]))
continue
# 5xx and 429 without header: exponential backoff with jitter.
time.sleep((2 ** attempt) + random.uniform(0, 1))
r.raise_for_status()
return r # unreachableNext
Production integrations land in this order: auth probe → list events → register webhook → handle deliveries → backfill via export. For each step, the corresponding reference page lives at Authentication, Audit events, and Webhooks.