# Individual Entity Verification In-Built Automation

Automate your KYC compliance workflows with BNDRY's Individual Entity Verification automation. Create configurable workflows that collect customer data, verify identities, screen for PEP and sanctions, and create structured entities in your Risk Hub—all without manual intervention.

## Overview

The Individual Entity Verification automation enables you to:

- **Verify customer identities** through integrated IDV providers
- **Receive real-time notifications** when onboarding completes


## How It Works

The Individual Entity Verification automation is designed to conduct ID Validation on existing entities in your Risk Hub. The process involves:

1. **Your business** initiates verification by running a pre-configured job for each customer
2. **Your customer** is redirected to BNDRY's hosted data collection forms to provide their information
3. **BNDRY's platform** handles the complete verification workflow, performing identity verification and compliance screening
4. **Your business** receives webhook notifications when the process completes, enabling you to utilise the result in real time
5. **Your customer** is redirected seamlessly back into your workflow to continue their journey


```mermaid
sequenceDiagram
    participant B as Your Business
    participant C as Customer / Entity
    participant BNDRY as BNDRY Platform
    participant IDV as Identity Verification

    B->>BNDRY: Run verification job
    BNDRY->>IDV: Initiate identity verification
    BNDRY-->>B: Return redirect URI
    B->>C: Redirect to IDV
    IDV-->>BNDRY: Verification complete
    BNDRY->>B: Webhook notification
```

## Getting Started

### Quick Start Checklist

Before you begin implementing the individual onboarding automation:

