Skip to content
← Cubid developer portal

Developer quickstart

Hosted Redirect Verification Quickstart

This quickstart is the first IAH integration path for web app developers. It keeps the app-side work small: redirect the user to IAH-hosted verification, handle the return URL, verify the result on the server, and receive webhook updates.

IAH owns the developer verification product surface. Cubid remains the infrastructure behind the proof, disclosure, policy, and identity runtime.

What You Build

  1. A "Verify with IAH" button in your app.
  2. A return URL that receives the user after hosted verification.
  3. A server verification check that confirms the result before granting access.
  4. A webhook receiver for asynchronous verification updates.

Environment

Use placeholders until your app credentials are issued:

Environment · Shell
IAH_APP_ID=iah_app_123
IAH_API_KEY=iah_live_replace_me
IAH_VERIFY_BASE_URL=https://i-am-human.app/verify/start
IAH_RETURN_URL=http://localhost:3000/iah/callback
IAH_WEBHOOK_SECRET=whsec_replace_me

Never expose IAH_API_KEY or IAH_WEBHOOK_SECRET to browser code.

Client Redirect

Build the hosted verification URL on the server when possible. For local prototypes, the browser can assemble a redirect with public values only:

Client Redirect · JavaScript
import { createHostedVerificationUrl } from "@iah/browser";

const url = createHostedVerificationUrl({
  appId: "iah_app_123",
  returnUrl: "http://localhost:3000/iah/callback",
  state: crypto.randomUUID(),
});

window.location.href = url;

The state value should be stored in your session before redirecting and checked when the user returns.

Return URL

IAH returns the user to your return_url with a verification reference and the original state. The current hosted UX scaffold is available at /verify/start and redirects to:

Return URL · Text
GET /iah/callback?verification_id=ver_123&state=state_123

Your app should:

  1. confirm state matches the value stored before redirect
  2. send verification_id to your server
  3. have the server check verification status with IAH before unlocking access

Server Verification Check

The server check is intentionally IAH-first. The app should not need to understand Cubid OIDC, custody, chains, or selective-disclosure internals.

Server Verification Check · JavaScript
import { createIAHCoreClient } from "@iah/core";

const iah = createIAHCoreClient({
  apiKey: process.env.IAH_API_KEY,
  appId: process.env.IAH_APP_ID,
});

const result = await iah.checkVerification({ verificationId });

if (result.data?.verified === true) {
  // Grant access to the protected feature.
}

Expected response shape:

Server Verification Check · JSON
{
  "data": {
    "verification_id": "ver_123",
    "verified": true,
    "subject": "app_scoped_subject_123",
    "completed_at": "2026-05-15T00:00:00.000Z"
  }
}

Webhook Receiver

Use webhooks for asynchronous updates or delayed proof completion:

Webhook Receiver · JSON
{
  "type": "verification.completed",
  "data": {
    "verification_id": "ver_123",
    "verified": true,
    "subject": "app_scoped_subject_123"
  }
}

The receiver should verify the webhook signature with IAH_WEBHOOK_SECRET before trusting the payload. The local example in examples/hosted-redirect/ includes the expected route shape.

Advanced Cubid Notes

Most apps should not need these for the first integration. When your product needs deeper identity infrastructure, use Cubid paths for Sign in with Cubid, app-scoped selective disclosure, passkey-required verification, custom proof policies, and chain or custody features.