Quickstart
This guide walks through a server-side verification flow using the REST API directly. For mobile integrations, see the Android SDK or iOS SDK guides.
Prerequisites
- A Kora IDV account (sign up)
- Your API key (starts with
test_for sandbox) - Your Tenant ID (UUID from your dashboard)
Step 1: Create a verification
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/idv/verifications \
-H "Authorization: Bearer $KORAIDV_API_KEY" \
-H "X-Tenant-ID: $KORAIDV_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"externalId": "user-123",
"tier": "standard",
"callbackUrl": "https://your-server.com/webhooks/koraidv"
}'
const response = await fetch("https://api.korastratum.com/api/v1/idv/verifications", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KORAIDV_API_KEY}`,
"X-Tenant-ID": process.env.KORAIDV_TENANT_ID,
"Content-Type": "application/json",
},
body: JSON.stringify({
externalId: "user-123",
tier: "standard",
callbackUrl: "https://your-server.com/webhooks/koraidv",
}),
});
const verification = await response.json();
console.log(verification.id); // "ver_abc123"
import requests
import os
response = requests.post(
"https://api.korastratum.com/api/v1/idv/verifications",
headers={
"Authorization": f"Bearer {os.environ['KORAIDV_API_KEY']}",
"X-Tenant-ID": os.environ["KORAIDV_TENANT_ID"],
"Content-Type": "application/json",
},
json={
"externalId": "user-123",
"tier": "standard",
"callbackUrl": "https://your-server.com/webhooks/koraidv",
},
)
verification = response.json()
print(verification["id"]) # "ver_abc123"
req := contracts.CreateVerificationRequest{
ExternalID: "user-123",
Tier: contracts.TierStandard,
CallbackURL: "https://your-server.com/webhooks/koraidv",
}
verification, err := client.CreateVerification(ctx, req)
fmt.Println(verification.ID) // "ver_abc123"
Save the returned id — you'll use it in all subsequent steps.
Step 2: Upload a document
Upload the front of the identity document as a base64-encoded image.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/idv/verifications/$VERIFICATION_ID/document \
-H "Authorization: Bearer $KORAIDV_API_KEY" \
-H "X-Tenant-ID: $KORAIDV_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"documentType": "us_passport",
"imageBase64": "'$(base64 -i document.jpg)'"
}'
const docResponse = await fetch(
`https://api.korastratum.com/api/v1/idv/verifications/${verification.id}/document`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KORAIDV_API_KEY}`,
"X-Tenant-ID": process.env.KORAIDV_TENANT_ID,
"Content-Type": "application/json",
},
body: JSON.stringify({
documentType: "us_passport",
imageBase64: documentImageBase64,
}),
}
);
doc_response = requests.post(
f"https://api.korastratum.com/api/v1/idv/verifications/{verification['id']}/document",
headers={
"Authorization": f"Bearer {os.environ['KORAIDV_API_KEY']}",
"X-Tenant-ID": os.environ["KORAIDV_TENANT_ID"],
"Content-Type": "application/json",
},
json={
"documentType": "us_passport",
"imageBase64": document_image_b64,
},
)
doc, err := client.UploadDocument(ctx, verification.ID, contracts.UploadDocumentRequest{
DocumentType: contracts.DocTypeUSPassport,
ImageBase64: documentImageBase64,
})
Step 3: Upload a selfie
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/idv/verifications/$VERIFICATION_ID/selfie \
-H "Authorization: Bearer $KORAIDV_API_KEY" \
-H "X-Tenant-ID: $KORAIDV_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"imageBase64": "'$(base64 -i selfie.jpg)'"
}'
const selfieResponse = await fetch(
`https://api.korastratum.com/api/v1/idv/verifications/${verification.id}/selfie`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KORAIDV_API_KEY}`,
"X-Tenant-ID": process.env.KORAIDV_TENANT_ID,
"Content-Type": "application/json",
},
body: JSON.stringify({
imageBase64: selfieImageBase64,
}),
}
);
selfie_response = requests.post(
f"https://api.korastratum.com/api/v1/idv/verifications/{verification['id']}/selfie",
headers={
"Authorization": f"Bearer {os.environ['KORAIDV_API_KEY']}",
"X-Tenant-ID": os.environ["KORAIDV_TENANT_ID"],
"Content-Type": "application/json",
},
json={
"imageBase64": selfie_image_b64,
},
)
selfie, err := client.UploadSelfie(ctx, verification.ID, contracts.UploadSelfieRequest{
ImageBase64: selfieImageBase64,
})
Step 4: Complete the verification
This triggers scoring, compliance screening, and a final decision.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/idv/verifications/$VERIFICATION_ID/complete \
-H "Authorization: Bearer $KORAIDV_API_KEY" \
-H "X-Tenant-ID: $KORAIDV_TENANT_ID"
const result = await fetch(
`https://api.korastratum.com/api/v1/idv/verifications/${verification.id}/complete`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KORAIDV_API_KEY}`,
"X-Tenant-ID": process.env.KORAIDV_TENANT_ID,
},
}
);
const data = await result.json();
console.log(data.status); // "verified" | "rejected" | "manual_review"
console.log(data.decision); // "auto_approve" | "auto_reject" | "manual_review"
result = requests.post(
f"https://api.korastratum.com/api/v1/idv/verifications/{verification['id']}/complete",
headers={
"Authorization": f"Bearer {os.environ['KORAIDV_API_KEY']}",
"X-Tenant-ID": os.environ["KORAIDV_TENANT_ID"],
"Content-Type": "application/json",
},
)
data = result.json()
print(data["status"]) # "verified" | "rejected" | "manual_review"
print(data["decision"]) # "auto_approve" | "auto_reject" | "manual_review"
result, err := client.CompleteVerification(ctx, verification.ID)
fmt.Println(result.Status) // "verified" | "rejected" | "manual_review"
fmt.Println(result.Decision) // "auto_approve" | "auto_reject" | "manual_review"
Step 5: Receive the webhook
Your callbackUrl receives a verification.completed event:
{
"id": "evt_def456",
"eventType": "verification.completed",
"resourceType": "verification",
"resourceId": "ver_abc123",
"tenantId": "your-tenant-id",
"timestamp": "2025-01-15T10:35:00Z",
"data": {
"verificationId": "ver_abc123",
"externalId": "user-123",
"status": "verified",
"decision": "auto_approve",
"decisionReason": "All checks passed",
"overallScore": 96.3
}
}
Always verify the webhook signature before processing.
What's next
- Mobile SDKs — The SDK handles document capture, selfie, and liveness — so you don't build camera UIs.
- Webhooks — Set up webhook signature verification and handle all event types.
- Sandbox Testing — Use test fixtures for deterministic results without real documents.
- Error Handling — Handle every error code with recovery suggestions.