Skip to Content
KnowaKYC
Admin panel

Review (manual review)

The Review section of the admin console handles verification sessions routed to manual review. Reviewers inspect documents and applicant data, decide approval or rejection, and leave internal comments.

Integrators (server-to-server): the same queue is available on the Tenant API under /tenant/v1/kyc/review-tasks and /tenant/v1/kyb/review-tasks with scopes reviews:* / kyb.reviews:*. See Review tasks (Tenant API).

Admin console HTTP paths below are relative to the admin API (/admin/v1/...), not the Tenant API.

Task queue

The queue lists tasks (sessions) waiting for manual review or in progress. Each task shows the session identifier, queue arrival date, current status, and the assigned reviewer.

Filters

To manage the queue, the following filters are available:

  • By task status — new (waiting for assignment), in progress, approved, rejected.
  • By assigned reviewer — tasks for a specific reviewer or unassigned tasks.
  • By date — task arrival date range.

Queue statistics

The section header shows summary metrics:

  • Number of tasks waiting for assignment.
  • Number of tasks in progress.
  • Total number of tasks processed in the current period.

Working on a task

When you open a task, you have access to the following information:

Session and applicant data

  • Session and applicant identifier.
  • Data extracted from the document (full name, date of birth, document number — when OCR is available).
  • External user identifier (external_user_id).

Documents

  • Uploaded document and selfie images, viewable at full size.
  • Automated check results: document authenticity, image quality, face match.

Check history

  • Chronological order of verification step execution.
  • Automated check results (document check, liveness, face match, AML).

Reviewer actions

Task assignment

  • Assign to me — the reviewer takes the task. The status changes to "In progress".
  • Reassign — transfer the task to another reviewer (for example, when a reviewer with broader permissions is needed).

Decision

  • Approve — verification passes. The session receives the approved status.
  • Reject — verification fails. The session receives the rejected status. On rejection, you must:
    1. Pick a rejection reason from the structured list (GET /admin/v1/review/reject-reasons), for example blurry_document, face_not_matching, suspected_fraud, or expired_document.
    2. Optionally enter an additional comment with an explanation.

Canonical reject codes are the same as on the Tenant API (blurry_document, unreadable_document, face_not_matching, … — full list in Review tasks).

Changing task priority

Through PATCH /admin/v1/review/tasks/{task_id}/priority, a reviewer with the right permission can change the task priority (for example, urgent VIP cases). The action is logged as review.priority_updated.

Delegating a task

Through POST /admin/v1/review/tasks/{task_id}/delegate, a reviewer can delegate the task to the KnowaKYC manual-review team. The current delegation status is returned by GET /admin/v1/review/tasks/{task_id}/delegation-status.

Comments

Reviewers can add an internal comment through POST /admin/v1/review/tasks/{task_id}/comments. Comments are visible to other reviewers and stored in the task history for audit and context handover.

Accessing uploaded documents

To view a specific applicant document, use GET /admin/v1/review/tasks/{task_id}/documents/{document_id}/url — it returns a signed URL with a limited lifetime.

Queue statistics

Aggregate review-task metrics (queue size, in progress, processed for a period) are available through GET /admin/v1/review/stats (or GET /admin/v1/review/queue with scope kyc / kyb).

Resubmit requests

Sometimes automated checks pass, but during manual review a document field turns out to be unreadable (glare, blur, cropped frame, wrong document, expired, etc.). In that case you can ask the user to resubmit a specific step without rejecting the whole session. This preserves conversion and saves the user from running through verification from scratch.

Use case

  1. The reviewer opens a task in the review queue and sees that the front-side document photo is blurry.
  2. Instead of rejecting, the reviewer clicks "Request resubmit", picks the step (for example, document_capture) and the reason code (blurry).
  3. The session moves to awaiting_resubmit, and the selected step is reset.
  4. The user receives a notification and reopens the flow — they go straight to the reset step with the reason explained.
  5. After successful resubmission, the session returns to the review queue automatically.

Reason codes (reason_code)

The allowed reason codes are:

CodeDescription
illegibleText is unreadable
blurryImage is blurred
croppedDocument is cropped
glareGlare obscures the data
wrong_documentWrong document type uploaded
expired_documentDocument has expired
partialDocument is not fully captured

The same codes are used in webhook payloads and in the message shown to the user.

Limits and TTL

  • Up to 3 requests per session by default. A fourth attempt returns 409 Conflict with code conflict.
  • After the supporting backend version and schema are deployed, an approved database change can set flow_review_tasks.resubmit_limit_override to 4–10 for one task. Record that change in the operations audit trail. NULL keeps the default. Existing resubmit rows remain intact; the limit counts all requests regardless of status.
  • TTL — 7 days. After that, the request transitions to expired, and the session closes with the final status rejected (if no other channel completed it).
  • No more than one active request per (session, step) pair at a time. A duplicate attempt returns 409 Conflict with code resubmit_already_pending.
  • The session must be active for review resubmit. in_progress sessions are accepted. A completed session can also be accepted when it is in the manual-review/resubmit path; the backend reopens it and resets the selected step atomically. Requests against pending, paused, failed, cancelled, or expired sessions return 409 Conflict with code session_not_in_progress.
  • Only applicant-actionable step types can be resubmitted. The current allowlist is document, selfie, phone_otp, email_otp, kyb_company_input, kyb_business_document, and kyb_beneficiary_kyc.

