Zauthy Documentation
Complete API reference for authentication, identity verification (KYC), and fraud prevention. Integrate secure user onboarding in minutes.
Quick Start
Get your first integration working in 4 steps.
1. Create an organization
Every Zauthy account starts with an organization (tenant). Sign up at the dashboard or use the API:
curl -X POST https://api.zauthy.com/v1/organizations \
-H "Content-Type: application/json" \
-d '{
"name": "My App",
"owner_email": "you@example.com",
"owner_password": "SecureP@ss123"
}'Response
{
"organization": {
"id": "org_abc123",
"name": "My App",
"api_key": "sk_live_..."
},
"user": {
"id": "usr_xyz789",
"email": "you@example.com",
"role": "owner"
},
"access_token": "eyJ...",
"refresh_token": "eyJ..."
}2. Install the SDK
npm install @zauthy/sdk3. Initialize the client
import { Zauthy } from '@zauthy/sdk';
const zauthy = new Zauthy({
apiKey: process.env.ZAUTHY_SECRET_KEY, // sk_live_...
baseUrl: 'https://api.zauthy.com/v1' // optional, defaults to production
});4. Register your first user
const { user, access_token } = await zauthy.auth.signup({
email: 'user@example.com',
password: 'SecureP@ss123',
name: 'Jane Doe'
});
console.log(user.id); // usr_abc123
// Store access_token for subsequent requestsAuthentication
All API requests require authentication via one of two methods:
API Key (server-side)
Use your organization API key for server-to-server calls. Never expose this in client-side code.
Authorization: Bearer sk_live_your_api_keyJWT Token (user-level)
Use the access token from login/signup for user-scoped operations. Tokens expire after 15 minutes.
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...API Key Security
Store API keys in environment variables. Never commit them to version control or embed in client-side code. Rotate keys immediately if compromised via the dashboard or DELETE /api-keys/{key_id}.
Error Handling
Zauthy uses standard HTTP status codes. All errors return a consistent JSON body:
{
"detail": "Human-readable error message",
"error": "error_code" // machine-readable, when available
}| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad request — invalid parameters or validation failure |
| 401 | Unauthorized — missing or invalid API key / token |
| 403 | Forbidden — insufficient permissions or role |
| 404 | Not found — resource does not exist |
| 409 | Conflict — resource already exists (e.g., duplicate email) |
| 429 | Rate limited — too many requests, retry after delay |
| 500 | Internal error — contact support if persistent |
Rate Limits
Rate limits vary by plan and endpoint category:
| Plan | Auth endpoints | KYC endpoints | General |
|---|---|---|---|
| Free | 20/min | 10/min | 60/min |
| Pro | 100/min | 50/min | 300/min |
| Enterprise | Custom | Custom | Custom |
When rate limited, you'll receive a 429 response. Implement exponential backoff in your integration.
Auth API
Base path: /api/v1
Signup & Login
/signupRegister a new user in your organization. Password must include uppercase, lowercase, digit, and special character (minimum 8 chars).
// Request
{
"email": "user@example.com",
"password": "SecureP@ss123",
"name": "Jane Doe", // optional
"phone": "+1234567890" // optional
}
// Response 201
{
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"name": "Jane Doe",
"role": "user",
"is_verified": false,
"created_at": "2026-03-07T10:00:00Z"
},
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer",
"expires_in": 900
}/loginAuthenticate a user with email and password. Returns tokens for API access. Account locks after 5 failed attempts (30 min), 10 (2 hr), 15 (24 hr).
// Request
{
"email": "user@example.com",
"password": "SecureP@ss123"
}
// Response 200
{
"user": { "id": "usr_abc123", "email": "user@example.com", "role": "user", ... },
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer",
"expires_in": 900,
"mfa_required": false // true if user has MFA enabled
}
// Response 200 (MFA required)
{
"mfa_required": true,
"mfa_token": "mfa_tmp_...",
"mfa_methods": ["totp"]
}/refreshExchange a refresh token for a new access token.
// Request
{ "refresh_token": "eyJ..." }
// Response 200
{
"access_token": "eyJ...",
"refresh_token": "eyJ...", // rotated
"token_type": "bearer",
"expires_in": 900
}/logoutInvalidate the current session. Requires Bearer token.
// Response 200
{ "success": true }Sessions & Tokens
/sessionsList all active sessions for the current user. Useful for 'active devices' UI.
/sessions/{session_id}Revoke a specific session (remote logout).
/sessionsRevoke all sessions for the current user (logout everywhere).
/token/verifyVerify an access token is valid. Use this in your backend middleware.
// Request
{ "token": "eyJ..." }
// Response 200
{
"valid": true,
"user_id": "usr_abc123",
"role": "user",
"org_id": "org_xyz789",
"expires_at": "2026-03-07T10:15:00Z"
}Password Management
/password/forgotSend a password reset email to the user.
// Request
{ "email": "user@example.com" }
// Response 200 (always succeeds to prevent email enumeration)
{ "message": "If an account exists, a reset link has been sent." }/password/resetReset password using the token from the reset email.
// Request
{ "token": "reset_token_...", "new_password": "NewSecureP@ss123" }/password/changeChange password for the authenticated user. Requires current password.
Magic Links (Passwordless)
/magic-link/sendSend a one-time login link to the user's email.
// Request
{
"email": "user@example.com",
"redirect_url": "https://yourapp.com/auth/callback" // optional
}/magic-link/verifyVerify the magic link token and receive auth tokens.
// Request
{ "token": "magic_token_..." }
// Response 200
{
"user": { ... },
"access_token": "eyJ...",
"refresh_token": "eyJ..."
}OTP Verification
/otp/sendSend a one-time passcode via email or SMS.
// Request
{
"email": "user@example.com", // or "phone": "+1234567890"
"channel": "email" // "email" or "sms"
}/otp/verifyVerify an OTP code. Returns auth tokens on success.
// Request
{
"email": "user@example.com",
"code": "123456"
}MFA / TOTP
/mfa/totp/setupGenerate a TOTP secret and QR code URI for the user to scan with their authenticator app.
// Response 200
{
"secret": "JBSWY3DPEHPK3PXP",
"qr_uri": "otpauth://totp/Zauthy:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Zauthy",
"backup_codes": ["abc123", "def456", ...]
}/mfa/totp/verifyVerify a TOTP code during login (when mfa_required is true) or to confirm MFA setup.
// Request
{
"code": "123456",
"mfa_token": "mfa_tmp_..." // from login response
}/mfa/disableDisable MFA for the current user. Requires password confirmation.
Passkeys / WebAuthn
FIDO2/WebAuthn passkeys for passwordless authentication. Uses the browser's navigator.credentials API.
/passkey/register/startGet WebAuthn registration options. Pass the response to navigator.credentials.create().
/passkey/register/finishComplete passkey registration with the browser's credential response.
/passkey/authenticate/startGet WebAuthn authentication options. Pass to navigator.credentials.get().
/passkey/authenticate/finishComplete passkey authentication. Returns auth tokens on success.
/passkey/listList all registered passkeys for the current user.
/passkey/{passkey_id}Remove a registered passkey.
OAuth (Social Login)
Support for Google and Apple OAuth. Configure providers in your dashboard settings.
/auth/oauth/providersList enabled OAuth providers for your organization.
/auth/oauth/initInitialize an OAuth flow. Returns a redirect URL for the provider.
// Request
{
"provider": "google",
"redirect_url": "https://yourapp.com/auth/callback"
}
// Response 200
{ "authorization_url": "https://accounts.google.com/o/oauth2/v2/auth?..." }/auth/oauth/callbackHandle OAuth callback. Exchange authorization code for tokens.
/auth/oauth/linkLink an OAuth provider to an existing authenticated account.
/auth/oauth/unlink/{provider}Unlink an OAuth provider from the current account.
KYC API
Base path: /api/v1/kyc
Sessions
A KYC session represents a single identity verification attempt. Create a session, upload documents, run face matching and liveness checks, then complete.
/kyc/sessionsCreate a new KYC verification session.
// Request
{
"user_id": "usr_abc123", // optional, link to existing user
"type": "full_kyc", // "full_kyc" | "document_only" | "face_only"
"checks": ["document", "face", "liveness"],
"metadata": { "source": "onboarding" }
}
// Response 201
{
"id": "kyc_sess_abc123",
"status": "pending",
"checks": ["document", "face", "liveness"],
"created_at": "2026-03-07T10:00:00Z",
"expires_at": "2026-03-07T11:00:00Z"
}/kyc/sessions/{session_id}Get session details including document status and verification results.
/kyc/sessions/{session_id}/statusQuick status check for polling. Returns just the status and scores.
/kyc/sessionsList all KYC sessions with optional filters (status, user_id, date range). Paginated.
/kyc/sessions/{session_id}/completeFinalize the session and trigger scoring. Returns the overall verification result.
/kyc/sessions/{session_id}Delete a KYC session and all associated data.
Document Upload
Upload identity documents (passport, driver's license, national ID) for OCR extraction. Supports JPEG, PNG, and PDF. Max 10MB. File content is validated via magic-byte detection.
/kyc/sessions/{session_id}/documentsUpload an identity document image. Uses multipart/form-data.
curl -X POST https://api.zauthy.com/v1/kyc/sessions/{session_id}/documents \
-H "Authorization: Bearer sk_live_..." \
-F "file=@passport.jpg" \
-F "document_type=passport" \
-F "country=US"
# Response 200
{
"document_id": "doc_abc123",
"status": "processed",
"document_type": "passport",
"extracted_data": {
"full_name": "Jane Doe",
"date_of_birth": "1990-01-15",
"document_number": "AB1234567",
"expiry_date": "2030-01-15",
"country": "US"
},
"confidence": 0.97
}Face Verification
/kyc/sessions/{session_id}/face/matchCompare a selfie with the face on the uploaded document. Upload as multipart/form-data.
// Response 200
{
"match": true,
"confidence": 0.94,
"threshold": 0.80
}Liveness Detection
/kyc/sessions/{session_id}/face/livenessVerify the selfie is a live person (not a photo of a photo, mask, or screen). Upload as multipart/form-data.
// Response 200
{
"is_live": true,
"confidence": 0.98,
"checks": {
"texture_analysis": true,
"depth_estimation": true,
"blink_detection": true
}
}Location Verification
/kyc/sessions/{session_id}/locationSubmit GPS coordinates for location-based verification (e.g., country matching with document).
// Request
{
"latitude": 37.7749,
"longitude": -122.4194,
"accuracy": 10.0
}Webhooks
Receive real-time notifications when events occur in your Zauthy account. Webhooks are HMAC-signed and retried automatically on failure.
/webhooksCreate a new webhook subscription.
// Request
{
"url": "https://yourapp.com/webhooks/zauthy",
"events": ["user.signup", "kyc.completed", "kyc.failed"],
"active": true
}
// Response 201
{
"id": "wh_abc123",
"url": "https://yourapp.com/webhooks/zauthy",
"secret": "whsec_...", // for signature verification
"events": ["user.signup", "kyc.completed", "kyc.failed"],
"active": true
}/webhooksList all webhook subscriptions.
/webhooks/{webhook_id}Update a webhook (URL, events, active status).
/webhooks/{webhook_id}Delete a webhook subscription.
/webhooks/{webhook_id}/testSend a test webhook event to verify your endpoint.
/webhooks/{webhook_id}/rotate-secretRotate the webhook signing secret.
/webhooks/{webhook_id}/deliveriesView delivery history and retry status.
Webhook Events
| Event | Description |
|---|---|
| user.signup | New user registered |
| user.login | User logged in |
| user.blocked | User account blocked |
| user.deleted | User account deleted |
| kyc.session.created | KYC session started |
| kyc.completed | KYC verification completed (passed) |
| kyc.failed | KYC verification failed |
| mfa.enabled | User enabled MFA |
| security.suspicious_login | Suspicious login detected |
Signature Verification
Every webhook includes an X-Webhook-Signature header. Always verify this to ensure the payload is authentic.
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler
app.post('/webhooks/zauthy', (req, res) => {
const isValid = verifyWebhook(
JSON.stringify(req.body),
req.headers['x-webhook-signature'] as string,
process.env.ZAUTHY_WEBHOOK_SECRET!
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the event
const { event, data } = req.body;
console.log(`Received ${event}`, data);
res.status(200).send('ok');
});SDKs
JavaScript / TypeScript
npm install @zauthy/sdkimport { Zauthy } from '@zauthy/sdk';
const zauthy = new Zauthy({ apiKey: process.env.ZAUTHY_SECRET_KEY });
// Auth
const { user, access_token } = await zauthy.auth.signup({
email: 'user@example.com',
password: 'SecureP@ss123'
});
// KYC
const session = await zauthy.kyc.createSession({
userId: user.id,
checks: ['document', 'face', 'liveness']
});
// Webhooks
const webhook = await zauthy.webhooks.create({
url: 'https://yourapp.com/webhooks',
events: ['kyc.completed']
});Python
pip install zauthyfrom zauthy import Zauthy
client = Zauthy(api_key="sk_live_...")
# Auth
user = client.auth.signup(
email="user@example.com",
password="SecureP@ss123"
)
# KYC
session = client.kyc.create_session(
user_id=user["id"],
checks=["document", "face", "liveness"]
)
# Upload document
result = client.kyc.upload_document(
session_id=session["id"],
file_path="./passport.jpg",
document_type="passport"
)Flutter / Dart
# pubspec.yaml
dependencies:
vault_kyc_sdk: ^1.0.0import 'package:vault_kyc_sdk/vault_kyc_sdk.dart';
// Initialize
final zauthy = VaultKYC();
await zauthy.initialize(
apiKey: 'sk_live_...',
baseUrl: 'https://api.zauthy.com/v1',
);
// Auth
final result = await zauthy.auth.signup(
email: 'user@example.com',
password: 'SecureP@ss123',
);
// KYC with camera capture
final session = await zauthy.kyc.startVerification(
checks: [KYCCheck.document, KYCCheck.face, KYCCheck.liveness],
);Security API
Base path: /api/v1/security
Device Tracking
/security/users/{user_id}/devicesList known devices for a user. Includes device fingerprint, OS, browser, and trust status.
/security/users/{user_id}/devices/{device_id}/trustMark a device as trusted or untrusted.
/security/users/{user_id}/devices/{device_id}Remove a device from the known list.
Risk Assessment
/security/login/assessAssess login risk before authenticating. Returns risk score and recommended actions.
// Request
{
"email": "user@example.com",
"ip": "203.0.113.42",
"device_fingerprint": "fp_...",
"user_agent": "Mozilla/5.0..."
}
// Response 200
{
"risk_score": 0.15, // 0.0 (safe) to 1.0 (high risk)
"risk_level": "low", // "low" | "medium" | "high"
"flags": [], // ["new_device", "impossible_travel", "tor_exit_node"]
"recommendation": "allow" // "allow" | "mfa" | "block"
}/security/users/{user_id}/suspicious-activitiesGet suspicious activity log for a user.
/security/users/{user_id}/security-summarySecurity dashboard: devices, sessions, risk events, MFA status.
IP Intelligence
/security/check-ipCheck IP reputation (VPN, proxy, Tor, data center detection).
// Request
{ "ip": "203.0.113.42" }
// Response 200
{
"ip": "203.0.113.42",
"is_vpn": false,
"is_proxy": false,
"is_tor": false,
"is_datacenter": false,
"country": "US",
"city": "San Francisco",
"risk_score": 0.05
}/security/geolocateGeolocate the requesting IP address. Returns country, city, coordinates.
Need help integrating?
Our team is here to help you get up and running.