Review tasks (manual review API)
Tenant API methods for server-side manual review: list the queue, inspect a task, assign it to the calling API key, approve or reject, comment, change priority, request a step resubmit, and fetch document URLs.
These endpoints are intended for integrators that run review outside the admin console (their own back-office or automation). Admin-panel operators use the console UI; see Admin → Review.
Base paths:
| Product | Base |
|---|---|
| KYC | /tenant/v1/kyc/review-tasks |
| KYB | /tenant/v1/kyb/review-tasks |
Authentication: HMAC-SHA256 with a KYC or KYB API key. See Authentication.
Required scopes
| Scope | Access |
|---|---|
reviews:read | KYC: list queue, stats, reject reasons, task detail, comments, resubmits |
reviews:write | KYC: assign, approve, reject, comment, priority, request resubmit |
media:read | KYC: document presigned URLs (together with reviews:read) |
kyb.reviews:read | KYB read surface |
kyb.reviews:write | KYB write surface |
kyb.media:read | KYB document URLs (together with kyb.reviews:read) |
KYC keys cannot call /kyb/review-tasks/* (HTTP 403). KYB keys cannot call /kyc/review-tasks/*.
Mutations are attributed to the API key (actor_type=api_key): assignment, comments, and final decisions store the key id and display name.
Response fields for actor identity (when present):
| Resource | Fields |
|---|---|
| Queue item / task detail | assigned_to, assigned_to_type (admin_user | superadmin_user | api_key), assigned_display_name |
| Task detail after decision | decision_by, decision_by_type, decision_display_name |
| Comment | author_id, author_type, author_display_name |
Typical flow
- Subscribe to
verification.needs_review(and related webhooks) — see Webhooks. GET .../review-tasks— pull the queue (status=pendingorin_progress).GET .../review-tasks/{task_id}— load detail andreview_reasons.POST .../assign— claim the task for this API key.- Inspect media via
GET .../documents/{document_id}/urlwhen needed. - Decide:
POST .../approvePOST .../rejectwith a canonicalreason_codefromGET .../reject-reasonsor a nonblank owncomment- or
POST .../request-resubmitfor a single step (limits apply)
After a final decision, webhooks emit the terminal verification outcome (verification.approved / verification.declined / session completed).
List queue
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
page?integerPage (default 1)
page_size?integerPage size (1-100, default 50)
status?stringComma-separated statuses: pending,assigned,in_progress,awaiting_resubmit,approved,rejected,completed
priority?stringComma-separated priorities: low,medium,high,urgent
flow_id?stringFlow UUID
assigned_to?stringReviewer/API key UUID
session_id?stringSession UUID
applicant_id?stringApplicant UUID
q?stringSearch by external ID/name
date_from?stringFrom (RFC3339)
date_to?stringTo (RFC3339)
sla_status?stringSLA status: breached, warning, ok
sort?stringSort order: priority_desc, sla_asc, created_at_asc, created_at_desc
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?array<>pagination?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks' \ -H 'X-Timestamp: string'{ "pagination": { "page": 0, "page_size": 0, "total_items": 0, "total_pages": 0 }, "success": true, "data": [ { "applicant_first_name": "string", "applicant_full_name": "string", "applicant_full_name_latin": "string", "applicant_full_name_native": "string", "applicant_full_name_original": "string", "applicant_id": "string", "applicant_last_name": "string", "applicant_middle_name": "string", "applicant_nationality": "string", "assigned_at": "string", "assigned_display_name": "string", "assigned_to": "string", "assigned_to_type": "string", "business_company_name": "string", "business_country": "string", "business_external_id": "string", "business_id": "string", "business_registration_number": "string", "business_tax_number": "string", "created_at": "string", "external_user_id": "string", "flow_id": "string", "flow_name": "string", "id": "string", "priority": 0, "reason": "string", "review_reasons": [ {} ], "reviewer_email": "string", "reviewer_first_name": "string", "reviewer_last_name": "string", "session_created_at": "string", "session_environment": "string", "session_id": "string", "sla_breached": true, "sla_deadline": "string", "started_at": "string", "status": "string", "system_decision": "string", "tenant_id": "string", "verification_result": "string", "verification_score": 0 } ]}KYB equivalent: GET /tenant/v1/kyb/review-tasks (same filters; search is company/external id oriented).
Status filter aliases
| Query value | Stored statuses |
|---|---|
in_progress | assigned |
completed | approved, rejected |
| other values | passed through (pending, awaiting_resubmit, …) |
Priority values
| Wire value | Numeric priority |
|---|---|
low | 1 |
medium | 2 |
high | 3 |
urgent | 4 |
Stats and reject reasons
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks/stats' \ -H 'X-Timestamp: string'{ "success": true, "data": { "avg_time_minutes": 0, "completed_today": 0, "in_progress": 0, "pending": 0 }}ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?array<>pagination?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks/reject-reasons' \ -H 'X-Timestamp: string'{ "pagination": { "has_more": true, "limit": 0, "next_cursor": "string", "offset": 0, "total": 0 }, "success": true, "data": [ { "category": "string", "code": "string", "label_en": "string", "label_ru": "string" } ]}Canonical rejection codes (must be used on POST .../reject):
| Code | Category |
|---|---|
blurry_document | document |
expired_document | document |
wrong_document_type | document |
document_mismatch | document |
unreadable_document | document |
face_not_matching | biometric |
poor_selfie_quality | biometric |
liveness_failed | biometric |
face_obscured | biometric |
sanctions_match | aml |
pep_match | aml |
adverse_media | aml |
suspected_fraud | general |
duplicate_account | general |
incomplete_data | general |
other | general |
Invalid reason_code → HTTP 400.
Task detail, comments, documents
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks/string' \ -H 'X-Timestamp: string'{ "success": true, "data": { "comments": [ { "author_display_name": "string", "author_id": "string", "author_type": "string", "content": "string", "created_at": "string", "id": "string", "task_id": "string" } ], "task": { "applicant_id": "string", "approval_blocked_reason": "string", "assigned_at": "string", "assigned_display_name": "string", "assigned_to": "string", "assigned_to_type": "string", "completed_at": "string", "created_at": "string", "decision": "string", "decision_at": "string", "decision_by": "string", "decision_by_type": "string", "decision_display_name": "string", "external_user_id": "string", "flow_id": "string", "flow_name": "string", "history": [ { "action": "string", "actor_id": "string", "actor_name": "string", "actor_type": "string", "created_at": "string", "details": { "property1": null, "property2": null }, "id": "string" } ], "id": "string", "notes": "string", "priority": 0, "reason": "string", "reason_details": "string", "reject_reason_code": "string", "resubmit_limit_override": 0, "review_reasons": [ {} ], "session_created_at": "string", "session_entity_type": "string", "session_environment": "string", "session_id": "string", "session_status": "string", "status": "string", "system_decision": "string", "tenant_id": "string" } }}Unassigned tasks omit assigned_to / assigned_to_type / assigned_display_name (they are not defaulted to admin_user). After assign or decision, type is one of admin_user | superadmin_user | api_key.
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?array<>pagination?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks/string/comments' \ -H 'X-Timestamp: string'{ "pagination": { "has_more": true, "limit": 0, "next_cursor": "string", "offset": 0, "total": 0 }, "success": true, "data": [ { "author_display_name": "string", "author_id": "string", "author_type": "string", "content": "string", "created_at": "string", "id": "string", "task_id": "string" } ]}ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Comment payload
application/json- body
content?stringContent is the comment text (required, non-empty after trim).
OK
application/json- response
data?success?booleancurl -X POST 'https://example.com/tenant/v1/kyc/review-tasks/string/comments' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "success": true, "data": { "author_display_name": "string", "author_id": "string", "author_type": "string", "comment_id": "string", "content": "string", "created_at": "string", "message": "string", "task_id": "string" }}Comment body field is content (JSON string). Example: {"content":"Needs a clearer passport photo"}. Response includes author_id, author_type (api_key for HMAC callers), and author_display_name.
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
document_id*stringDocument ID or storage key suffix
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?unknownsuccess?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks/string/documents/string/url' \ -H 'X-Timestamp: string'{ "data": null, "success": true}document_id may be a full storage key or a suffix under the session documents prefix. Path traversal (.., \) is rejected.
Mutations: assign, priority, decide
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?unknownsuccess?booleancurl -X POST 'https://example.com/tenant/v1/kyc/review-tasks/string/assign' \ -H 'X-Timestamp: string'{ "data": null, "success": true}Assign only succeeds for tasks in pending or awaiting_resubmit. The task is assigned to the current API key (not an admin user).
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Priority payload
application/json- body
priority?stringOK
application/json- response
data?unknownsuccess?booleancurl -X PATCH 'https://example.com/tenant/v1/kyc/review-tasks/string/priority' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": null, "success": true}ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Optional comment and optimistic lock timestamp
application/json- body
comment?stringif_unmodified_since?stringOK
application/json- response
data?unknownsuccess?booleancurl -X POST 'https://example.com/tenant/v1/kyc/review-tasks/string/approve' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": null, "success": true}ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Reject payload
application/json- body
comment?stringif_unmodified_since?stringreason_code?stringOK
application/json- response
data?unknownsuccess?booleancurl -X POST 'https://example.com/tenant/v1/kyc/review-tasks/string/reject' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": null, "success": true}Optional optimistic concurrency: send if_unmodified_since (RFC3339) with the last known updated_at / task timestamp when available.
Resubmit
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Resubmit payload
application/json- body
client_message?stringinternal_notes?stringreason_code?stringrequest_id?stringscope?stringstep_id?stringOK
application/json- response
data?success?booleancurl -X POST 'https://example.com/tenant/v1/kyc/review-tasks/string/request-resubmit' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "success": true, "data": { "clientMessage": "string", "createdAt": "string", "deliveredAt": "string", "deliveryChannel": "string", "expiresAt": "string", "fulfilledAt": "string", "id": "string", "internalNotes": "string", "reasonCode": "string", "requestedBy": "string", "requestedByDisplayName": "string", "requestedByType": "string", "scope": "string", "sessionID": "string", "status": "string", "stepID": "string", "taskID": "string", "tenantID": "string", "updatedAt": "string" }}ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
task_id*stringReview task UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
OK
application/json- response
data?array<>pagination?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/review-tasks/string/resubmits' \ -H 'X-Timestamp: string'{ "pagination": { "has_more": true, "limit": 0, "next_cursor": "string", "offset": 0, "total": 0 }, "success": true, "data": [ { "clientMessage": "string", "createdAt": "string", "deliveredAt": "string", "deliveryChannel": "string", "expiresAt": "string", "fulfilledAt": "string", "id": "string", "internalNotes": "string", "reasonCode": "string", "requestedBy": "string", "requestedByDisplayName": "string", "requestedByType": "string", "scope": "string", "sessionID": "string", "status": "string", "stepID": "string", "taskID": "string", "tenantID": "string", "updatedAt": "string" } ]}Resubmit reason codes (step quality) are separate from final rejection codes:
| Code | Meaning |
|---|---|
illegible | Text unreadable |
blurry | Image blurred |
cropped | Document cropped |
glare | Glare |
wrong_document | Wrong type |
expired_document | Expired |
partial | Incomplete capture |
Limits: ≤ 3 resubmits per session, 7-day TTL, one active resubmit request per session. See webhooks Manual Review Resubmit events.
KYB
All operations are mirrored under /tenant/v1/kyb/review-tasks with kyb.reviews:* and kyb.media:read. Interactive reference: KYB API reference and OpenAPI.
What is admin-only
Not exposed on the Tenant API (admin console / JWT only):
- reassign / unassign to another human reviewer
- delegate to the KnowaKYC manual-review team
- cancel a resubmit request
- list resubmittable steps helper endpoints used by the console UI
Related
- Webhooks —
verification.needs_review, resubmit events, terminal outcomes - Authentication — HMAC and scopes
- Admin → Review — operator UI workflow
- OpenAPI — full machine-readable spec