Skip to main content
API reference · Code samples

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).

Set these env vars first
  • VELORA_API_KEY — your vlk_live_... key from Authentication.
  • VELORA_BASE_URL https://api.velora.health for 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')
done

3. 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.txt

4. 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  # unreachable

Next

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.