Set up API credentials
Contact the [BNDRY team](https://bndry.net/contact) to obtain your OAuth2 client credentials

Configure webhook endpoint
Set up an HTTPS endpoint to receive progress notifications

Work with BNDRY
We'll work with you to ensure everything is set up correctly.

Test the integration
Use the [mock server](https://docs.bndry.net/_mock/apis/openapi/) to verify your implementation

### What You Do Once Live

Once configured, you'll primarily use the `RunIndividualEntityVerificationJob` API to execute the verification automation and monitor progress through the long-running operations API.

For testing and development, you can use the [mock server](https://docs.bndry.net/_mock/apis/openapi/) to experiment with the API without affecting production data.

## Core Concepts

### Verification Job API Resource

The `RunIndividualEntityVerificationJob` API resource represents an automation for verifying individual entities through data capture, entity creation, and verification workflows.

Why 'Job' in the API?
You'll notice we use "automation" when describing the product capability, but "job" appears in API resource names like `RunIndividualEntityVerificationJob`. This follows Google's API design standards for long-running operations ([AIP-152](https://google.aip.dev/152)), ensuring reliable and predictable behavior for asynchronous workflows. The terms refer to the same functionality - we use "automation" from a product perspective and "job" in the API contract.

The resource contains:

- **name** - Resource identifier
- **entity_resource_name** - Target entity in your Risk Hub
- **webhook_uri** - Webhook target URI for notifications
- **create_time** and **update_time** - Resource timestamps


## Using the API

### Authentication

Before making API calls, you'll need to authenticate using OAuth 2.0 Client Credentials flow. See the [Authentication guide](/docs/get-started-with-the-api/authentication) for complete details on obtaining and using access tokens.

### Running the Onboarding Automation

Once your automation is configured, you can run it for each customer:

This returns a long-running operation with the redirect URI in the metadata:

```json
{
  "name": "operations/op_abc123",
  "metadata": {
    "redirect_uri": "https://forms.bndry.net/verifications/{your_verification_job_id}/op_abc123"
  },
  "done": false
}
```

### Hosted or embedded experience?

You can choose to redirect your customers to BNDRY's hosted data collection forms using the provided [`redirect_uri`](/apis/openapi/individual-entity-verification/individualentityverificationjobservice_runindividualentityverificationjob#individual-entity-verification/individualentityverificationjobservice_runindividualentityverificationjob/t=request&path=redirecturi), or embed the forms directly within your application using an iframe. For embedding, check out our dedicated guide to [Embedding BNDRY Forms](/docs/guides/embedding-bndry-forms).

### Monitoring Operation Progress

You can monitor the progress of the onboarding operation by polling the operation status:

Webhook Best Practice
Use webhooks to handle completion events - they provide richer context about the onboarding results and are the recommended approach rather than polling the operation status.

### Error Handling

The onboarding process can fail for various reasons (form abandonment, verification failures, etc.). Failed operations will have `done: true` with error details in the `error` field. See the [Errors guide](/docs/get-started-with-the-api/errors) for complete error handling patterns.

## API Reference

### Primary APIs

Once your onboarding automation is configured, you'll primarily use these APIs:

RunIndividualEntityVerificationJob
Execute an onboarding workflow for a customer

GetOperation
Monitor the progress of a running onboarding automation

GetIndividualEntityVerificationJob
Retrieve configuration details of your onboarding automation

For complete API documentation including request/response schemas, see the [API Reference](/apis/openapi).

## Webhook Configuration

### How BNDRY Webhooks Work

BNDRY webhooks follow the [CloudEvents specification](https://cloudevents.io/) and use the [`dataref` extension](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/extensions/dataref.md), also known as the "Claim Check Pattern". Instead of including sensitive event data directly in webhook payloads, BNDRY provides a reference URL where you can securely fetch the actual event data.

This two-step process works as follows:

1. **Receive webhook notification**: You get a "thin" CloudEvent containing only metadata and a `dataref` URL
2. **Fetch complete event data**: Make an authenticated API call using the `dataref` to retrieve the full event details


This approach provides several key benefits:

- **Security**: Prevents accidental exposure of personally identifiable information (PII) in webhook payloads
- **Access control**: BNDRY can verify that the webhook receiver has proper permissions before releasing sensitive data
- **Reduced payload size**: Webhook payloads remain lightweight regardless of the underlying event data size
- **Audit trail**: All access to sensitive event data can be logged and monitored


### Events delivered by this automation

| Event | Event Type & Description |
|  --- | --- |
| **Verification Processing Started**
 | `bndry.risk.entities.v1alpha.IdentityVerificationProcessingStarted`
Delivered when the automation user has completed all required input, and verification processing has begun. At this point, the UI component of the automation attempts to redirect to the provided [`redirect_uri`](/apis/openapi/individual-entity-verification/individualentityverificationjobservice_runindividualentityverificationjob#individual-entity-verification/individualentityverificationjobservice_runindividualentityverificationjob/t=request&path=redirecturi)
 |
| **Verification Complete**
 | `bndry.risk.entities.v1alpha.IndividualEntityVerified`
Delivered when BNDRY has processed the results of the verification
 |


### Authentication

BNDRY webhooks use a combination of signing verification and OAuth2.0 Bearer token authentication:

```json
{
  "url": "https://example.com/webhook",
  "signing_secret": "your-signing-secret",
  "authentication": {
    "type": "bearer",
    "value": "your-bearer-token"
  }
}
```

### Webhook Payload Format

When an individual entity's identity verification completes, you'll receive a CloudEvents-formatted webhook payload:

```json
{
  "specversion": "1.0",
  "type": "bndry.api.risk.entities.v1alpha.IdentityVerificationCompleted",
  "source": "api.bndry.net/Entity/entities/entity-abc123",
  "id": "event-12345-67890",
  "datacontenttype": "application/json",
  "dataref": "/v1alpha/entities/entity-abc123/events/event-12345-67890",
  "time": "2024-01-15T10:30:00Z"
}
```

### Retrieving Event Data

To get the complete event details, make an authenticated request to the URL provided in the `dataref` field:

```http
GET /v1alpha/entities/entity-abc123/events/event-12345-67890
Authorization: Bearer your-api-token
```

### Complete Webhook Handler Example

Here's a complete webhook handler implementation:

```javascript
const crypto = require("crypto");

app.post("/webhooks/onboarding-complete", async (req, res) => {
  try {
    // Verify webhook signature
    const signature = req.headers["x-bndry-signature"];
    const expectedSignature = crypto
      .createHmac("sha256", process.env.BNDRY_SIGNING_SECRET)
      .update(JSON.stringify(req.body))
      .digest("hex");

    if (signature !== `sha256=${expectedSignature}`) {
      return res.status(401).send("Invalid signature");
    }

    const cloudEvent = req.body;

    // Fetch the complete event data
    const eventResponse = await fetch(
      `https://api.bndry.app${cloudEvent.dataref}`,
      {
        headers: {
          Authorization: `Bearer ${process.env.BNDRY_API_TOKEN}`,
          "Content-Type": "application/json",
        },
      }
    );

    const eventData = await eventResponse.json();

    // Process the onboarding completion
    if (eventData.success && eventData.entity_created) {
      // Update your customer records
      await updateCustomerRecord(eventData.entity_annotations.external_id, {
        bndryEntityId: eventData.related_ref,
        onboardingStatus: "completed",
        identityVerified: eventData.identity_verification_status === "passed",
        sanctionsCleared: eventData.sanctions_screening_status === "clear",
      });

      // Trigger downstream processes
      await activateCustomerAccount(eventData.entity_annotations.external_id);
    }

    res.status(200).send("OK");
  } catch (error) {
    console.error("Webhook processing error:", error);
    res.status(500).send("Internal Server Error");
  }
});
```

### Webhook URL Requirements

Webhook URLs must meet these security requirements:

- **HTTPS only** - HTTP URLs are not permitted
- **Valid hostname** - Must have a proper host component
- **No private/internal IPs** - Cannot target private, loopback, link-local, or multicast IP addresses
- **Domain restrictions** - Cannot target blocked domains including:
  - bndry.app and bndry.net (prevents self-targeting)
  - Cloud metadata services (metadata.google.internal, metadata.google.com, metadata.azure.com)


During webhook execution, DNS resolution is validated to ensure hostnames don't resolve to blocked IP addresses.

## Support

For questions about implementing the Individual Entity Verification automation, contact the BNDRY team during your platform onboarding process.

*Ready to embed ID verification into your processes? [Get started with BNDRY's Early Access Program](https://bndry.net/early-access)*