SDK Reference
Integration reference (canonical SDK doc)
This page is rendered directly from packages/age-verify/docs/INTEGRATION.md so website guidance stays aligned with the SDK source docs.
packages/age-verify/docs/INTEGRATION.md
# Age Verify Integration Guide
This guide covers the current integration flow for `age-verify`.
## Prerequisites
- Active operator account.
- API key generated in portal.
- Billing setup complete (payment method + active billing state).
## Recommended architecture
- Backend owns `AGEVERIFY_API_KEY`.
- Browser does not hold secret API key.
- Browser biometric runtime uses short-lived model access tokens from backend-assisted API calls.
## End-to-end flow
1. Evaluate policy
- `POST /api/v1/policy/evaluate`
- Input context: `operatorId`, `action`, optional route/category/geography.
- Output determines whether verification is required and which method/classification applies.
2. Create verification session
- `POST /api/v1/verification-sessions`
- Required: `operatorId`, `idempotencyKey`.
- Optional: `userId`, `paymentIntentId`, `expiresAt`.
3. Request model access
- `POST /api/v1/verification-sessions/{sessionId}/model-access`
- Returns `modelAccessToken` + `modelBasePath`.
4. Run biometric check (browser SDK)
- `runDefaultBiometricCheck({ modelBasePath, modelAccessToken, ... })`
5. Submit result
- `POST /api/v1/verification-sessions/{sessionId}/biometric-result`
- For checkbox companion UX: `POST /api/v1/verification-sessions/{sessionId}/checkbox-result`
- Canonical response outcome: `passed` | `failed` | `inconclusive`
- Successful fresh outcomes may include a signed decision token for reusable verification.
6. Optional fallback handoff
- `POST /api/v1/fallback/initiate`
- Body: `{ verificationSessionId }`
- Fallback is external-vendor handoff only; no internal fallback verification engine is used.
## Minimal SDK example
```ts
import { createAgeVerifyClient, runDefaultBiometricCheck } from 'age-verify';
const client = createAgeVerifyClient({
apiBaseUrl: '/api/ageverify-proxy',
});
const session = await client.createVerificationSession({
operatorId: '11111111-1111-1111-1111-111111111111',
idempotencyKey: 'idem_1234567890',
userId: 'user_abc',
});
const access = await client.getModelAccess(session.sessionId);
const biometric = await runDefaultBiometricCheck({
modelBasePath: access.modelBasePath,
modelAccessToken: access.modelAccessToken,
});
const result = await client.submitBiometricResult(session.sessionId, {
outcome: biometric.passed ? 'passed' : 'failed',
reason: biometric.reason,
subjectId: biometric.subjectId,
});
// Canonical outcome field: 'passed' | 'failed' | 'inconclusive'
// Use result.outcome for all new integrations.
// The legacy result.passed boolean is retained for backward compatibility but is deprecated.
if (result.outcome === 'passed') {
// allow access
}
if (result.outcome === 'inconclusive') {
// route to external fallback as required by policy
await client.initiateFallback(session.sessionId);
}
```
## Terminology
- Completed verification session: lifecycle completion in `verification_sessions`.
- Successful tokenized outcome: successful result persisted in `decision_tokens`.
- Billable verification: event persisted in `billable_events`.
- API usage telemetry: request event in `api_key_usage_events`.
Do not treat these as interchangeable metrics.
## Error handling guidance
- Reuse `idempotencyKey` when retrying session creation.
- Handle `billing_blocked` as an onboarding/billing-state action item.
- Treat webhook processing as idempotent by event id.
- Treat model access token expiry as recoverable: request fresh model access and retry the biometric step.
## Security checklist
- Keep secret API key backend-only.
- Verify webhook signatures.
- Use HTTPS for all requests.
- Rotate API keys through portal workflows.