Developers
CLV Intelligence API
Read-only access to CLV's government-verified reimbursement policy alerts. Every alert links to its primary government source. Enterprise/partner plans only.
Machine-readable spec: /api/v1/openapi.json
Authentication
Create a key on your account page (Enterprise/partner plans). It is shown once — store it securely. Revoke it any time; revocation is immediate and audit-logged.
Rate limiting
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 includes Retry-After (seconds). Limits are per key.
Pagination
List endpoints return `nextCursor`. Pass it back as `?cursor=` for the next page. A null nextCursor means the last page. Cursors are opaque — pass them verbatim.
Endpoints
/api/v1/alertsList alerts
The alert feed, newest first, with cursor pagination. Results are scoped to your plan — paid analysis fields are omitted for plans that don't include them.
specialty(query) — Specialty slug filter.mac(query) — MAC jurisdiction (includes National).payer_type(query)min_signal(query) — Minimum signal score.from(query)to(query)code(query) — CPT/HCPCS/ICD-10 cross-reference.cursor(query) — Opaque pagination cursor.limit(query)
/api/v1/alerts/{id}Get one alert
id(path)
/api/v1/codes/{code}/alertsAlerts for a code
code(path)
/api/v1/policies/{policy_id}/versionsPolicy version metadata
Captured version history (dates, capture status). Full text is reserved for a higher tier.
policy_id(path)mac(query) — Defaults to National.
Example
curl https://clvintelligence.com/api/v1/alerts?specialty=cardiology&limit=25 \ -H "Authorization: Bearer clv_live_your_key_here"
Webhooks
Register a delivery URL (https only) and a filter on your account page; we POST signed new-alert events with at-least-once delivery. Each request carries a CLV-Signature: t=<ts>,v1=<hex> header — an HMAC-SHA256 of "{timestamp}.{rawBody}" with your signing secret. Verify it and reject timestamps outside a few minutes to stop replays.
Node
import crypto from "node:crypto";
function verify(secret, rawBody, header, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(",").map(kv => kv.split("=")));
const t = Number(parts.t);
if (Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = crypto.createHmac("sha256", secret)
.update(`${t}.${rawBody}`).digest("hex");
const a = Buffer.from(expected), b = Buffer.from(parts.v1 || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Python
import hmac, hashlib, time
def verify(secret, raw_body, header, tolerance=300):
parts = dict(kv.split("=") for kv in header.split(","))
t = int(parts["t"])
if abs(time.time() - t) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{t}.{raw_body}".encode(),
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))Need a key? Talk to us about API access →