Skip to main content
POST
/
kyc
/
jobs
Batch Jobs
curl --request POST \
  --url https://api.example.com/kyc/jobs
Create and manage batch KYC validation jobs for processing multiple entities efficiently. Batch jobs allow you to submit large numbers of entities for validation and track their progress asynchronously.

Endpoints

MethodEndpointDescription
POST/kyc/jobsCreate a new batch job
GET/kyc/jobs/{job_id}Get job status and results

Authentication

Requires kyc:create permission for creating jobs and kyc:read permission for retrieving job status. Include your Bearer token in the Authorization header.

Create Batch Job

Submit multiple entities for KYC validation in a single batch job.

Endpoint

POST /kyc/jobs

Request Body Parameters

Request Example

curl -X POST https://stg.kyc.legaltalent.ai/kyc/jobs \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entities": [
      {
        "entity_id": "e1",
        "subject": {
          "full_name": "John Doe",
          "nationality": "US",
          "birth_date": "1985-03-15"
        },
        "lists": ["ofac", "un"],
        "search_type": "composite"
      },
      {
        "entity_id": "e2",
        "subject": {
          "full_name": "Jane Smith",
          "document_id": "12345678",
          "document_type": "CI",
          "nationality": "UY"
        },
        "lists": ["senaclaft_uy"]
      }
    ]
  }'

Response Format

{
  "status": "success",
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "total_entities": 2,
  "status": "processing",
  "created_at": "2024-11-22T10:30:00Z",
  "estimated_completion": "2024-11-22T10:35:00Z"
}

Response Fields

FieldTypeDescription
statusstringAlways "success" when job is created
job_idstringUnique identifier for the batch job
total_entitiesintegerNumber of entities in the batch
statusstringJob status: "processing", "completed", "failed"
created_atstringISO 8601 timestamp when job was created
estimated_completionstringEstimated completion time (ISO 8601)

Get Job Status

Retrieve the status and results of a batch job.

Endpoint

GET /kyc/jobs/{job_id}

Path Parameters

Request Example

curl https://stg.kyc.legaltalent.ai/kyc/jobs/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_TOKEN"

Response Format - Processing

{
  "status": "success",
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "job_status": "processing",
  "total_entities": 2,
  "processed_entities": 1,
  "completed_entities": 1,
  "failed_entities": 0,
  "matches_found": 0,
  "created_at": "2024-11-22T10:30:00Z",
  "updated_at": "2024-11-22T10:32:00Z",
  "estimated_completion": "2024-11-22T10:35:00Z"
}

Response Format - Completed

{
  "status": "success",
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "job_status": "completed",
  "total_entities": 2,
  "processed_entities": 2,
  "completed_entities": 2,
  "failed_entities": 0,
  "matches_found": 1,
  "created_at": "2024-11-22T10:30:00Z",
  "completed_at": "2024-11-22T10:34:00Z",
  "results": [
    {
      "entity_id": "e1",
      "status": "completed",
      "is_match": false,
      "match_count": 0,
      "matches": []
    },
    {
      "entity_id": "e2",
      "status": "completed",
      "is_match": true,
      "match_count": 1,
      "matches": [
        {
          "entity_id": "12345",
          "name": "Jane Smith",
          "confidence_score": 0.95,
          "match_type": "composite",
          "source_list": "senaclaft_uy",
          "programs": ["PEP"]
        }
      ]
    }
  ]
}

Response Fields

FieldTypeDescription
statusstringResponse status: "success"
job_idstringUnique identifier for the batch job
job_statusstringJob status: "processing", "completed", "failed"
total_entitiesintegerTotal number of entities in the batch
processed_entitiesintegerNumber of entities processed so far
completed_entitiesintegerNumber of entities successfully completed
failed_entitiesintegerNumber of entities that failed processing
matches_foundintegerTotal number of matches found across all entities
created_atstringISO 8601 timestamp when job was created
completed_atstringISO 8601 timestamp when job completed (if completed)
updated_atstringISO 8601 timestamp of last update
estimated_completionstringEstimated completion time (if processing)
resultsarrayArray of entity results (only present when completed)

Entity Result Object

FieldTypeDescription
entity_idstringEntity identifier (if provided)
statusstringEntity processing status
is_matchbooleanWhether any matches were found
match_countintegerNumber of matches found
matchesarrayArray of match objects (same format as single check)

Error Responses

400 Bad Request - Invalid Entities

{
  "error": "Invalid entities",
  "message": "Entity at index 0 must have a non-empty 'subject.full_name' field"
}

