> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gu1.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Check Verification Status

> Query KYC validation results and verification details — in the gu1 KYC API for identity verification flows, with examples for check status use cases.

## Overview

After a customer completes their KYC verification, you can query the results to check the verification status, extracted data, and decision details. This is useful for:

* Checking if verification is complete
* Retrieving verified customer information
* Getting verification results and risk assessment
* Auditing verification history

<Note>
  While you can poll this API, we strongly recommend using [webhooks](/en/use-cases/kyc/webhook-integration) to receive real-time notifications when verification completes.
</Note>

## Get Validation by ID

Retrieve a specific validation using its ID:

### Endpoint

```
GET https://api.gu1.ai/api/kyc/validations/{id}
```

### Example

<CodeGroup>
  ```javascript Node.js theme={null}
  const validationId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(
    `https://api.gu1.ai/api/kyc/validations/${validationId}`,
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
      }
    }
  );

  const validation = await response.json();

  console.log('Status:', validation.status);
  console.log('Verified:', validation.status === 'approved');

  if (validation.status === 'approved') {
    console.log('Verified data:', validation.extractedData);
    console.log('Verified fields:', validation.verifiedFields);
  }
  ```

  ```python Python theme={null}
  import requests

  validation_id = '550e8400-e29b-41d4-a716-446655440000'

  response = requests.get(
      f'https://api.gu1.ai/api/kyc/validations/{validation_id}',
      headers={'Authorization': 'Bearer YOUR_API_KEY'}
  )

  validation = response.json()

  print('Status:', validation['status'])
  print('Verified:', validation['status'] == 'approved')

  if validation['status'] == 'approved':
      print('Verified data:', validation['extractedData'])
      print('Verified fields:', validation['verifiedFields'])
  ```
</CodeGroup>

## Get Current Validation for Entity

If you don't have the validation ID, retrieve the current active validation for a person entity:

### Endpoint

```
GET https://api.gu1.ai/api/kyc/entities/{entityId}/current
```

### Example

<CodeGroup>
  ```javascript Node.js theme={null}
  const entityId = '123e4567-e89b-12d3-a456-426614174000';

  const response = await fetch(
    `https://api.gu1.ai/api/kyc/entities/${entityId}/current`,
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
      }
    }
  );

  if (response.status === 404) {
    console.log('No active validation for this entity');
  } else {
    const validation = await response.json();
    console.log('Current validation:', validation.status);
  }
  ```

  ```python Python theme={null}
  import requests

  entity_id = '123e4567-e89b-12d3-a456-426614174000'

  response = requests.get(
      f'https://api.gu1.ai/api/kyc/entities/{entity_id}/current',
      headers={'Authorization': 'Bearer YOUR_API_KEY'}
  )

  if response.status_code == 404:
      print('No active validation for this entity')
  else:
      validation = response.json()
      print('Current validation:', validation['status'])
  ```
</CodeGroup>

## Get Entity KYC Status

Get a summary of an entity's KYC verification status:

### Endpoint

```
GET https://api.gu1.ai/api/kyc/entities/{entityId}/status
```

### Response

```json theme={null}
{
  "entityId": "123e4567-e89b-12d3-a456-426614174000",
  "hasKyc": true,
  "isVerified": true,
  "currentValidation": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "approved",
    
    "verifiedAt": "2025-01-15T11:00:00Z"
  },
  "lastVerifiedAt": "2025-01-15T11:00:00Z",
  "expiresAt": "2026-01-15T11:00:00Z",
  "needsReverification": false
}
```

### Example

<CodeGroup>
  ```javascript Node.js theme={null}
  const entityId = '123e4567-e89b-12d3-a456-426614174000';

  const response = await fetch(
    `https://api.gu1.ai/api/kyc/entities/${entityId}/status`,
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
      }
    }
  );

  const status = await response.json();

  if (status.isVerified) {
    console.log('✅ Customer is verified');
    console.log('Verified on:', status.lastVerifiedAt);

    if (status.needsReverification) {
      console.log('⚠️ Needs reverification');
    }
  } else {
    console.log('❌ Customer not verified');
  }
  ```

  ```python Python theme={null}
  import requests

  entity_id = '123e4567-e89b-12d3-a456-426614174000'

  response = requests.get(
      f'https://api.gu1.ai/api/kyc/entities/{entity_id}/status',
      headers={'Authorization': 'Bearer YOUR_API_KEY'}
  )

  status = response.json()

  if status['isVerified']:
      print('✅ Customer is verified')
      print('Verified on:', status['lastVerifiedAt'])

      if status['needsReverification']:
          print('⚠️ Needs reverification')
  else:
      print('❌ Customer not verified')
  ```
</CodeGroup>

## Understanding Validation Results

### Status Values

<ResponseField name="status" type="string">
  Current validation status:

  * **`pending`** - Validation created, waiting for customer to start
  * **`in_progress`** - Customer is actively completing verification (filling out form)
  * **`in_review`** - Verification completed, requires manual review from compliance team
  * **`approved`** - Verification successful, identity confirmed
  * **`rejected`** - Verification failed, identity not confirmed
  * **`expired`** - Verification session expired (typically after 7 days)
  * **`abandoned`** - Customer started but didn't complete verification
  * **`cancelled`** - Validation manually cancelled
</ResponseField>

### Decision object (`decision`)

When status is `approved` or `rejected`, the `decision` field contains detailed provider results. When a validation reaches a terminal or in-review state with provider results, `decision` contains the full verification outcome from the KYC flow. Gu1 **always stores and returns both shapes** for each feature: a singular object (legacy) **and** a one-element array (current). You can read either `id_verification` or `id_verifications[0]`; they are kept in sync. The same applies to `liveness` / `liveness_checks`, `face_match` / `face_matches`, `aml_screening` / `aml_screenings`, and `ip_analysis` / `ip_analyses`.

Media fields (`front_image`, `reference_image`, `images.*`, etc.) are **Gu1 storage keys** (`kyc/...`) after ingest. Fetch them via the [validation media API](/en/use-cases/kyc/validation-media). Older rows may still contain short-lived HTTPS URLs until synced.

**Approved example (complete):**

```json theme={null}
{
  "status": "Approved",
  "workflow_type": "standard",
  "session_id": "7c0fa22d-0cfa-4a78-8090-7c842397e788",
  "session_number": 921,
  "features": ["ID_VERIFICATION", "LIVENESS", "FACE_MATCH", "IP_ANALYSIS"],
  "images": {
    "documentFront": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
    "documentBack": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-back.jpg",
    "selfie": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg"
  },
  "id_verification": {
    "status": "Approved",
    "node_id": "feature_ocr",
    "document_type": "Passport",
    "document_number": "AB123456",
    "first_name": "John",
    "last_name": "Doe",
    "full_name": "John Doe",
    "date_of_birth": "1990-05-20",
    "nationality": "US",
    "gender": "M",
    "age": 35,
    "issuing_state": "US",
    "expiration_date": "2030-05-20",
    "date_of_issue": "2020-05-20",
    "front_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
    "back_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-back.jpg",
    "portrait_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
    "warnings": [],
    "matches": []
  },
  "id_verifications": [
    {
      "status": "Approved",
      "node_id": "feature_ocr",
      "document_type": "Passport",
      "document_number": "AB123456",
      "first_name": "John",
      "last_name": "Doe",
      "full_name": "John Doe",
      "date_of_birth": "1990-05-20",
      "nationality": "US",
      "gender": "M",
      "age": 35,
      "issuing_state": "US",
      "expiration_date": "2030-05-20",
      "date_of_issue": "2020-05-20",
      "front_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
      "back_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-back.jpg",
      "portrait_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
      "warnings": [],
      "matches": []
    }
  ],
  "liveness": {
    "status": "Approved",
    "node_id": "feature_liveness",
    "score": 98,
    "method": "PASSIVE",
    "reference_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/liveness-reference.jpg",
    "video_url": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/liveness-video.webm",
    "face_quality": 92.5,
    "warnings": [],
    "matches": []
  },
  "liveness_checks": [
    {
      "status": "Approved",
      "node_id": "feature_liveness",
      "score": 98,
      "method": "PASSIVE",
      "reference_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/liveness-reference.jpg",
      "video_url": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/liveness-video.webm",
      "face_quality": 92.5,
      "warnings": [],
      "matches": []
    }
  ],
  "face_match": {
    "status": "Approved",
    "node_id": "feature_face_match",
    "score": 95,
    "source_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
    "target_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
    "warnings": []
  },
  "face_matches": [
    {
      "status": "Approved",
      "node_id": "feature_face_match",
      "score": 95,
      "source_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
      "target_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
      "warnings": []
    }
  ],
  "aml_screening": {
    "status": "Approved",
    "node_id": "feature_aml",
    "warnings": []
  },
  "aml_screenings": [
    {
      "status": "Approved",
      "node_id": "feature_aml",
      "warnings": []
    }
  ],
  "ip_analysis": {
    "status": "Approved",
    "node_id": "feature_ip_analysis",
    "ip_address": "203.0.113.10",
    "country": "US",
    "region": "New York",
    "city": "New York",
    "is_vpn": false,
    "is_proxy": false,
    "warnings": []
  },
  "ip_analyses": [
    {
      "status": "Approved",
      "node_id": "feature_ip_analysis",
      "ip_address": "203.0.113.10",
      "country": "US",
      "region": "New York",
      "city": "New York",
      "is_vpn": false,
      "is_proxy": false,
      "warnings": []
    }
  ]
}
```

**Rejected example (complete):**

```json theme={null}
{
  "status": "Declined",
  "workflow_type": "standard",
  "session_id": "7c0fa22d-0cfa-4a78-8090-7c842397e788",
  "session_number": 921,
  "features": ["ID_VERIFICATION", "LIVENESS", "FACE_MATCH"],
  "images": {
    "documentFront": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
    "selfie": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg"
  },
  "id_verification": {
    "status": "Declined",
    "node_id": "feature_ocr",
    "document_type": "Passport",
    "document_number": "AB123456",
    "first_name": "John",
    "last_name": "Doe",
    "full_name": "John Doe",
    "front_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
    "portrait_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
    "warnings": [
      {
        "risk": "DOCUMENT_AUTHENTICITY_FAILED",
        "feature": "ID_VERIFICATION",
        "short_description": "Document authenticity could not be verified",
        "long_description": "The document failed authenticity checks.",
        "log_type": "error"
      }
    ],
    "matches": []
  },
  "id_verifications": [
    {
      "status": "Declined",
      "node_id": "feature_ocr",
      "document_type": "Passport",
      "document_number": "AB123456",
      "first_name": "John",
      "last_name": "Doe",
      "full_name": "John Doe",
      "front_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
      "portrait_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
      "warnings": [
        {
          "risk": "DOCUMENT_AUTHENTICITY_FAILED",
          "feature": "ID_VERIFICATION",
          "short_description": "Document authenticity could not be verified",
          "long_description": "The document failed authenticity checks.",
          "log_type": "error"
        }
      ],
      "matches": []
    }
  ],
  "liveness": {
    "status": "Declined",
    "node_id": "feature_liveness",
    "score": 42,
    "method": "PASSIVE",
    "reference_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/liveness-reference.jpg",
    "warnings": [
      {
        "risk": "LIVENESS_FAILED",
        "feature": "LIVENESS",
        "short_description": "Liveness detection failed",
        "long_description": "The liveness check did not pass the required threshold.",
        "log_type": "error"
      }
    ],
    "matches": []
  },
  "liveness_checks": [
    {
      "status": "Declined",
      "node_id": "feature_liveness",
      "score": 42,
      "method": "PASSIVE",
      "reference_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/liveness-reference.jpg",
      "warnings": [
        {
          "risk": "LIVENESS_FAILED",
          "feature": "LIVENESS",
          "short_description": "Liveness detection failed",
          "long_description": "The liveness check did not pass the required threshold.",
          "log_type": "error"
        }
      ],
      "matches": []
    }
  ],
  "face_match": {
    "status": "Declined",
    "node_id": "feature_face_match",
    "score": 38,
    "source_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
    "target_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
    "warnings": [
      {
        "risk": "FACE_MATCH_LOW_CONFIDENCE",
        "feature": "FACE_MATCH",
        "short_description": "Face match confidence below threshold",
        "long_description": "The selfie did not match the document portrait with sufficient confidence.",
        "log_type": "error"
      }
    ]
  },
  "face_matches": [
    {
      "status": "Declined",
      "node_id": "feature_face_match",
      "score": 38,
      "source_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/document-front.jpg",
      "target_image": "kyc/global_gueno_validation_kyc/org-uuid/entity-uuid/validation-uuid/selfie.jpg",
      "warnings": [
        {
          "risk": "FACE_MATCH_LOW_CONFIDENCE",
          "feature": "FACE_MATCH",
          "short_description": "Face match confidence below threshold",
          "long_description": "The selfie did not match the document portrait with sufficient confidence.",
          "log_type": "error"
        }
      ]
    }
  ]
}
```

### Verification results

Each feature block in `decision` includes a **`status`** (`Approved`, `Declined`, `In Review`, etc.), optional **`score`**, **`warnings`**, and media references:

| Feature key       | Array alias           | Typical fields                                                                                           |
| ----------------- | --------------------- | -------------------------------------------------------------------------------------------------------- |
| `id_verification` | `id_verifications[0]` | `document_type`, `document_number`, `front_image`, `back_image`, `portrait_image`, `warnings`, `matches` |
| `liveness`        | `liveness_checks[0]`  | `score`, `method`, `reference_image`, `video_url`, `warnings`, `matches`                                 |
| `face_match`      | `face_matches[0]`     | `score`, `source_image`, `target_image`, `warnings`                                                      |
| `aml_screening`   | `aml_screenings[0]`   | `status`, `warnings`                                                                                     |
| `ip_analysis`     | `ip_analyses[0]`      | `ip_address`, `country`, `is_vpn`, `warnings`                                                            |

Gu1 also exposes normalized fields in **`extractedData`**, **`verifiedFields`**, and top-level **`warnings`** (risk codes) for easier integration.

### Extracted Data

Use `extractedData` to update customer records with verified information:

```javascript theme={null}
const validation = await getValidation(validationId);

