> 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-mobile-sdk/integration-overview/backend-integration/overview.md).

# Overview

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

This section applies to both iOS and Android integrations. The backend API calls are identical regardless of which mobile SDK your client app uses. There is no need for a separate backend section per platform.
{% endhint %}

After the KYC SDK completes on the user's device, your client backend needs to call VIDA's backend APIs to retrieve the KYC outcome, transaction records, and fraud evaluation results.

This section covers all backend calls - when to make them, how to make them, and how to act on the results.

## Who Is This For?

This section is for backend engineers responsible for:

* Receiving the SDK response forwarded from the mobile app
* Calling VIDA's APIs after the SDK session ends
* Routing users based on the KYC outcome (approved, manual review, or rejected)
* Audit logging and billing reconciliation using transaction IDs

## End-to-End Flow

Below is explaining how end-to-end flow KYC Backend works.

<figure><img src="https://2033469942-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC2s0IISjZwzGfw8dm215%2Fuploads%2FM95wIX2uO5FwyYxJYRAJ%2Fkyc-mobile-sdk-end-to-end-flow.png?alt=media&amp;token=6f94905b-7c79-4aa6-b855-8da59cb02669" alt=""><figcaption></figcaption></figure>

<details>

<summary>End-to-end Flow</summary>

{% code expandable="true" %}

````mmd
```mermaid
sequenceDiagram
    participant U  as End User
    participant App as Client App (iOS/Android)
    participant BE  as Client Backend
    participant GX  as VIDA My-Verify
    participant LS  as VIDA Liveness Service
 
    U->>App: Starts KYC
    App->>GX: OCR + ID Verification
    App->>LS: Liveness check (direct)
    App->>GX: Face Match (+ livenessTransactionIds)
    GX-->>App: SDK Response
    App->>BE: Forward SDK Response
 
    Note over BE,GX: Backend calls VIDA APIs
    BE->>GX: GET /api/v2/verify/status?verificationId=UUID
    GX-->>BE: overallStatus + per-operation breakdown
    BE->>GX: GET /api/v2/transaction?transactionId=UUID
    GX-->>BE: Full transaction payload
    BE->>GX: GET /api/v1/evaluation/{verificationId}
    GX-->>BE: Fraud Shield result
 
    BE->>App: KYC decision
    App->>U: Show result
```
````

{% endcode %}

</details>

### Quick Reference: Which API to Call

<table><thead><tr><th width="237.234375">Trigger</th><th width="259.93359375">API Endpoint</th><th>Purpose</th></tr></thead><tbody><tr><td>SDK response received</td><td><code>GET</code> <code>/api/v2/verify/status?verificationId=UUID</code></td><td>Get the overall KYC decision and per-operation status breakdown</td></tr><tr><td>Need full operation payload</td><td><code>GET</code> <code>/api/v2/transaction?transactionId=UUID</code></td><td>Retrieve the complete result for a single attempt — used for audit, billing, or dispute resolution. Add <code>includeDocuments=true</code> (optional) to also get presigned URLs for the submitted documents (default: <code>false</code>).</td></tr><tr><td>Fraud Shield is enabled</td><td><code>GET</code> <code>/api/v1/evaluation/{verificationId}</code></td><td>Get the full device/session fraud evaluation result</td></tr></tbody></table>

### Key Identifiers

Before making any API call, understand these four identifiers and how they relate to each other.

<table><thead><tr><th width="169">Identifier</th><th>Also Called</th><th>Description</th><th>Where to Find It</th></tr></thead><tbody><tr><td>verificationId</td><td>groupId, sessionId</td><td>Unique ID for the entire KYC session. Shared across all operations (OCR, IDV, Liveness, FaceMatch).</td><td>SDK response - top level</td></tr><tr><td>transactionId</td><td>-</td><td>Unique ID for one attempt of one operation. Each retry creates a new transactionId.</td><td>SDK response - per operation</td></tr><tr><td>clientTransactionId</td><td>groupId</td><td>Same value as verificationId. Used specifically when calling the Fraud Shield API.</td><td>SDK response - top level</td></tr><tr><td>partnerTrxId</td><td>-</td><td>Your own system's reference ID, echoed back by VIDA in every response.</td><td>SDK response - per operation</td></tr></tbody></table>

{% hint style="info" %}
**Critical: Liveness transactionId goes to a different API**

The transactionId inside `livenessDetails` must be used with the Liveness Service's own `GET` transaction API - NOT with `GET` `/api/v2/transaction?transactionId=UUID`.

The My-Verify transaction API does not serve liveness records.
{% endhint %}

### What to Do Based on overallStatus

Once you call `GET` `/api/v2/verify/status?verificationId=UUID`, use overallStatus to drive your business logic.

<table><thead><tr><th width="148.671875">OverallStatus</th><th>Meaning</th><th>Recommended Action</th></tr></thead><tbody><tr><td><code>VERIFIED</code></td><td>All required checks passed with latest results verified</td><td>Proceed with onboarding</td></tr><tr><td><code>REVIEW</code></td><td>All checks completed, none failed, but one or more flagged</td><td>Route to manual review queue</td></tr><tr><td><code>ERROR</code></td><td>At least one check failed (may also indicate fraud detected)</td><td>Check fraudResult field; retry or reject</td></tr><tr><td><code>IN_PROGRESS</code></td><td><p>At least one required operation has not been attempted yet. <br><br>Note: If the SDK has already</p><p>returned an error callback (containing failedOperation), this session will not transition to VERIFIED.</p><p>Treat as not verified and prompt the user to restart. </p><p></p><p>See Important Note below</p><p><br></p></td><td>Wait and poll again - the flow may still be running</td></tr><tr><td><code>FAILED</code></td><td>Session timed out or was abandoned (terminal state)</td><td>Mark case as failed; prompt user to restart</td></tr></tbody></table>

{% hint style="info" %}
**Important: 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 reject onboarding).

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),

&#x20; the session is considered terminal. You may treat this as a failed verification without waiting

&#x20; for the GET KYC Status API to update.<br>
{% endhint %}

{% hint style="info" %}
**Status Precedence**

`FAILED` > `IN_PROGRESS` > `ERROR` > `REVIEW` > `VERIFIED`

Once a case reaches `VERIFIED` or `FAILED`, it is terminal - no further operations are accepted. Any new request using that verificationId will be rejected with error code 5702.
{% endhint %}
