Recipes

Four copy-paste integration recipes

Verify webhook signatures, rotate API tokens, run sandbox checks, and export a 90-day usage CSV — each in one block you can drop straight into your integration.

Verify an X-Veridact-Signature header in Node

Your webhook receiver must verify the HMAC-SHA256 digest before processing any payload — Veridact signs every delivery with the whsec_… secret you set when creating the webhook endpoint.

// webhook-receiver.js — drop-in for any Node/Express app
const crypto = require('crypto');

const SIGNING_SECRET = process.env.VERIDACT_WEBHOOK_SECRET; // whsec_… from POST /api/v1/compliance/webhooks

function verifySignature(rawBody, signatureHeader) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', SIGNING_SECRET)
    .update(rawBody)          // Buffer — not the parsed JSON string
    .digest('hex');
  const sig = Buffer.from(signatureHeader || '', 'utf8');
  const exp = Buffer.from(expected, 'utf8');
  return sig.length === exp.length && crypto.timingSafeEqual(sig, exp);
}

// Express middleware example
app.post('/veridact/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  if (!verifySignature(req.body, req.headers['x-veridact-signature'])) {
    return res.status(400).json({ ok: false, reason: 'signature_mismatch' });
  }
  const event = JSON.parse(req.body.toString('utf8'));
  console.log('verified event:', event.event, event.subject_check_id);
  res.json({ ok: true });
});
Expect 200 from your handler when the digest matches. Mismatch returns 400 — Veridact will retry up to three times at 1 min / 5 min / 30 min intervals. Full reference → /compliance-api#post-webhooks

Rotate a vda_ API token

In-place rotation: the old token is invalidated immediately, and the new plaintext is returned exactly once in the response body.

# Rotate the calling vda_ token in place — returns new plaintext exactly once
curl -X POST https://veridact.solutions/api/v1/compliance/api-keys/rotate \
  -H "Authorization: Bearer vda_your_token_here" \
  -H "Content-Type: application/json"
Expected response 201
{
  "success":      true,
  "id":           42,
  "account_id":   "acct_...",
  "token_prefix": "vda_ab12",
  "created_at":   "2026-08-21T09:00:00.000Z",
  "key":          "vda_<new-168-bit-secret>"
}
The old token returns 401 invalid_key on the very next request. Save the new key immediately — it won’t be shown again. Full reference → /compliance-api#post-api-keys-rotate

Run a sandbox subject check

Test the full request/response cycle without consuming quota or writing to the database — the sandbox endpoint mirrors the live pipeline’s validation but returns a fixed mock verdict.

curl -X POST https://veridact.solutions/api/v1/compliance/subject-checks/sandbox \
  -H "Authorization: Bearer vda_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name":    "Jane",
    "last_name":     "Doe",
    "locations":     [{ "country": "US", "state": "CA" }],
    "purpose":       "pre_investment",
    "consent_given": true
  }'
Expected response 201
{
  "success":          true,
  "subject_check_id": "sandbox",
  "status":           "completed",
  "subject_name":     "Jane Doe",
  "verdict":          "clear_no_match",
  "confidence_score": 1.0,
  "created_at":       "2026-08-21T12:00:00.000Z"
}
No quota decrement, no DB write, no rate-limit tick. Swap the path to /api/v1/compliance/subject-checks (drop /sandbox) when you’re ready for a real check. Full reference → /compliance-api#post-subject-checks-sandbox

Export a 90-day usage CSV

Pull a 90-day per-day subject-check count for billing reconciliation or audit — the same data that powers the sparkline on your usage dashboard, returned as a flat CSV.

# Export 90-day per-day subject-check CSV (session cookie required)
curl -X GET "https://veridact.solutions/api/account/usage/csv?days=90" \
  -H "Cookie: auth_token=$VERIDACT_SESSION" \
  --output usage-90d.csv
Returns a two-column CSV (date,count) with one row per day, oldest first. Requires an active session (auth_token cookie). Full reference → /account/usage