Skip to content
Try Free →

Identity verification API

Last updated: · 3 min read

Endpoints

These live under the workspace-settings API, not the public /v1/* surface — they're authenticated with your dashboard session (the same login used by the AskVault dashboard), and restricted to the workspace owner:

GET /api/workspaces/{workspace_id}/identity-verification # Get current config
POST /api/workspaces/{workspace_id}/identity-verification/setup # Enable + generate a secret
PATCH /api/workspaces/{workspace_id}/identity-verification # Update config (enable/disable)
POST /api/workspaces/{workspace_id}/identity-verification/rotate # Rotate the secret

Get config

Terminal window
curl https://api.askvault.co/api/workspaces/wt_xxx/identity-verification \
-H "Authorization: Bearer <dashboard access token>"

Returns:

{
"enabled": true,
"has_secret": true,
"secret_preview": "ivs_ab12****"
}

The full secret is only ever returned once, from the setup or rotate endpoints — GET only exposes a preview.

Update config

Enable enforcement:

Terminal window
curl -X PATCH https://api.askvault.co/api/workspaces/wt_xxx/identity-verification \
-H "Authorization: Bearer <dashboard access token>" \
-d '{"enabled":true}'

Regenerate secret:

Terminal window
curl -X POST https://api.askvault.co/api/workspaces/wt_xxx/identity-verification/rotate \
-H "Authorization: Bearer <dashboard access token>"

Returns {"enabled": true, "secret": "ivs_..."} — the full secret, shown once, not stored for re-retrieval.

HMAC computation

The hash is HMAC-SHA256(secret, user_id):

import hmac, hashlib
hash_value = hmac.new(secret.encode(), user_id.encode(), hashlib.sha256).hexdigest()
const crypto = require('crypto');
const hashValue = crypto.createHmac('sha256', secret).update(userId).digest('hex');

See identity verification setup for full implementation.

Rotation flow

Rotate every 6 to 12 months. Rotation has no grace period — the old secret stops verifying the instant you rotate, so sequence it carefully:

  1. Deploy your backend change first, computing hashes with the new secret, while the old secret is still active — or accept a brief verification gap.
  2. Call the rotate endpoint. Returns the new secret once; it is not stored for re-retrieval.
  3. Confirm your backend is live with the new secret. The old one no longer verifies anything.

Limits

  • Grace period on rotation. None — the old secret is invalidated the moment you rotate.
  • HMAC secret format. ivs_ prefix plus a random URL-safe token (variable length, not fixed).
  • Failed verification. Rejected requests return 403 Forbidden to the caller; check your own backend logs to spot repeated failures.

Common pitfalls

Hash mismatch. Encoding mismatch (UTF-8 vs ASCII) between your backend and the HMAC computation above. Check both sides.

Rotation breaks production. There's no grace period — rotating before your backend is updated invalidates every hash your backend computes until it catches up. Deploy the new secret first where possible.

FAQ

Can I disable verification mid-cycle?

Yes via PATCH {"enabled":false}. Visitors no longer need to verify.

Does rotating the secret have a grace period?

No. The old secret stops verifying immediately — update your backend before or during rotation, not after.

Was this page helpful?