> ## 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.

# Sync KYC Validation

> Manually synchronize KYC validation data with the provider — in the gu1 KYC API for identity verification flows, with examples for sync validation use cases.

## Overview

This endpoint allows you to manually synchronize a KYC validation with the verification provider to get the latest status and decision data. When you sync:

* **Fetches latest data** from the KYC provider in real-time
* **Refreshes expired image URLs** (provider URLs expire after \~4 hours)
* **Updates validation status** if the provider has made a decision
* **Preserves manual decisions** - won't overwrite manually approved/rejected/cancelled validations
* **Returns updated verification data** including documents, biometrics, and risk assessment

<Info>
  Syncing is useful when you need fresh data immediately without waiting for webhooks, or when image URLs have expired and you need to view verification documents.
</Info>

## When to Use This

* **Check latest status**: Get real-time status updates from the provider
* **Refresh expired images**: Image URLs from the provider expire after 4 hours
* **Force update**: Manually trigger a sync if webhook delivery failed
* **Debug verification**: Review the most recent verification data and decisions
* **Before manual decision**: Sync before approving/rejecting to see latest provider data

## Request

### Endpoint

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

### Path Parameters

<ParamField path="id" type="string" required>
  The validation ID to synchronize
</ParamField>

### Headers

```json theme={null}
{
  "Authorization": "Bearer YOUR_API_KEY",
  "Content-Type": "application/json"
}
```

### Body Parameters

<ParamField body="force" type="boolean">
  Force synchronization even if recently synced (optional)

  **Type**: `boolean` (default: `false`)

  **Example**: `true`
</ParamField>

## Response

### Success Response (200 OK)

Returns the updated validation object with latest data from the provider:

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "entityId": "123e4567-e89b-12d3-a456-426614174000",
  "organizationId": "org_abc123",
  "validationSessionId": "session_xyz789",
  "status": "approved",
  "provider": "KYC Provider",
  "providerSessionUrl": "https://verify.example.com/session_xyz789",
  "decision": {
      "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": []
        }
      ]
    },
  "extractedData": {
    "firstName": "John",
    "lastName": "Doe",
    "dateOfBirth": "1990-05-15",
    "nationality": "US",
    "documentNumber": "AB123456",
    "documentType": "Identity Card"
  },
  "documentsVerified": [
    {
      "type": "Identity Card",
      "verified": true,
      "verifiedAt": "2025-01-27T10:30:00Z"
    }
  ],
  "biometricResult": {
    "livenessScore": 0.98,
    "faceMatchScore": 0.95,
    "passed": true,
    "timestamp": "2025-01-27T10:30:00Z"
  },
  "riskAssessment": {
    "riskLevel": "low"
  },
  "verifiedFields": ["firstName", "lastName", "dateOfBirth", "nationality", "documentNumber"],
  "warnings": [],
  "isCurrent": true,
  "verifiedAt": "2025-01-27T10:30:00Z",
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-27T10:30:00Z"
}
```

## Example Request

<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: false
      })
    }
  );

  const synced = await response.json();
  console.log('Validation synced:', synced.status);
  console.log('Updated at:', synced.updatedAt);
  ```

  ```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': False
      }
  )

  synced = response.json()
  print('Validation synced:', synced['status'])
  print('Updated at:', synced['updatedAt'])
  ```

  ```curl cURL theme={null}
  curl -X POST https://api.gu1.ai/api/kyc/validations/550e8400-e29b-41d4-a716-446655440000/sync \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "force": false
    }'
  ```
</CodeGroup>

## Error Responses

### Validation Not Found (404)

```json theme={null}
{
  "error": "NOT_FOUND",
  "message": "Validation not found"
}
```

### No Session ID (400)

Validation has no provider session to sync:

```json theme={null}
{
  "error": "NO_SESSION_ID",
  "message": "Validation has no session ID"
}
```

### Provider Integration Not Configured (400)

```json theme={null}
{
  "error": "INTEGRATION_NOT_CONFIGURED",
  "message": "Integration not configured for organization: kyc_provider_code"
}
```

## Important Notes

<AccordionGroup>
  <Accordion title="Automatic Sync">
    Validations are automatically synced when fetched via GET if images are older than 3.5 hours. Manual sync is useful when you need immediate updates.
  </Accordion>

  <Accordion title="Manual Decisions Are Protected">
    If a validation was manually approved, rejected, or cancelled, syncing will NOT overwrite that decision. Manual decisions are preserved to maintain audit trails.
  </Accordion>

  <Accordion title="Image URL Refresh">
    Provider image URLs (document photos, selfies) expire after \~4 hours. Syncing fetches fresh URLs so you can view documents again.
  </Accordion>

  <Accordion title="Status Updates">
    If the provider has made a decision since the last sync, the validation status will be updated automatically (unless it has a manual status).
  </Accordion>

  <Accordion title="Credit Charging">
    Syncing does NOT charge credits. Credits are only charged when a validation reaches a final state (approved/rejected) for the first time.
  </Accordion>
</AccordionGroup>

## Use Cases

### 1. Refresh Expired Images

```javascript theme={null}
// User wants to review documents but images expired
const validation = await fetch(
  `https://api.gu1.ai/api/kyc/validations/${validationId}/sync`,
  {
    method: 'POST',
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
  }
);

const data = await validation.json();
// Fresh image URLs available in data.decision.id_verification.front_image
```

### 2. Check Status Before Manual Decision

```javascript theme={null}
// Sync before making a manual approval decision
const synced = await fetch(
  `https://api.gu1.ai/api/kyc/validations/${validationId}/sync`,
  { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);

const data = await synced.json();

// Review latest provider data
console.log('Provider status:', data.status);
console.log('Risk level:', data.riskAssessment?.riskLevel);
console.log('Warnings:', data.warnings);

// Then approve if satisfied
if (data.status === 'in_progress' && data.warnings.length === 0) {
  await approveValidation(validationId, 'All checks passed');
}
```

### 3. Force Update After Webhook Failure

```javascript theme={null}
// If you suspect webhooks didn't deliver
const validations = await getValidationsWithStatus('in_progress');

for (const validation of validations) {
  // Sync each to get latest status
  await fetch(
    `https://api.gu1.ai/api/kyc/validations/${validation.id}/sync`,
    {
      method: 'POST',
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
      body: JSON.stringify({ force: true })
    }
  );
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Approve Validation" icon="check" href="/en/use-cases/kyc/approve-validation">
    Manually approve a validation
  </Card>

  <Card title="Reject Validation" icon="xmark" href="/en/use-cases/kyc/reject-validation">
    Manually reject a validation
  </Card>

  <Card title="Check Verification Status" icon="magnifying-glass" href="/en/use-cases/kyc/check-status">
    Query validation results
  </Card>

  <Card title="Cancel Validation" icon="ban" href="/en/use-cases/kyc/cancel-validation">
    Cancel a pending validation
  </Card>
</CardGroup>
