> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heliumid.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Recipe: Individual Verification Integration

> A practical end-to-end recipe for creating an individual verification, redirecting the user, and handling the final webhook outcome.

This recipe shows the simplest reliable individual-verification integration pattern.

## What you will build

1. Create a verification from your server
2. Store the returned `verificationId`
3. Redirect the user to the hosted link
4. Receive webhook updates
5. Mark the user as approved or rejected when a decision arrives

## Step 1: Create the verification

```bash theme={null}
curl -X POST "https://server.heliumid.io/api/v1/verifications" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "vendorData": "user_12345",
    "meta": {
      "applicationId": "app_67890"
    }
  }'
```

Store:

* `data.verificationId`
* `data.link`
* your own `vendorData`

## Step 2: Redirect the user

Send the user to `data.link` exactly as returned.

Do not rebuild the hosted URL yourself.

## Step 3: Listen for webhooks

At minimum, handle:

* `verification.successful`
* `verification.failed`

You can also listen for progress events like:

* `verification.started`
* `verification.processing_started`

## Step 4: Verify the signature

Validate:

* `Webhook-Timestamp`
* `Webhook-Signature`
* the raw request body

See [HMAC Authentication and Endpoint Security](/technical/hmac).

## Step 5: Update your own system

Recommended logic:

* if `event === "verification.successful"`, mark the user as verified
* if `event === "verification.failed"`, mark the user as rejected or request a new session

## Minimal Node.js handler example

```javascript theme={null}
app.post("/webhooks/helium", express.raw({ type: "*/*" }), (req, res) => {
  const rawBody = req.body.toString("utf8");
  const event = JSON.parse(rawBody);

  if (event.event === "verification.successful") {
    const { verificationId, vendorData } = event.data;
    // Mark the user as verified in your system
  }

  if (event.event === "verification.failed") {
    const { verificationId, vendorData, reason } = event.data;
    // Mark the user as rejected or request a retry
  }

  res.status(200).send("ok");
});
```

## Optional polling fallback

If you need a fallback path, you can fetch the current state with:

* `GET /v1/verifications`
* `GET /v1/verifications/{id}`

## Recommended stored fields

For each individual verification, store:

* `verificationId`
* `vendorData`
* current status
* latest webhook event
* raw webhook payload
* environment used

That gives you a clean audit trail and makes support much easier.
