> For the complete documentation index, see [llms.txt](https://docs.vida.id/identity-stack/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vida.id/identity-stack/verify/kyc-web-sdk/integration/backend-integration/kyc-status-api.md).

# KYC Status API

{% hint style="info" %}
**Purpose Of This Page**

Documents `GET` `/api/v2/verify/status?verificationId=UUID` - the primary post-SDK call to retrieve the overall KYC outcome and per-operation status breakdown.
{% endhint %}

### Step 2 - KYC Status API

Call this API immediately after your backend receives the SDK response. It returns the overall KYC decision and the status of every individual operation (OCR, IDV, Liveness, FaceMatch).

#### Endpoint

<mark style="color:blue;">**`GET`**</mark> `/api/v2/verify/status?verificationId=UUID`

#### When to Call

1. Mobile app receives the SDK response
2. App forwards the payload to your backend
3. Backend calls `GET` `/verify/status` using the `verificationId`
4. Backend acts on `overallStatus` to route the user

#### Request

| Parameter        | Location     | Type          | Required | Description                                |
| ---------------- | ------------ | ------------- | -------- | ------------------------------------------ |
| `verificationId` | Query string | string (uuid) | Yes      | The `verificationId` from the SDK response |

#### Response Fields

| Field                 | Type            | Description                                                                        |
| --------------------- | --------------- | ---------------------------------------------------------------------------------- |
| `verificationId`      | string          | The KYC case ID                                                                    |
| `overallStatus`       | string (enum)   | Overall outcome: `VERIFIED`, `REVIEW`, `ERROR`, `IN_PROGRESS`, or `FAILED`         |
| `updatedTime`         | ISO 8601 string | Timestamp of the last status update                                                |
| `documentCaptureMode` | string          | FRONT\_BACK\_SEPARATE or BOTH\_SIDE                                                |
| `requiredOperations`  | string\[]       | Operations that must complete for this flow type (determined by SDK `kycFlowType`) |
| `fraudResult`         | object          | Fraud Shield evaluation (if enabled). Empty object if not applicable.              |
| `operations`          | object          | Per-operation status and transaction ID breakdown (see below)                      |

#### operations Object

Each operation contains its latest result and a list of all previous attempt IDs.

{% hint style="info" %}
**Null status means not yet attempted**\
If an operation has not been attempted, `latestExecution` will contain: `status: null`, `transactionId: null`, `updatedTime: null.`

This results in an `overallStatus` of `IN_PROGRESS` if that operation is in the `requiredOperations` list.
{% endhint %}

<details>

<summary>JSON Response</summary>

{% code expandable="true" %}

```json
"operations": {
 
  // Document operations — split by front/back
  "ocr": {
    "front": {
      "latestExecution": {
        "status":        "VERIFIED",            // VERIFIED | REVIEW | ERROR | null
        "transactionId": "70f5e8df-...",
        "updatedTime":   "2025-10-30T23:40:04.512"
      },
      "previousTransactionIds": ["earlier-id-1"]  // IDs from retried attempts
    },
    "back": { ... }   // Same structure
  },
  "idVerification": {
    "front": { ... },
    "back":  { ... }
  },
 
  // Non-document operations — use 'result' key (no front/back split)
  "livenessVerification": {
    "result": {
      "latestExecution":      { "status": "VERIFIED", "transactionId": "...", "updatedTime": "..." },
      "previousTransactionIds": []
    }
  },
  "faceMatchVerification": {
    "result": { ... }   // Same structure
  }
}
```

{% endcode %}

</details>

#### overallStatus Values

<table><thead><tr><th width="155.00390625">Status</th><th width="460.03125">When It Applies</th><th>Precedence</th></tr></thead><tbody><tr><td><code>FAILED</code></td><td><p>KYC session remained <code>IN_PROGRESS</code> beyond the configured timeout (user abandoned, SDK crashed, etc.). Terminal - no further updates accepted. </p><p></p><p>The configured timeout determines how long an IN_PROGRESS session remains open before automatically transitioning to FAILED. Customers who need faster resolution should use the SDK callback response as the primary signal for failure cases (see Important Note below).</p></td><td>1 (highest)</td></tr><tr><td><code>IN_PROGRESS</code></td><td><p>At least one required operation has not been attempted yet.<br><br><strong>Note:</strong> An <code>IN_PROGRESS</code> status does not guarantee the user will complete the flow. If the SDK has already returned an error callback to the host app, the user can no longer resume this verificationId.</p><p>In this case, treat the KYC outcome as not verified. See the Important Note section below for recommended decision-making logic.</p></td><td>2</td></tr><tr><td><code>ERROR</code></td><td>All required operations have been attempted, and at least one latest result is <code>ERROR</code>.</td><td>3</td></tr><tr><td><code>REVIEW</code></td><td>All required operations are complete, none are ERROR, but one or more are <code>REVIEW</code>.</td><td>4</td></tr><tr><td><code>VERIFIED</code></td><td>All required operations are complete and every latest result is <code>VERIFIED</code>.</td><td>5 (lowest)</td></tr></tbody></table>

{% hint style="info" %}
**Important Note**

Interpreting KYC Status for Decision-Making When using the GET KYC Status API to determine a user's KYC outcome, we recommend the following approach:

* **VERIFIED** -> The user has successfully passed KYC. You may proceed with granting access or completing onboarding.
* Any other status (**including IN\_PROGRESS or FAILED**) -> The user has NOT successfully completed KYC. Your application should treat this as a non-verified outcome and handle accordingly (e.g., prompt the user to retry, or restrict access). Additionally, use the SDK callback response as your primary signal for real-time decision-making:
* If the SDK returns a success callback, poll the GET KYC Status API to confirm the VERIFIED status.
* If the SDK returns an error callback (containing failedOperation in the operations array), the session is considered terminal. You may treat this as a failed verification without waiting for the GET KYC Status API to update.
  {% endhint %}

#### Sample Responses

**Verified - All Checks Passed**

<details>

<summary>JSON Response</summary>

{% code expandable="true" %}

```json
{
  "verificationId": "005e9def-c93a-3703-af5b-424a42f7c08a",
  "overallStatus": "VERIFIED",
  "updatedTime": "2025-10-30T23:43:41.936",
  "documentCaptureMode": "FRONT_BACK_SEPARATE",
  "requiredOperations": ["ocr", "idVerification", "livenessVerification", "faceMatchVerification"],
  "fraudResult": {},
  "operations": {
    "ocr": {
      "front": { "latestExecution": { "status": "VERIFIED", "transactionId": "70f5e8df-..." }, "previousTransactionIds": [] },
      "back":  { "latestExecution": { "status": "VERIFIED", "transactionId": "5282b0b8-..." }, "previousTransactionIds": [] }
    },
    "idVerification": {
      "front": { "latestExecution": { "status": "VERIFIED", "transactionId": "70f5e8df-..." }, "previousTransactionIds": [] },
      "back":  { "latestExecution": { "status": "VERIFIED", "transactionId": "5282b0b8-..." }, "previousTransactionIds": [] }
    },
    "livenessVerification":  { "result": { "latestExecution": { "status": "VERIFIED", "transactionId": "47ad1045-..." }, "previousTransactionIds": [] } },
    "faceMatchVerification": { "result": { "latestExecution": { "status": "VERIFIED", "transactionId": "35d26180-..." }, "previousTransactionIds": [] } }
  }
}


```

{% endcode %}

</details>

**IN\_PROGRESS - Liveness and FaceMatch not yet done**

<details>

<summary>JSON Response</summary>

{% code expandable="true" %}

```json
{
  "verificationId": "434790d6-ecd4-4b4d-876d-9a208e260e27",
  "overallStatus": "IN_PROGRESS",
  "updatedTime": "2025-10-30T23:58:30.907",
  "documentCaptureMode": "FRONT_BACK_SEPARATE",
  "requiredOperations": ["ocr", "idVerification", "livenessVerification", "faceMatchVerification"],
  "fraudResult": {},
  "operations": {
    "ocr": {
      "front": { "latestExecution": { "status": "REVIEW",   "transactionId": "381e5639-..." }, "previousTransactionIds": [] },
      "back":  { "latestExecution": { "status": "REVIEW",   "transactionId": "381e5639-..." }, "previousTransactionIds": [] }
    },
    "idVerification": {
      "front": { "latestExecution": { "status": "VERIFIED", "transactionId": "381e5639-..." }, "previousTransactionIds": [] },
      "back":  { "latestExecution": { "status": "VERIFIED", "transactionId": "381e5639-..." }, "previousTransactionIds": [] }
    },
    "livenessVerification":  { "result": { "latestExecution": { "status": null, "transactionId": null, "updatedTime": null }, "previousTransactionIds": [] } },
    "faceMatchVerification": { "result": { "latestExecution": { "status": null, "transactionId": null, "updatedTime": null }, "previousTransactionIds": [] } }
  }
}


```

{% endcode %}

</details>

**ERROR - Fraud detected on Face Match**

<details>

<summary>JSON Response</summary>

{% code expandable="true" %}

```json
{
  "verificationId": "abc-123",
  "overallStatus": "ERROR",
  "operations": {
    "ocr":                   { "front": { "latestExecution": { "status": "VERIFIED" } } },
    "idVerification":        { "front": { "latestExecution": { "status": "VERIFIED" } } },
    "livenessVerification":  { "result": { "latestExecution": { "status": "VERIFIED" } } },
    "faceMatchVerification": { "result": { "latestExecution": { "status": "ERROR"    } } }
  },
  "fraudResult": {
    "configuredErrorThreshold":   "HIGH",
    "configuredWarningThreshold":  "MEDIUM",
    "result": {
      "verificationId": "abc-123",
      "riskLevel": "HIGH",
      "evaluatedAt": "2026-04-01T10:30:00.000+07:00",
      "deviceProfile":   { ... },
      "behaviorMetrics": { ... },
      "sessionContext":  { ... },
      "userProfile":     { ... },
      "ipProfile":       { ... },
      "ruleEvaluations": [ ... ]
    }
  }
}


```

{% endcode %}

</details>

#### Using previous TransactionIds for Reconciliation

The `operations` object returns not only the latest `transactionId` per operation, but also all previous attempt IDs from retries. You can pass any of these to the [*Transaction Details API*](/identity-stack/verify/kyc-web-sdk/integration/backend-integration/transaction-details-api.md).

<details>

<summary>Responses</summary>

{% code expandable="true" %}

```json
// From GET /verify/status response:
operations.ocr.front.latestExecution.transactionId = "70f5e8df-..."
operations.ocr.front.previousTransactionIds        = ["earlier-id-1", "earlier-id-2"]
 
// Pass any of these to the Transaction Details API:
GET /api/v1/transaction/70f5e8df-...      ← latest attempt
GET /api/v1/transaction/earlier-id-1      ← previous attempt (for reconciliation)
```

{% endcode %}

</details>