400 Bad Request - Too Many Entities

{
  "error": "Too many entities",
  "message": "Maximum 10,000 entities per job"
}

404 Not Found - Job Not Found

{
  "error": "Job not found",
  "message": "Job ID does not exist or belongs to a different tenant"
}

Status Codes

CodeDescription
200Success - Job created or retrieved
400Bad Request - Invalid parameters
401Unauthorized - Missing or invalid token
403Forbidden - Insufficient permissions
404Not Found - Job not found
500Internal Server Error

Usage Examples

Python Example

import requests
import time

token = "YOUR_TOKEN"

# Create batch job
response = requests.post(
    "https://stg.kyc.legaltalent.ai/kyc/jobs",
    headers={
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    },
    json={
        "entities": [
            {
                "entity_id": "e1",
                "subject": {
                    "full_name": "John Doe",
                    "nationality": "US"
                },
                "lists": ["ofac"]
            },
            {
                "entity_id": "e2",
                "subject": {
                    "full_name": "Jane Smith",
                    "nationality": "UY"
                },
                "lists": ["senaclaft_uy"]
            }
        ]
    }
)

if response.status_code == 200:
    job_data = response.json()
    job_id = job_data["job_id"]
    print(f"Job created: {job_id}")
    
    # Poll for completion
    while True:
        status_response = requests.get(
            f"https://stg.kyc.legaltalent.ai/kyc/jobs/{job_id}",
            headers={"Authorization": f"Bearer {token}"}
        )
        
        if status_response.status_code == 200:
            status_data = status_response.json()
            print(f"Status: {status_data['job_status']} - {status_data['processed_entities']}/{status_data['total_entities']}")
            
            if status_data['job_status'] == 'completed':
                print(f"Matches found: {status_data['matches_found']}")
                for result in status_data['results']:
                    if result['is_match']:
                        print(f"Entity {result['entity_id']}: {result['match_count']} matches")
                break
            elif status_data['job_status'] == 'failed':
                print("Job failed")
                break
        
        time.sleep(5)  # Poll every 5 seconds
else:
    print(f"Error: {response.json()}")

JavaScript Example

const token = "YOUR_TOKEN";

async function createBatchJob(entities) {
  // Create job
  const createResponse = await fetch(
    "https://stg.kyc.legaltalent.ai/kyc/jobs",
    {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ entities })
    }
  );
  
  const jobData = await createResponse.json();
  
  if (!createResponse.ok) {
    throw new Error(jobData.error);
  }
  
  const jobId = jobData.job_id;
  console.log(`Job created: ${jobId}`);
  
  // Poll for completion
  while (true) {
    const statusResponse = await fetch(
      `https://stg.kyc.legaltalent.ai/kyc/jobs/${jobId}`,
      {
        headers: {
          "Authorization": `Bearer ${token}`
        }
      }
    );
    
    const statusData = await statusResponse.json();
    console.log(`Status: ${statusData.job_status} - ${statusData.processed_entities}/${statusData.total_entities}`);
    
    if (statusData.job_status === 'completed') {
      console.log(`Matches found: ${statusData.matches_found}`);
      statusData.results.forEach(result => {
        if (result.is_match) {
          console.log(`Entity ${result.entity_id}: ${result.match_count} matches`);
        }
      });
      return statusData;
    } else if (statusData.job_status === 'failed') {
      throw new Error("Job failed");
    }
    
    // Wait 5 seconds before polling again
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}

Best Practices

  • Batch Size: Keep batches between 100-1,000 entities for optimal performance
  • Entity IDs: Always provide entity_id to track individual entities in results
  • Polling: Poll job status every 5-10 seconds (don’t poll too frequently)
  • Error Handling: Handle failed entities appropriately
  • Rate Limits: Be aware of API rate limits when creating multiple jobs

Performance

  • Processing Time: Approximately 1-2 seconds per entity
  • Maximum Entities: 10,000 entities per job
  • Chunking: Large batches are automatically chunked for processing
  • Concurrent Processing: Entities are processed in parallel for faster completion

Job Statuses

StatusDescription
processingJob is currently being processed
completedAll entities have been processed successfully
failedJob failed (check error details)

Integration Tips

  1. Async Processing: Batch jobs are processed asynchronously - don’t wait for completion
  2. Status Polling: Implement exponential backoff for status polling
  3. Result Storage: Store job results for audit and compliance purposes
  4. Error Recovery: Implement retry logic for failed entities