Testing KBA with the Sandbox
Exercise every KBA outcome in automated tests (pass, fail, and the full question flow) without calling the identity provider.
Knowledge-based authentication (KBA) is hard to test. Every attempt is a paid lookup against a third-party identity provider, the questions are generated from real public records, and they change every session. None of that is something you can assert on in CI.
The KBA sandbox replaces the identity provider with a deterministic stand-in, for organizations you set aside for testing. Nothing else changes: you call the same Verify Signer endpoint, the recipient moves through the same auth states, and failures produce the same errors and webhooks they would in production.
You choose the outcome per request with sandbox_test_type:
pass
KBA completes immediately. No questions are asked.
fail
KBA fails immediately, as if the identity provider couldn't find the person.
questions (default)
Four questions with known answers, graded by the sandbox.
How a request is routed
A KBA attempt runs in the sandbox only when both of these are true:
- The organization has the
kba_sandboxentitlement. - The signer submits the sandbox identity.
sandbox_test_type on the same request then picks the scenario. Everything else is rejected before anything is sent to the identity provider:
Both 400s are deliberate guard rails:
| Situation | Response | Why |
|---|---|---|
sandbox_test_type sent, but the organization doesn't have the sandbox | 400 "The KBA sandbox is not enabled for this organization." | A misconfigured test fails fast instead of running a real lookup with a fake identity. |
| The organization has the sandbox, but the signer submits any other identity | 400 "This organization is in KBA sandbox mode. Use the sandbox identity to test KBA." | A test organization can never run a real person through KBA. |
Enable the sandbox
kba_sandbox is an organization entitlement. Verdocs grants it on request: contact your account team or support@verdocs.com. It's never included in a subscription, so it can't be switched on by accident.
Use a dedicated test organization
Once an organization has the sandbox, every KBA signer in it must use the sandbox identity, and real signers are turned away. Don't enable it on an organization that sends real envelopes.
The sandbox identity
The signer must submit these values exactly. The match is case-sensitive, and all seven fields are required.
| Field | Value |
|---|---|
first_name | VERDOCS |
last_name | SANDBOX |
address | 888 TURNKEY DRIVE |
city | NYC |
state | NY |
zip | 99999 |
dob | 01/13/1982 |
Walkthrough
Create an envelope with a KBA recipient
Create the envelope as usual with Create Envelope, and add kba to the recipient's auth_methods:
{
"role_name": "Signer",
"first_name": "Verdocs",
"last_name": "Sandbox",
"email": "kba-tests@example.com",
"auth_methods": ["kba"]
}Start a signing session
Start a session for the recipient with Start Signing Session, and keep the access_token from the response. Every call below uses it as the bearer token, not your API key.
Submit the sandbox identity
Send the identity with the scenario you want. Leave out sandbox_test_type to get questions.
curl -X POST https://api.verdocs.com/v2/sign/verify \
-H "Authorization: Bearer $SIGNING_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"auth_method": "kba",
"first_name": "VERDOCS",
"last_name": "SANDBOX",
"address": "888 TURNKEY DRIVE",
"city": "NYC",
"state": "NY",
"zip": "99999",
"dob": "01/13/1982",
"sandbox_test_type": "questions"
}'import {verifySigner} from '@verdocs/js-sdk';
// `endpoint` is a VerdocsEndpoint holding the signing session token
const session = await verifySigner(endpoint, {
auth_method: 'kba',
first_name: 'VERDOCS',
last_name: 'SANDBOX',
address: '888 TURNKEY DRIVE',
city: 'NYC',
state: 'NY',
zip: '99999',
dob: '01/13/1982',
sandbox_test_type: 'questions',
});The response is the usual signing session payload. Read the outcome from recipient.auth_method_states.kba. For pass and fail you're done here: see the scenario reference.
Answer the questions
For questions, recipient.kba_questions holds four questions. Each one tells you its answer:
[
{"type": "sandbox.question.1", "prompt": "The correct answer is 1", "answer": ["1", "2", "3", "4"]},
{"type": "sandbox.question.2", "prompt": "The correct answer is 2", "answer": ["1", "2", "3", "4"]},
{"type": "sandbox.question.3", "prompt": "The correct answer is 3", "answer": ["1", "2", "3", "4"]},
{"type": "sandbox.question.4", "prompt": "The correct answer is 4", "answer": ["1", "2", "3", "4"]}
]Answer all four in one request, pairing each type with the option you pick:
curl -X POST https://api.verdocs.com/v2/sign/verify \
-H "Authorization: Bearer $SIGNING_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"auth_method": "kba",
"responses": [
{"type": "sandbox.question.1", "answer": "1"},
{"type": "sandbox.question.2", "answer": "2"},
{"type": "sandbox.question.3", "answer": "3"},
{"type": "sandbox.question.4", "answer": "4"}
]
}'To test a failure, change any one answer.
Scenario reference
Identity step
sandbox_test_type | Response | auth_method_states.kba |
|---|---|---|
pass | 200 signing session | complete |
fail | 400 "Authentication failed. Please contact the sender for assistance." | failed |
questions (or omitted) | 200 signing session, with four kba_questions | questions |
| Anything else | 400 validation error | Unchanged |
Answers step (questions only)
| Answers | Response | auth_method_states.kba |
|---|---|---|
| All four correct | 200 signing session | complete |
| Any answer wrong | 400 "Authentication failed. Please contact the sender for assistance." | failed |
Fewer than four, or a type that wasn't asked | 400 "Please answer every question." | Unchanged: answer again |
A failure marks the recipient failed and fires the recipient_auth_fail webhook, exactly as a real KBA failure does (see The Recipient Auth Ladder).
Things to know
- The identity provider is never called. Sandbox attempts don't leave Verdocs, so they have no lookup cost and always behave the same way.
completeandfailedare final, as in production. A failed recipient can't retry. Use a fresh envelope per test case, or reset the envelope, which clears every recipient's auth state.- Grading is stricter than production. Any wrong answer fails, whereas production may allow a few. Don't use the sandbox to test pass thresholds.
- The 24-hour window still applies. KBA must be completed within 24 hours of starting it, as in production.
- There's no differentiator step. Production KBA can occasionally ask one extra question to tell people with similar records apart before the main questions. The sandbox goes straight to its four questions.