Skip to main content
This guide covers how to verify business documents using the Parcha API. We’ll use incorporation document verification as our canonical example to demonstrate the three main approaches.

Choosing the Right Approach

Parcha offers three ways to verify documents, each optimized for different use cases:

Quick Comparison

ApproachEndpointSpeedUse Case
1. Full Agent JobstartKYBAgentJobVariesDocument verification as part of comprehensive KYB review with multiple checks
2. PrevalidationrunCheckFastQuick document type validation before full review
3. Full VerificationrunCheckThoroughComplete verification with visual analysis and fraud detection

Incorporation Document Example

We’ll demonstrate all three approaches using incorporation document verification. The same patterns apply to other document types (proof of address, EIN documents, etc.).

Sample Business Data

business_data = {
    "registered_business_name": "Example Business Inc.",
    "incorporation_date": "2023-01-01",
    "address_of_incorporation": {
        "street_1": "123 Main St",
        "city": "Wilmington",
        "state": "DE",
        "country_code": "US",
        "postal_code": "19801"
    }
}

Approach 1: Full Agent Job

Best for: Comprehensive compliance reviews

Use Agent Jobs when you need to run multiple checks together as part of a unified compliance workflow with custom pass/fail criteria.
When to use:
  • Running a full KYB review with multiple checks (web presence + sanctions + document verification)
  • You have an agent configured with specific pass/fail logic
  • You need unified case view and risk scoring across all checks
How it works:
curl -X POST 'https://api.parcha.ai/api/v1/startKYBAgentJob' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
  "agent_key": "your-kyb-agent-key",
  "kyb_schema": {
    "id": "case-001",
    "self_attested_data": {
      "registered_business_name": "Example Business Inc.",
      "website": "https://example.com",
      "incorporation_date": "2023-01-01",
      "address_of_incorporation": {
        "street_1": "123 Main St",
        "city": "Wilmington",
        "state": "DE",
        "country_code": "US",
        "postal_code": "19801"
      },
      "incorporation_documents": [
        {
          "file_name": "certificate_of_incorporation.pdf",
          "b64_document": "BASE64_ENCODED_DOCUMENT"
        }
      ]
    }
  },
  "webhook_url": "https://your-webhook.com/callback"
}'
Agent configuration matters: Your agent key determines which checks run and the pass/fail criteria. Work with Parcha to configure agents that match your compliance policies.

Approach 2: Prevalidation (Quick Check)

Best for: Real-time document upload validation

Use Prevalidation for fast document type checking without running full verification. Perfect for inline validation during user uploads.
When to use:
  • Real-time document upload flows where users expect quick feedback
  • Pre-screening documents before committing to full verification
  • Validating document type before user submits their application
How it works: Set all verification flags to false to skip visual verification and fraud checks. The system will only validate that the document is a valid type. Use a webhook to receive the result quickly.
curl -X POST 'https://api.parcha.ai/api/v1/runCheck' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
  "agent_key": "your-agent-key",
  "check_id": "kyb.incorporation_document_verification",
  "kyb_schema": {
    "id": "case-001",
    "self_attested_data": {
      "registered_business_name": "Example Business Inc.",
      "incorporation_date": "2023-01-01",
      "incorporation_documents": [
        {
          "file_name": "certificate_of_incorporation.pdf",
          "b64_document": "BASE64_ENCODED_DOCUMENT"
        }
      ]
    }
  },
  "check_args": {
    "enable_visual_verification": false,
    "enable_fraud_check": false,
    "verify_incorporation_date": false,
    "verify_registration_number": false,
    "verify_address": false,
    "verify_no_high_risk_fraud": false
  },
  "webhook_url": "https://your-webhook.com/prevalidation-callback"
}'
Webhook or Poll? Provide a webhook_url (recommended) to receive results automatically as soon as prevalidation completes, or poll the /getJobById endpoint if webhooks aren’t feasible for your setup.

Approach 3: Full Verification

Best for: Thorough document analysis

Use Full Verification for complete document analysis including visual verification, fraud detection, and data extraction.
When to use:
  • Final verification before approving a business application
  • When you need visual element analysis (seals, signatures)
  • When fraud detection is required
  • When you need to verify specific data fields (dates, addresses)
How it works: Enable the verification options you need. Each adds additional analysis capabilities:
curl -X POST 'https://api.parcha.ai/api/v1/runCheck' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
  "agent_key": "your-agent-key",
  "check_id": "kyb.incorporation_document_verification",
  "kyb_schema": {
    "id": "case-001",
    "self_attested_data": {
      "registered_business_name": "Example Business Inc.",
      "incorporation_date": "2023-01-01",
      "address_of_incorporation": {
        "street_1": "123 Main St",
        "city": "Wilmington",
        "state": "DE",
        "country_code": "US",
        "postal_code": "19801"
      },
      "incorporation_documents": [
        {
          "file_name": "certificate_of_incorporation.pdf",
          "b64_document": "BASE64_ENCODED_DOCUMENT"
        }
      ]
    }
  },
  "check_args": {
    "enable_visual_verification": true,
    "enable_fraud_check": true,
    "verify_incorporation_date": true,
    "verify_registration_number": true,
    "verify_address": true,
    "verify_no_high_risk_fraud": true
  },
  "webhook_url": "https://your-webhook.com/callback"
}'

