> 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/sdk-response.md).

# SDK Response

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

Explains the structure of the SDK JSON payload, what each field means, and which values to extract before making backend API calls.
{% endhint %}

### Step 1 - Parse the SDK Response

When the KYC Web SDK finishes in the browser, it delivers a single JSON payload to your host app through the `onComplete` callback. Your app must forward this to your backend. This payload contains all the identifiers you need to call VIDA's backend APIs.

{% hint style="info" %}
**Note**: On failure, the SDK invokes `onError` instead, which returns an errors array (plus any results completed before the failure). The Web SDK does not use a top-level `failedOperation` field - use the errors array to route error handling on your backend. See the [*Callback Methods*](/identity-stack/verify/kyc-web-sdk/customization/callback-methods.md) page for the full error structure.
{% endhint %}

<details>

<summary><strong>Response Structure</strong></summary>

{% code expandable="true" %}

```json
{
  "verificationId",                    ← Master ID for this KYC session (derived from backend groupId)

  "docVerificationResult": {
    "verificationId",                  ← Same as top-level verificationId
    "transactionId",                   ← Pass to GET /api/v1/transaction (latest/successful attempt)
    "card",                            ← Document country and type
    "imageQualityResult": {            ← Blur and low-light scores
      "front",
      "back"
    },
    "idVerificationResult": {          ← Spoofing, landmark, forgery scores
      "front",
      "back"
    },
    "ocrResult": {                     ← Extracted text (name, ID number, DOB...)
      "front",
      "back"
    },
    "attemptedTransactionIds"          ← All attempt IDs (only present when retries occurred)
  },

  "faceMatchVerificationResult": {
    "code",
    "message",
    "score",                           ← Face match similarity score
    "transactionId"                    ← Pass to GET /api/v1/transaction
  },

  "livenessVerificationResult": {
    "score",                           ← Liveness score
    "liveImage",                       ← Boolean — true if a live photo
    "message",
    "code",
    "transactionId",                   ← Use with Liveness Service ONLY (NOT My-Verify)
    "base64Image",                     ← Captured selfie (on-device only)
    "livenessScores"                   ← Per-method scores — color flash only (see Response Variations)
  }
}
```

{% endcode %}

</details>

#### What to Extract and Store

| Field                                        | Where to Find It                                    | Used For                                                                   |
| -------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------- |
| verificationId                               | Top level                                           | All backend API calls (`GET` `/verify/status`, `GET` `/api/v1/evaluation`) |
| docVerificationResult.transactionId          | docVerificationResult (default mode)                | `GET` `/api/v1/transaction` - `OCR/IDV`                                    |
| docFrontSideVerificationResult.transactionId | Top level (per-side mode)                           | `GET` `/api/v1/transaction` - OCR/IDV front                                |
| docBackSideVerificationResult.transactionId  | Top level (per-side mode)                           | `GET` `/api/v1/transaction` - OCR/IDV back                                 |
| faceMatchVerificationResult.transactionId    | Top level                                           | `GET` `/api/v1/transaction` - Face Match                                   |
| livenessVerificationResult.transactionId     | Top level                                           | Liveness Service `GET` transaction (NOT My-Verify)                         |
| warnings\[].code                             | Per card side/ faceMatchVerificationResult.warnings | Alert logging - non-blocking                                               |

{% hint style="info" %}
**Portrait image in ocrResult vs. documents API**

The portrait image and `base64Image` fields returned in the SDK payload are populated on-device by the SDK only - they are not returned in API responses.

The actual portrait image (extracted from the ID card) is available via `GET` `/api/v1/transaction/{transactionId}?includeDocuments=true` as a presigned URL in documents.portrait. See the [*Transaction Details API*](/identity-stack/verify/kyc-web-sdk/integration/backend-integration/transaction-details-api.md) page for details.

*(Verify this field name matches the Web SDK payload before publishing - confirm whether the Web SDK exposes portraitImage inside `ocrResult` the same way the Mobile SDK does.)*
{% endhint %}

#### Understanding Scores

Each OCR field, verification check, and image quality check includes a score and a threshold. Use the table below to determine what constitutes a passing result.

| Check Type             | Field                                       | Passes When                                                                                                                                              |
| ---------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OCR extraction         | name, idNumber, dob, address, etc.          | score >= threshold (confidence in extracted value)                                                                                                       |
| Anti-spoofing          | spoofingResult.recapScore, colorPrint, etc. | score < threshold (lower = less spoof-like)                                                                                                              |
| Forgery detection      | forgeryResult.summary                       | score < threshold (lower = less forgery-like)                                                                                                            |
| Image quality          | imageQualityResult.blurriness, lowLight     | score < threshold (lower = better quality)                                                                                                               |
| Landmark detection     | landmarkResult.containerResult items        | score > 0 (0 = not detected / occluded)                                                                                                                  |
| Liveness (Color Flash) | livenessScores\[].score per method          | See [*Callback Methods*](/identity-stack/verify/kyc-web-sdk/customization/callback-methods.md) - types: passiveLiveness, imageManipulation, colorCaptcha |
