Skip to main content
GET
/
api
/
kyc
/
validations
/
{id}
Check Verification Status
curl --request GET \
  --url http://api.gu1.ai/api/kyc/validations/{id} \
  --header 'Authorization: Bearer <token>'
{
  "status": "<string>"
}

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
While you can poll this API, we strongly recommend using webhooks to receive real-time notifications when verification completes.

Get Validation by ID

Retrieve a specific validation using its ID:

Endpoint

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

Example

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

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

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

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

{
  "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

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');
}

Understanding Validation Results

Status Values

status
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

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. Older rows may still contain short-lived HTTPS URLs until synced. Approved example (complete):
{
  "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):
{
  "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 keyArray aliasTypical fields
id_verificationid_verifications[0]document_type, document_number, front_image, back_image, portrait_image, warnings, matches
livenessliveness_checks[0]score, method, reference_image, video_url, warnings, matches
face_matchface_matches[0]score, source_image, target_image, warnings
aml_screeningaml_screenings[0]status, warnings
ip_analysisip_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:
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

{
  "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

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

Common Integration Patterns

Pattern 1: Check Before Allowing Action

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

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

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

Instead of repeatedly checking validation status, use webhooks to receive real-time notifications. This is more efficient and provides better user experience.
Store the verification status in your database and update it via webhooks. Don’t query the API on every request.
// 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
}
Verifications may expire after a certain period (typically 1 year). Check needsReverification and prompt customers to reverify when necessary.
Always store the validation ID in your database linked to the customer. This allows you to audit verification history and retrieve detailed results later.

Next Steps

Create KYC Validation

Start a new verification session

Webhook Integration

Get real-time notifications