Sync KYC Validation
curl --request POST \
--url http://api.gu1.ai/api/kyc/validations/{id}/sync \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"force": true
}'import requests
url = "http://api.gu1.ai/api/kyc/validations/{id}/sync"
payload = { "force": True }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({force: true})
};
fetch('http://api.gu1.ai/api/kyc/validations/{id}/sync', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/api/kyc/validations/{id}/sync",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'force' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/api/kyc/validations/{id}/sync"
payload := strings.NewReader("{\n \"force\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/api/kyc/validations/{id}/sync")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"force\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/api/kyc/validations/{id}/sync")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"force\": true\n}"
response = http.request(request)
puts response.read_bodySession-based validation
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.
POST
/
api
/
kyc
/
validations
/
{id}
/
sync
Sync KYC Validation
curl --request POST \
--url http://api.gu1.ai/api/kyc/validations/{id}/sync \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"force": true
}'import requests
url = "http://api.gu1.ai/api/kyc/validations/{id}/sync"
payload = { "force": True }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({force: true})
};
fetch('http://api.gu1.ai/api/kyc/validations/{id}/sync', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/api/kyc/validations/{id}/sync",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'force' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/api/kyc/validations/{id}/sync"
payload := strings.NewReader("{\n \"force\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/api/kyc/validations/{id}/sync")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"force\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/api/kyc/validations/{id}/sync")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"force\": true\n}"
response = http.request(request)
puts response.read_bodyOverview
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
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.
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
string
required
The validation ID to synchronize
Headers
{
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
Body Parameters
boolean
Force synchronization even if recently synced (optional)Type:
boolean (default: false)Example: trueResponse
Success Response (200 OK)
Returns the updated validation object with latest data from the provider:{
"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
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);
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 -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
}'
Error Responses
Validation Not Found (404)
{
"error": "NOT_FOUND",
"message": "Validation not found"
}
No Session ID (400)
Validation has no provider session to sync:{
"error": "NO_SESSION_ID",
"message": "Validation has no session ID"
}
Provider Integration Not Configured (400)
{
"error": "INTEGRATION_NOT_CONFIGURED",
"message": "Integration not configured for organization: kyc_provider_code"
}
Important Notes
Automatic Sync
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.
Manual Decisions Are Protected
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.
Image URL Refresh
Image URL Refresh
Provider image URLs (document photos, selfies) expire after ~4 hours. Syncing fetches fresh URLs so you can view documents again.
Status Updates
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).
Credit Charging
Credit Charging
Syncing does NOT charge credits. Credits are only charged when a validation reaches a final state (approved/rejected) for the first time.
Use Cases
1. Refresh Expired Images
// 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
// 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
// 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
Approve Validation
Manually approve a validation
Reject Validation
Manually reject a validation
Check Verification Status
Query validation results
Cancel Validation
Cancel a pending validation
Was this page helpful?