if (validation.status === 'approved' && validation.extractedData) {
  // Update customer record with verified data
  await updateCustomer(customerId, {
    firstName: validation.extractedData.firstName,
    lastName: validation.extractedData.lastName,
    dateOfBirth: validation.extractedData.dateOfBirth,
    nationality: validation.extractedData.nationality,
    documentType: validation.extractedData.documentType,
    documentNumber: validation.extractedData.documentNumber,
    isVerified: true,
    verifiedAt: validation.verifiedAt
  });
}
```

## List All Validations for Entity

Get the complete verification history for an entity:

### Endpoint

```
GET https://api.gu1.ai/api/kyc/entities/{entityId}/validations
```

### Response

```json theme={null}
{
  "validations": [
    {
      "id": "validation_1",
      "status": "approved",
      
      "isCurrent": true,
      "createdAt": "2025-01-15T10:30:00Z",
      "verifiedAt": "2025-01-15T11:00:00Z"
    },
    {
      "id": "validation_2",
      "status": "abandoned",
      
      "isCurrent": false,
      "createdAt": "2025-01-10T09:00:00Z"
    }
  ],
  "total": 2,
  "page": 1,
  "limit": 100
}
```

## Sync Validation Status

If you suspect the validation status is out of sync with the identity provider, trigger a manual sync:

### Endpoint

```
POST https://api.gu1.ai/api/kyc/validations/{id}/sync
```

### Example

<CodeGroup>
  ```javascript Node.js theme={null}
  const validationId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(
    `https://api.gu1.ai/api/kyc/validations/${validationId}/sync`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ force: true })
    }
  );

  const updatedValidation = await response.json();
  console.log('Updated status:', updatedValidation.status);
  ```

  ```python Python theme={null}
  import requests

  validation_id = '550e8400-e29b-41d4-a716-446655440000'

  response = requests.post(
      f'https://api.gu1.ai/api/kyc/validations/{validation_id}/sync',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={'force': True}
  )

  updated_validation = response.json()
  print('Updated status:', updated_validation['status'])
  ```
</CodeGroup>

## Common Integration Patterns

### Pattern 1: Check Before Allowing Action

```javascript theme={null}
async function requireVerification(entityId) {
  const status = await fetch(
    `https://api.gu1.ai/api/kyc/entities/${entityId}/status`,
    {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }
  ).then(r => r.json());

  if (!status.isVerified) {
    throw new Error('Customer must complete identity verification');
  }

  if (status.needsReverification) {
    throw new Error('Customer identity verification expired. Please reverify.');
  }

  return true;
}
```

### Pattern 2: Conditional Features Based on Verification

```javascript theme={null}
async function getCustomerFeatures(entityId) {
  const status = await getKycStatus(entityId);

  return {
    basicFeatures: true,
    advancedFeatures: status.isVerified,
    highLimitTransactions: status.isVerified && !status.needsReverification,
    internationalTransfers: status.isVerified && hasAmlClearance(status)
  };
}
```

### Pattern 3: Periodic Re-verification Check

```javascript theme={null}
async function checkReverificationNeeded() {
  const stats = await fetch(
    'https://api.gu1.ai/api/kyc/stats',
    {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }
  ).then(r => r.json());

  // Find entities needing reverification
  const validations = await fetch(
    'https://api.gu1.ai/api/kyc/validations?status=approved',
    {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }
  ).then(r => r.json());

  for (const validation of validations.validations) {
    const status = await getEntityKycStatus(validation.entityId);

    if (status.needsReverification) {
      await notifyCustomerReverification(validation.entityId);
    }
  }
}

