Introduction

Quickstart

Sign up, grab a test key, and run a full identity verification end to end. Everything below happens in the sandbox, so it never spends a credit.

You will create an account, generate an API key, create a verification, let the user complete capture, and read the decision. About five minutes.

What you need
An OKIAS account (free — includes 100 credits) and a terminal with curl, or Node / Python. No SDK required.

Step 1 — Create your account

Sign up at okias.io/register. New accounts start with 100 free credits and both a live and a test API key generated for you. Verify your email so you can receive verification-decision notifications and manage payouts later.

Step 2 — Get your API key

Open Dashboard → API keys. You will see keys in two flavours:

1
Copy a test key (ok_test_…)
Test keys hit the deterministic sandbox and never charge a credit. Perfect for this quickstart.
2
Keep the live key (ok_live_…) for later
Live keys run real checks and cost one credit per approved full KYC — declined, review and errored checks are free. You will switch to it at go-live.
Secret shown once
A key's secret is displayed only at creation. Copy it into a secret manager or your .env immediately — if you lose it, rotate the key rather than trying to recover it.
terminal
export OKIAS_API_KEY="ok_test_..."

Step 3 — Create a verification

Make one authenticated POST to the verifications endpoint. Always send an Idempotency-Key so a retried request never creates a duplicate or double-charges.

POST/v1/verifications
curl https://api.okias.io/v1/verifications \
  -H "Authorization: Bearer ok_test_..." \
  -H "Idempotency-Key: 9f2c4a1b-1e33-4c07-9c1e-2b7f0d5a1a10" \
  -H "Content-Type: application/json" \
  -d '{
    "level": ["FULL_KYC"],
    "country": "pk",
    "end_user_ref": "user_8842"
  }'

The response is 201 Created with a flat verification object (no envelope) — the id, a hosted flow URL, and a server-generated liveness_challenge: the ordered head-turn actions the user must perform during capture. The hosted flow handles the challenge for you; see the liveness challenge for details.

201 Created
{
  "id": "cms80k9ix001moea2jxy64fgu",
  "status": "PENDING",
  "country": "pk",
  "doc_type": null,
  "end_user_ref": "user_8842",
  "cost_credits": 1,
  "mode": "SANDBOX",
  "risk_score": null,
  "hosted_url": "https://okias.io/verify/cms80k9ix001moea2jxy64fgu",
  "liveness_challenge": { "actions": ["LOOK_DOWN", "TURN_RIGHT", "LOOK_UP", "TURN_LEFT"] },
  "reason_codes": [],
  "created_at": "2026-07-30T10:00:00.054Z",
  "completed_at": null
}

Step 4 — Collect the user's document + selfie

You have two options; most teams start with the hosted flow because OKIAS handles the hard parts.

Option A — Hosted flow (recommended)

Redirect the user to the hosted_url from the response — or embed the same flow on your own domain with one script tag. OKIAS renders capture, document guidance and active liveness, then returns the user to you. See Hosted flow & Embed SDK.

Option B — Upload assets yourself

If you run your own capture UI, submit the base64 assets to /v1/verifications/:id/submit. See Verifications for the asset kinds and schema.

Step 5 — Read the decision

The moment scoring finishes, the status moves from PENDING to a final decision. Fetch it any time:

GET/v1/verifications/:id
curl
curl https://api.okias.io/v1/verifications/cms80k9ix001moea2jxy64fgu \
  -H "Authorization: Bearer ok_test_..."
200 OK
{
  "id": "cms80k9ix001moea2jxy64fgu",
  "status": "APPROVED",
  "country": "pk",
  "doc_type": "NATIONAL_ID",
  "end_user_ref": "user_8842",
  "cost_credits": 1,
  "mode": "SANDBOX",
  "risk_score": 8,
  "hosted_url": "https://okias.io/verify/cms80k9ix001moea2jxy64fgu",
  "liveness_challenge": null,
  "reason_codes": [],
  "created_at": "2026-07-30T10:00:00.054Z",
  "completed_at": "2026-07-30T10:03:41.120Z",
  "extracted": { "fullName": "OKIAS SAMPLE USER", "documentNumber": "AB1234567", "dateOfBirth": "1990-01-01" },
  "images": { "front": "data:image/jpeg;base64,...", "back": null, "selfie": "data:image/jpeg;base64,..." },
  "declared": null,
  "match": null
}

GET /v1/verifications/:id also returns owner-only detail fields — extracted, images, declared and match — which stay null until processing completes (and where no data was captured). Full field reference in Verifications.

In production you do not poll — you receive the same decision on a signed webhook the instant it resolves. Set that up in Webhooks.

That's the whole loop
Create → capture → decision. Swap the ok_test_ key for ok_live_ and you are running real verifications.

Next steps