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

# Integrate Vouch

> Let an end user grant your app access to an identity they already hold — publish a Vouch flow in EasyOnboard, launch it with the KYC widget, and exchange the share code for claims.

Vouch lets an end user grant your app access to an identity they already hold. You publish a Vouch flow in [EasyOnboard](/dashboard-guide/workflows/easyonboard), launch it with the KYC widget, and exchange the `shareCode` the widget returns for that user's claims.

There are two flow types:

| Flow | What the user grants | What you receive |
| - | - | - |
| **Verification** | The identity attributes you selected when you built the flow | Those attributes, under `claims` |
| **Authentication** | Basic profile info | `claims.basic_info` and `claims.bio_data` (email and name) |

<Warning>
  **The widget callback is not the identity.** Grant access only after your server exchanges the share code and the claims response is `approved`.
</Warning>

```mermaid theme={null}
sequenceDiagram
    participant App as Your app
    participant Widget as KYC widget
    participant User as End user
    participant API as Retrieve claims

    App->>Widget: Open published widget_id
    Widget->>User: Request access to identity
    User->>Widget: Grant access
    Widget->>App: onSuccess shareCode
    App->>API: POST /api/v1/vouch/request/claims
    API->>App: Approved claims
```

## 1. Create the flow

In the Dojah app, open **EasyOnboard** and create a Vouch widget. Choose one type:

* **Verification** — select the identity claims the user must share (for example the government data your onboarding requires). The retrieve-claims response includes only what this flow requests.
* **Authentication** — the flow asks the user to share basic profile info. Use this for sign-in or account matching. The response includes email and name.

Publish the flow. From the Integration tab, copy the `widget_id`. From **Developers**, copy the same app's App ID and secret key. Keep the secret key on your server. See [Authentication](/api-reference/get-started/authentication).

## 2. Launch the widget

Load the KYC widget and open the published Vouch flow. `type` is `vouch` for both verification and authentication. `type` is the only attribute that changes compared to the [default widget flow](/api-reference/hosted-flows-easyonboard/launch-a-flow).

```html HTML theme={null}
<script src="https://widget.dojah.io/widget.js"></script>
<button id="vouch">Continue with Vouch</button>
<script>
  const connect = new Connect({
    app_id: "your_app_id",
    p_key: "your_public_key",
    type: "vouch",
    config: { widget_id: "your_vouch_widget_id" },
    reference_id: "session-8f3a1c9b2e",
    onSuccess: function (response) {
      // Send response.shareCode to your server. Do not call the claims API here.
    },
    onError: function () {},
    onClose: function () {},
  });

  document.querySelector("#vouch").addEventListener("click", function () {
    connect.setup();
    connect.open();
  });
</script>
```

`onSuccess` means the user granted access and the widget returned a `shareCode`. `onError` and `onClose` mean there is no share code — do not create a session from those events.

Post `shareCode` to your backend over HTTPS as soon as you receive it. The browser must not call the claims API.

## 3. Exchange the share code

Call this from your server with the app's secret key. Send the key raw in `Authorization` — not as `Bearer`.

```bash cURL theme={null}
curl -X POST "https://api.dojah.io/api/v1/vouch/request/claims" \
  -H "Authorization: {{secret_key}}" \
  -H "AppId: {{app_id}}" \
  -H "Content-Type: application/json" \
  -d '{ "share_code": "SHARE_CODE" }'
```

<Note>
  **Sandbox uses the same path on a different host.** While testing, call `https://sandbox.dojah.io/api/v1/vouch/request/claims` with sandbox keys. See [Environments](/api-reference/get-started/environments).
</Note>

Set a 30 second timeout. Retry timeouts and `5xx` responses up to 3 times with exponential backoff. Do not retry `4xx` responses.

### Response

```json Response theme={null}
{
  "entity": {
    "status": "approved",
    "claims": {
      "basic_info": {
        "email": "user@example.com"
      },
      "bio_data": {
        "first_name": "Ada",
        "last_name": "Lovelace"
      }
    }
  },
  "error": null,
  "status": true
}
```

Proceed only when `entity.status` is `"approved"`. Any other status means the user did not grant the request — do not sign them in or mark them verified.

| Flow | Fields to read |
| - | - |
| Authentication | `claims.basic_info.email` is required to match or create the account. `claims.bio_data.first_name` and `claims.bio_data.last_name` are the shared name. |
| Verification | Read the identity attributes you selected on the flow. They are returned on `claims`. Ignore attributes the flow did not request — they will not be present. |

Treat a missing field your flow requires as a failed grant, the same as a non-approved status.

| HTTP status | Meaning |
| - | - |
| `200` with `entity.status` `"approved"` | Claims are ready to use |
| `200` with any other `entity.status` | Grant was not approved |
| `400` | Share code is missing or rejected |
| `401` | Secret key or App ID is wrong, or the key was sent as `Bearer …` |
| `402` | Production wallet balance is too low |
| `5xx` or timeout | Retry, then fail closed |

## 4. Use the claims

**Authentication.** Look up your user by `claims.basic_info.email`. If the email is absent, stop. Update the stored name from `claims.bio_data` when those fields are present, then issue your own session.

**Verification.** Map `claims` onto the checks your verification flow requested, then store the result against your own user id and the `reference_id` you passed into the widget. Do not treat the widget callback as a passed KYC check.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.