API Keys & Scopes
Every API request to VerifyHuman is authenticated with an API key. Keys are environment-scoped (test or live), product-scoped (which verification products they can call), and individually revocable.
Key format
vhk_live_<32+ url-safe chars> # Live key
vhk_test_<32+ url-safe chars> # Test key
The prefix tells you the environment at a glance. Keys are shown to you exactly once when created — copy them into your secrets manager immediately.
Creating a key
- Sign in and open Dashboard → API Keys.
- Click Create API Key.
- Choose:
- Environment — Test or Live.
- Scope — which products the key can call (see below).
- Allowed domains (optional) — for browser/widget usage, restrict to your hostnames.
- Show "Powered by VerifyHuman" — toggle the badge on hosted flows. (Pro/Enterprise.)
- Save. Copy the secret now — it will not be shown again.
You need the api_keys.create permission. See Roles & permissions.
Authentication methods
Header (recommended for server-to-server)
curl -X POST https://api.verifyhuman.io/api/verify \
-H "X-API-Key: vhk_live_..." \
-F file=@selfie.jpg
Header (mobile / SDK — publishable key)
Mobile and SDK clients send the publishable key in a dedicated header — never as a query parameter:
POST /api/mobile/v1/verifyhuman/verify
Authorization: ClientKey vhk_live_...
The header X-Client-Key: vhk_live_... is also accepted for compatibility. See Mobile API & SDK for the full surface and the response envelope.
Never embed a non-publishable secret key in a mobile app or single-page-app bundle.
Scopes
Each key has exactly one scope:
| Scope | Endpoints |
|---|---|
verifyhuman |
VerifyHuman (face liveness) |
verifyage |
VerifyAge |
identity |
VerifyIdentity |
kyc |
KYC submit |
kyc_plus |
VerifyTrust + report generation |
hybrid |
All of the above (use sparingly, server-to-server only) |
A key calling an endpoint outside its scope receives 403 Forbidden.
Test vs Live behavior
| Aspect | Test key | Live key |
|---|---|---|
| Credit consumption | None | Real credits deducted |
| AI processing | Simulated, deterministic | Real verification provider |
| Verification history | Stored in test history | Stored in live history |
| Webhooks | Delivered to test endpoints only | Delivered to live endpoints only |
| Stripe | No charges | Real charges |
Test and live data are fully isolated. A live webhook endpoint will never receive a test event, and vice versa.
Rotation
Rotate a key when:
- A team member with access leaves.
- A key may have leaked (e.g. accidentally committed to a public repo).
- Your security policy requires periodic rotation.
To rotate:
- Create a new key with the same scope and environment.
- Update your application to use the new key.
- Verify traffic is flowing through the new key (check Dashboard → API Analytics).
- Revoke the old key.
There is no forced overlap window — you control the cutover.
Revocation
Revoking a key takes effect immediately. Inflight requests using the revoked key may complete; new requests will receive 401 Unauthorized. Revoked keys cannot be restored — create a new key if you need access again.
Domain allowlisting (browser/widget)
Keys used by the browser widget should set Allowed domains to your hostnames. Requests from origins not on the list are rejected:
"error": "Origin not allowed for this key"
Server-to-server keys do not need a domain allowlist.
Best practices
- One key per integration. Easier rotation, easier auditing.
- Use test keys in CI. They're free and produce deterministic outputs.
- Never log API keys. Filter them at your log aggregator.
- Store secrets in a secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager, Doppler, etc.). Never check them into version control.
- Use the narrowest scope that works. Prefer
verifyhumanoverhybridif you only need bot detection.
Limits
| Resource | Default limit |
|---|---|
| Active keys per organization | 50 (raise on request for Enterprise) |
| Allowed domains per key | 25 |
| Revoked keys retained for audit | Unlimited |
Errors
| HTTP | Body | Meaning |
|---|---|---|
401 |
Invalid API key |
Key not found or revoked |
401 |
Environment mismatch |
Test key used against live endpoint, or vice versa |
403 |
Scope does not allow this product |
Wrong scope for the endpoint |
403 |
Origin not allowed for this key |
Domain allowlist rejected the Origin header |
429 |
Rate limit exceeded |
Per-key rate limit hit; see Rate Limits |