cValue.ai
API REFERENCE · V1

Install, claim, prove.

One script on the form records the consent. One API call claims the lead, checks your rules and returns a TrustScore.

1. Install the capture script

Add the script to every page with a lead form. It records the session as the consumer saw it (passwords, card numbers and Social Security numbers are never recorded; add data-cv-mask to any other field you want hidden), measures the consent text at submit, and writes the certificate URL into hidden fields named cv_cert_url, cv_cert_token and cv_ping_url, so it travels with the lead.

<script src="https://cdn.cvalue.ai/v1/cvalue.js"
        data-cv-source="src_XXXXXXXX" async></script>

Add data-cv-sandbox="true" to create test certificates that are never billed.

If your page validates the form before sending it, add data-cv-submit="manual" and call window.cvalue.submit() once the form is really submitted. In a single-page app, call window.cvalue.stop() when the form's view goes away.

2. Authenticate

Create an API key in Developers → API keys. Send it as Authorization: Bearer cv_live_…. Test keys start with cv_test_. Every response carries an x-request-id you can quote to support.

3. Endpoints

Base URL https://api.cvalue.ai/v1

METHODPATHPURPOSEBILLED
GET/v1/certificates/{id}/pingFree. Confirms a certificate exists and is sealed. With an API key, also adds it to your watch list.No
POST/v1/certificates/{id}/claimClaim, match the lead, check your consent rule and get a TrustScore. Idempotent per account.Yes, once
GET/v1/certificates/{id}Your claim result for a certificate.No
GET/v1/certificatesSearch your claims by reference, outcome and date. Cursor pagination.No
POST/v1/certificates/{id}/watchWatch an unclaimed certificate for expiry alerts and auto-claim.No
POST/v1/certificates/{id}/legal-holdPlace or release a legal hold.No
GET/v1/proofs/{id}Manifest hash, Ed25519 signature, Merkle path and RFC 3161 timestamp tokens.No
GET/v1/keysPublic signing keys.No

4. Claim a certificate

Claim when you accept the lead. Email and phone can be raw or SHA-256 of the normalised value (lowercased email; E.164 phone such as +15125550147). Raw values are never stored. Claiming the same certificate again returns the first result and is not billed twice. Unclaimed certificates are deleted 90 days after sealing.

curl -X POST https://api.cvalue.ai/v1/certificates/CERT_ID/claim \
  -H "Authorization: Bearer cv_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "lead-88412",
    "match": { "email": "maria.garcia@example.com", "phone": "(512) 555-0147" },
    "verify": { "rule": "TCPA standard", "seller_name": "Acme Insurance" },
    "retain_years": 5
  }'

5. Webhooks

Events: certificate.claimed, certificate.flagged, claim.verify_failed, legal_hold.changed, certificates.expiring, certificate.auto_claimed. Failed deliveries are retried with backoff for 24 hours. Check the signature before trusting a payload.

import crypto from "node:crypto";

// header: cvalue-signature: t=1759068137,v1=5f2c…
function verify(header, rawBody, secret) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  return fresh && crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

6. Verify a certificate without trusting cValue

Each certificate's manifest is hashed (SHA-256) and signed (Ed25519). Every hour the hashes are combined into a Merkle tree whose root is timestamped by two independent RFC 3161 authorities. GET /v1/proofs/{id} returns the hash, signature, Merkle path and timestamp tokens; GET /v1/keys returns the public key. Check a token with openssl ts -verify -digest ROOT -sha256 -in token.tsr -CAfile tsa.pem.

7. Errors

Errors return { "error": { "code", "message" } }. Common codes: unauthorised (401), forbidden (403, missing scope), not_found (404), not_sealed (409, the form hasn't been submitted yet), expired (410, the 90-day window closed).