Verification Options Reference

Latency vs. Thoroughness Trade-off: Each verification option adds scrutiny but increases processing time. Choose based on your risk tolerance and UX requirements.
OptionDefaultDescriptionLatency Impact
enable_visual_verificationtrueUses vision model to analyze seals, signatures, visual elements+15-30 seconds
enable_fraud_checkfalseSophisticated fraud and tampering analysis on document metadata+1-2 minutes
verify_incorporation_datetrueFail if incorporation date has significant discrepanciesMinimal
verify_registration_numberfalseFail if registration number has significant discrepanciesMinimal
verify_addressfalseFail if address has significant discrepanciesMinimal
verify_no_high_risk_fraudfalseFail if HIGH_RISK fraud indicators detectedMinimal
By default (without explicit options), the system performs OCR-based analysis using LLMs to extract and analyze text from the document.

Polling for Results

After starting a job, poll for completion:
curl 'https://api.parcha.ai/api/v1/getJobById?job_id=YOUR_JOB_ID&include_check_results=true' \
-H 'Authorization: Bearer YOUR_API_KEY'

Using Webhooks

Instead of polling, configure a webhook to receive results automatically:
const express = require('express');
const app = express();
app.use(express.json());

app.post('/callback', (req, res) => {
  const jobData = req.body;
  
  if (jobData.status === 'complete') {
    const incorpCheck = jobData.check_results.find(
      check => check.command_id === 'kyb.incorporation_document_verification'
    );
    
    if (incorpCheck) {
      if (incorpCheck.passed) {
        console.log('✓ Document verified');
        console.log('Company:', incorpCheck.payload.company_name);
      } else {
        console.log('✗ Verification failed:', incorpCheck.answer);
      }
    }
  }
  
  res.sendStatus(200);
});

app.listen(3000);
For more details, see the Webhooks documentation.

Decision Guide

Use: Approach 1 - Full Agent Job (startKYBAgentJob)Include documents in your kyb_schema and let the agent handle document verification alongside web presence, sanctions screening, and other checks. You get unified pass/fail logic across all verification types.
Use: Approach 2 - Prevalidation (runCheck with flags disabled)Set all verification flags to false for fast document type validation. Show users immediate feedback on whether their document is the right type before they submit.
Use: Approach 3 - Full Verification (runCheck with flags enabled)Enable enable_visual_verification and enable_fraud_check for comprehensive analysis. Use this for final verification before approving applications.
Combine Approaches 2 and 3
  1. Run prevalidation during upload for quick feedback
  2. Run full verification when user submits their complete application
This gives users fast feedback while ensuring thorough verification before approval.

Document Upload Options

When submitting documents for verification, you have two options for how to include the document data:

Option A: Inline Base64 (Single Request)

Include the base64-encoded document directly in your verification request. This is the simplest approach for most use cases. How it works: When to use:
  • Most common approach
  • Documents under 10MB
  • When you want simplicity
import base64

with open('document.pdf', 'rb') as file:
    b64_document = base64.b64encode(file.read()).decode('utf-8')

data = {
    "agent_key": "your-agent-key",
    "check_id": "kyb.incorporation_document_verification",
    "kyb_schema": {
        "id": "case-001",
        "self_attested_data": {
            "registered_business_name": "Example Business Inc.",
            "incorporation_documents": [
                {
                    "file_name": "certificate.pdf",
                    "b64_document": b64_document  # Document included inline
                }
            ]
        }
    },
    "check_args": {...}
}

Option B: Pre-upload (Two-Step)

Upload the document first to get a URL, then reference that URL in your verification request. Useful when you need to manage documents separately. How it works: When to use:
  • Large documents
  • When you need to reuse the same document across multiple checks
  • When you want to manage document storage separately
Step 1: Upload the document
curl -X POST 'https://api.parcha.ai/api/v1/uploadB64Document' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
  "b64_document": "BASE64_ENCODED_CONTENT",
  "document_name": "certificate_of_incorporation.pdf"
}'
Step 2: Run verification with the URL
data = {
    "agent_key": "your-agent-key",
    "check_id": "kyb.incorporation_document_verification",
    "kyb_schema": {
        "id": "case-001",
        "self_attested_data": {
            "registered_business_name": "Example Business Inc.",
            "incorporation_documents": [
                {
                    "file_name": "certificate_of_incorporation.pdf",
                    "url": document_url  # Reference the uploaded document
                }
            ]
        }
    },
    "check_args": {...}
}

response = requests.post(
    'https://api.parcha.ai/api/v1/runCheck',
    headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'},
    json=data
)

Comparison

OptionRequestsBest For
A: Inline Base641Simple integration, most use cases
B: Pre-upload2Large files, document reuse, separate storage management

Other Document Types

The same three approaches work for all document verification checks:
Document TypeCheck IDDocument Field
Incorporation Certificatekyb.incorporation_document_verificationincorporation_documents
Proof of Addresskyb.proof_of_address_verificationproof_of_address_documents
EIN Documentkyb.ein_document_verificationein_documents
Business Ownershipkyb.business_ownership_document_verificationbusiness_ownership_documents
Source of Fundskyb.source_of_funds_document_verificationsource_of_funds_documents
Simply swap the check_id and document field in your requests.