// Run daily
setInterval(checkReverificationNeeded, 24 * 60 * 60 * 1000);
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use Webhooks, Not Polling">
    Instead of repeatedly checking validation status, use [webhooks](/en/use-cases/kyc/webhook-integration) to receive real-time notifications. This is more efficient and provides better user experience.
  </Accordion>

  <Accordion title="Cache Verification Status">
    Store the verification status in your database and update it via webhooks. Don't query the API on every request.

    ```javascript theme={null}
    // Good: Cache in your database
    const customer = await db.getCustomer(customerId);
    if (customer.isVerified) {
      // Allow action
    }

    // Bad: Query API every time
    const status = await api.getKycStatus(entityId);
    if (status.isVerified) {
      // Allow action
    }
    ```
  </Accordion>

  <Accordion title="Handle Expired Verifications">
    Verifications may expire after a certain period (typically 1 year). Check `needsReverification` and prompt customers to reverify when necessary.
  </Accordion>

  <Accordion title="Store Validation IDs">
    Always store the validation ID in your database linked to the customer. This allows you to audit verification history and retrieve detailed results later.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Create KYC Validation" icon="play" href="/en/use-cases/kyc/create-validation">
    Start a new verification session
  </Card>

  <Card title="Webhook Integration" icon="webhook" href="/en/use-cases/kyc/webhook-integration">
    Get real-time notifications
  </Card>
</CardGroup>
