Quickstart

Integrate Human Gateway safely.

Start with hosted Verify or Auth, connect your backend with signed callbacks, and keep persistent product decisions on the server side.

Before you start

Human Gateway is currently available to selected early partners. You need a project, at least one action, an allowed origin, and a backend callback URL before moving to a production integration.

The SDK result is useful for immediate product UX. The signed backend callback should be treated as the durable source of truth for backend state, access decisions, and database updates.

1. Install the SDK

Add the Human Gateway SDK to your frontend app.

Install SDK

npm install @human-gateway/sdk

2. Configure project and action

A Human Gateway project represents your partner integration. An action represents a specific Verify or Auth flow inside that project.

For production integrations, pass an explicit actionKey. This avoids ambiguity when a project has multiple actions.

Use environment variables for your public project and action keys instead of hardcoding real values directly in source files, examples, screenshots, or tutorials. Frontend project/action values are not callback secrets, but keeping them configurable reduces accidental exposure and makes sandbox and production environments easier to manage.

Frontend environment variables

NEXT_PUBLIC_HG_PROJECT_ID=project_xxx
NEXT_PUBLIC_HG_VERIFY_ACTION_KEY=hg_verify_action_key_xxx
NEXT_PUBLIC_HG_AUTH_ACTION_KEY=hg_auth_action_key_xxx

3. Run Verify

Use Verify when you need to confirm that a user is a real human for a specific product action, without creating a Human Gateway auth session.

Verify example

import { HumanGateway } from "@human-gateway/sdk";

const hg = new HumanGateway({
  projectId: process.env.NEXT_PUBLIC_HG_PROJECT_ID!,
  environment: "production",
});

const result = await hg.verify({
  actionKey: process.env.NEXT_PUBLIC_HG_VERIFY_ACTION_KEY!,
});

if (result.verified_human) {
  // Update the UI immediately.
  // Persist durable state only after your backend receives
  // and verifies the signed Human Gateway callback.
}

4. Run Auth

Use Auth when you need a private verified-human login/session flow. Auth creates a partner-scoped user reference and Human Gateway auth session.

Auth example

import { HumanGateway } from "@human-gateway/sdk";

const hg = new HumanGateway({
  projectId: process.env.NEXT_PUBLIC_HG_PROJECT_ID!,
  environment: "production",
});

const result = await hg.auth({
  actionKey: process.env.NEXT_PUBLIC_HG_AUTH_ACTION_KEY!,
});

if (result.success && result.verified_human) {
  // Update the UI.
  // Reconcile durable access from your backend callback flow.
}

5. Configure allowed origin and callback URL

Allowed origins and callback URLs are different. The allowed origin is the frontend origin that can launch Human Gateway hosted flows. The callback URL is the exact backend endpoint that receives signed POST callbacks.

Allowed origin vs callback URL

Allowed origin:
https://yourapp.com

Callback URL:
https://yourapp.com/api/human-gateway/callback

Do not configure only your root domain as the callback URL. Human Gateway sends callbacks to the exact URL configured in Partner Console, including the full path.

6. Use signed callbacks as source of truth

A frontend result can be manipulated by a malicious client. A valid signed callback cannot be forged without the project callback secret. Your backend should verify the callback before granting durable access or updating persistent user state.

7. Add a minimal callback endpoint

In a Next.js App Router project, create a backend route such as app/api/human-gateway/callback/route.ts. This endpoint should read the raw request body, verify the Human Gateway signature, validate the expected project, and process events idempotently.

Next.js callback endpoint

import { NextResponse } from "next/server";
import {
  HumanGatewayCallbackError,
  verifyCallback,
} from "@human-gateway/sdk/server";

export async function POST(request: Request): Promise<Response> {
  const callbackSecret = process.env.HG_CALLBACK_SECRET;
  const expectedProjectId = process.env.HG_PROJECT_ID;

  if (!callbackSecret || !expectedProjectId) {
    return NextResponse.json(
      {
        success: false,
        error: "missing_human_gateway_config",
      },
      { status: 500 }
    );
  }

  const body = await request.text();

  try {
    const callback = verifyCallback({
      body,
      headers: request.headers,
      secret: callbackSecret,
      expectedProjectId,
    });

    // Store callback.event_id and process it idempotently.
    // If this event_id was already processed, return 200
    // without repeating business logic.

    if (callback.event === "verification.completed") {
      const payload = callback.payload;

      if (payload.verified_human === true) {
        // Persist verified state in your backend.
      }
    }

    if (callback.event === "auth.completed") {
      const payload = callback.payload;

      if (payload.verified_human === true) {
        // Persist or reconcile auth state in your backend.
      }
    }

    return NextResponse.json({
      success: true,
      received: true,
      event_id: callback.event_id,
      event: callback.event,
      project_id: callback.project_id,
    });
  } catch (error) {
    if (error instanceof HumanGatewayCallbackError) {
      return NextResponse.json(
        {
          success: false,
          error: error.code,
        },
        { status: 401 }
      );
    }

    return NextResponse.json(
      {
        success: false,
        error: "callback_error",
      },
      { status: 500 }
    );
  }
}

Keep callback configuration on the backend. The callback secret must never use a NEXT_PUBLIC_ prefix and must never be exposed to browser code, screenshots, public repositories, or client-side logs.

Backend environment variables

HG_PROJECT_ID=project_xxx
HG_CALLBACK_SECRET=your_callback_secret

This example is intentionally minimal. In production, store callback.event_id before running business logic so retries or duplicate deliveries do not process the same event twice.

Continue with the callbacks guide for signature verification details, timestamp validation, raw body handling, error codes, and idempotency recommendations.

Production checklist

Checklist

Frontend
- Install @human-gateway/sdk
- Initialize HumanGateway with your projectId
- Pass an explicit actionKey for Verify or Auth
- Launch Verify/Auth from a direct user action
- Treat frontend results as UX signals

Backend
- Create a callback endpoint
- Read the raw request body before parsing JSON
- Verify x-hg-signature and x-hg-timestamp
- Validate event_id, event, and project_id
- Process callbacks idempotently
- Persist durable state only after valid signed callbacks

Partner Console
- Configure allowed origins
- Configure the full callback URL path
- Keep callback secrets private
- Test callbacks before production use

Privacy and compliance note

Human Gateway does not expose raw World ID nullifiers, raw World ID proofs, biometric data, identity documents, government identity data, or unnecessary personal identity information through standard Verify/Auth responses or callbacks. Human Gateway may return scoped operational fields such as verified_human, verification_level, project/action references, session references, event IDs, and timestamps.

verification_level can be device, document, secure_document, orb, or null. Human Gateway only propagates the value returned by World ID.

Human Gateway is not a KYC provider, civil identity provider, sanctions screening service, or replacement for legal compliance checks required by regulated products. Partners remain responsible for their own privacy notices, consent flows, legal compliance, and access decisions.