Endpoints

Create a resubmit request

POST /admin/v1/review/tasks/{task_id}/request-resubmit
Content-Type: application/json

{
  "step_id": "550e8400-e29b-41d4-a716-446655440000",
  "reason_code": "blurry",
  "client_message": "Please re-take the document in daylight without glare",
  "internal_notes": "Date of birth field is unreadable due to glare"
}
  • step_id — UUID of the specific flow step to reset.
  • reason_code — required, from the canonical list above.
  • client_message (optional) — text shown to the user.
  • internal_notes (optional) — internal note for other reviewers; not shown to the user.

Response (200 OK):

{
  "data": {
    "request_id": "550e8400-e29b-41d4-a716-446655440099",
    "task_id": "550e8400-e29b-41d4-a716-446655440010",
    "status": "pending",
    "reason_code": "blurry",
    "expires_at": "2026-05-04T10:00:00Z"
  }
}

The action is logged in the audit trail (review.decided + decision=request_resubmit + reason_code).

List task resubmit requests

GET /admin/v1/review/tasks/{task_id}/resubmits

Returns every resubmit request for the task (including fulfilled / expired / cancelled), sorted by creation date.

Request lifecycle

StatusDescription
pendingRequest created, sent to the user, waiting for resubmission
fulfilledThe user resubmitted the step — the task is back in the review queue
expired7 days passed without resubmission — the session closes with rejection
cancelledRequest cancelled by the admin / tenant before fulfilment

The pending → fulfilled transition happens automatically after the user completes the requested step again.

User notification delivery

KnowaKYC delivers the resubmit notification through the available user channels:

  1. WebSocket push — instant, when the user has the verification flow open.
  2. Email / SMS — sent when the user needs a session-resume link outside the open verification page.

Webhook events

When a request is created or fulfilled, KnowaKYC sends webhook events:

  • verification.resubmit_requested — a reviewer requested resubmission. The payload includes session_id, flow_id, applicant_id, step_id, step_type, reason_code, client_message, attempt_number, requested_by_id, requested_by_name, expires_at.
  • verification.resubmit_fulfilled — the user resubmitted. The payload includes session_id, flow_id, applicant_id, step_id, reason_code, attempt_number, fulfilled_at.

Full payload schemas are in Webhooks API.

Outcome of processing

After a decision is made:

  • The session receives a final status (approved or rejected).
  • The result is available through the Tenant API and is sent to configured webhooks (events verification.approved / verification.declined).
  • The decision, rejection reason, and comments are recorded in the audit log.

Review comment webhooks

New comments on KYC review tasks emit verification.comment.created; new comments on KYB review tasks emit kyb.review.comment.created. Comments created in the tenant dashboard, the platform review console, and the tenant API use the same contract. These events do not change the verification decision or complete the session.

Subscribe to the exact event type for the required scope. Existing * subscriptions also receive these events. Delivery uses the existing webhook signature, environment filtering, retries, and delivery logs. Events are delivered at least once; consumers must deduplicate using the event id or idempotency_key. Arrival order is not guaranteed.

Example event data for KYC:

{
  "scope": "kyc",
  "task_id": "550e8400-e29b-41d4-a716-446655440010",
  "session_id": "550e8400-e29b-41d4-a716-446655440001",
  "flow_id": "550e8400-e29b-41d4-a716-446655440002",
  "external_id": "customer_123",
  "applicant_id": "550e8400-e29b-41d4-a716-446655440099",
  "comment": {
    "id": "550e8400-e29b-41d4-a716-446655440011",
    "content": "Please provide a clearer document photo.",
    "created_at": "2026-10-16T08:00:00.123456Z",
    "author_type": "admin_user"
  }
}

For KYB, scope is kyb and business_id replaces applicant_id when present. Author types are admin_user, superadmin_user, api_key, and system. Employee identifiers and names are not included in the webhook. All task comments are client-visible; decision internal_notes and resubmission client_message are separate fields and do not produce comment events. Only newly created comments generate these events; existing comments are not replayed.

Retrieve comments with GET /tenant/v1/kyc/review-tasks/{task_id}/comments (reviews:read) or GET /tenant/v1/kyb/review-tasks/{task_id}/comments (kyb.reviews:read). Creating a comment uses POST at the same path and the corresponding write scope. The successful creation response adds comment_id and created_at, matching the saved comment and webhook snapshot. Each successful POST creates a new comment; webhook event deduplication does not make repeated creation requests idempotent. After an uncertain request outcome, reconcile using the comments API before resubmitting.

The comment, webhook event, and outbox entry are committed together. Failure to persist the event rolls back comment creation. HTTP delivery happens asynchronously after commit, so a successful comment response is not proof of successful HTTP webhook delivery; use delivery logs.

On this page