SDK

Use the Human Gateway SDK.

The Human Gateway SDK lets Partners launch Verify/Auth flows, receive frontend UX results, and verify signed backend callbacks with server helpers.

Install

Add the SDK to your frontend application. Server-side callback helpers are also exported from the same package.

Install SDK

npm install @human-gateway/sdk

Configure the client

Initialize the SDK with the Human Gateway Project ID used by that integration flow. Project IDs and Action keys are public integration references, not secrets. Environment variables are a local application convention for keeping configuration explicit and maintainable.

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

Create SDK client

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

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

The variable names shown above are examples only. Human Gateway uses the actual projectId and actionKey values, not your local environment variable names.

If your application uses multiple Projects or several Actions of the same type, namespace the configuration locally with names that make sense for your application.

Multi-Project and multi-Action example

NEXT_PUBLIC_HG_COMMUNITY_PROJECT_ID=project_xxx
NEXT_PUBLIC_HG_COMMUNITY_LOGIN_ACTION_KEY=hg_auth_action_key_xxx
NEXT_PUBLIC_HG_COMMUNITY_VERIFY_ACTION_KEY=hg_verify_action_key_xxx

NEXT_PUBLIC_HG_ADMIN_PROJECT_ID=project_yyy
NEXT_PUBLIC_HG_ADMIN_LOGIN_ACTION_KEY=hg_auth_action_key_yyy

Names such as COMMUNITY, ADMIN, and LOGIN are local labels only. They are not Human Gateway Project aliases, Action aliases, or protocol identifiers.

Project and action model

A Human Gateway Project is a scoped integration boundary for an application. A Partner can have multiple Projects, and each Project can contain multiple Actions. An Action represents a specific Verify or Auth flow inside its Project.

  • Use Verify actions for one-time or repeated human verification flows.
  • Use Auth actions when you need a Project-scoped PartnerUser and Human Gateway auth session.
  • Pass explicit actionKey values in production to avoid ambiguity.

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 with SDK

const result = await hg.verify({
  actionKey: process.env.NEXT_PUBLIC_HG_VERIFY_ACTION_KEY!,
  onOpen: () => {
    console.log("Human Gateway Verify opened");
  },
  onSuccess: (result) => {
    console.log("Human Gateway Verify completed", result);
  },
  onError: (error) => {
    console.error("Human Gateway Verify failed", error.code);
  },
});

if (result.verified_human) {
  // Update UI immediately.
  // Persist durable state after a valid signed callback.
}

Verify result

{
  "success": true,
  "verified_human": true,
  "unique_for_action": true,
  "already_verified": false,
  "project_id": "project_xxx"
}

Run Auth

Use Auth when you need a private verified-human login/session flow. Auth resolves or creates a Project-scoped PartnerUser and a Human Gateway auth session.

First auth

const result = await hg.auth({
  actionKey: process.env.NEXT_PUBLIC_HG_AUTH_ACTION_KEY!,
  onOpen: () => {
    console.log("Human Gateway Auth opened");
  },
  onSuccess: (result) => {
    console.log("Human Gateway Auth completed", result);
  },
  onError: (error) => {
    console.error("Human Gateway Auth failed", error.code);
  },
});

// hg.auth() resolves only after successful Auth completion.
// Update UI immediately and reconcile durable access from your backend callback flow.
console.log(result.partner_user_id);

For returning Auth, pass the partner_user_id from a previous successful Auth result for the same Project as partnerUserId. Human Gateway treats it as an opaque continuity hint, not authentication evidence, and independently validates the returning Auth flow before completion.

Returning auth

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

// partnerUserId must come from a previous successful Auth result.
// It is an opaque continuity hint, not authentication evidence.

Auth result

{
  "success": true,
  "event": "auth.completed",
  "verified_human": true,
  "partner_user_id": "puser_xxx",
  "auth_session_id": "authsess_xxx",
  "project_id": "project_xxx",
  "expires_at": "2026-08-01T00:00:00.000Z"
}

SDK options

During early access, popup mode is the primary supported browser flow. Partner-facing integrations should validate their integration in sandbox before promoting the Project to production.

SDK options

type HumanGatewayOptions = {
  projectId: string;
  environment?: "production" | "sandbox";
  mode?: "auto" | "popup" | "modal" | "redirect";
  baseUrl?: string;
  timeoutMs?: number;
};

Both production and sandbox use the hosted Human Gateway domain by default. For local testing, previews, or controlled internal validation, pass an explicit baseUrl.

Call hg.verify() or hg.auth() directly from a user action such as a button click. Modern browsers may block popups opened after delayed promises, timers, or background tasks.

Auth options

type HumanGatewayAuthOptions = {
  actionKey?: string;
  partnerUserId?: string;
  onOpen?: () => void;
  onClose?: () => void;
  onSuccess?: (result: HumanGatewayAuthResult) => void;
  onError?: (error: HumanGatewayError) => void;
};

partnerUserId is optional and should only contain a partner_user_id previously returned by Human Gateway Auth. Do not invent, transform, or treat this value as proof of identity.

Frontend result vs backend callback

SDK results are useful for immediate UI updates. Signed backend callbacks should be treated as the durable source of truth for persistent state, access control, and database updates.

A malicious client can manipulate frontend state. A valid callback signature cannot be produced without the Project callback secret. Your backend should also validate the timestamp, expected Project, callback envelope, and event payload before trusting the event.

Continue with the callbacks guide to verify signed backend events.

Server helpers

Server helpers are exported from @human-gateway/sdk/server. Use them only in backend code. For a Project-scoped callback endpoint, keep the trusted Project ID and matching callback secret together in your server-side configuration and pass expectedProjectId to verifyCallback().

Server callback helper

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

const callbackSecret = process.env.HG_CALLBACK_SECRET;
const expectedProjectId = process.env.HG_PROJECT_ID;

if (!callbackSecret || !expectedProjectId) {
  throw new Error("Missing Human Gateway callback configuration");
}

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

For multiple Projects, namespace each trusted Project ID and callback secret pair locally, for example HG_COMMUNITY_PROJECT_ID with HG_COMMUNITY_CALLBACK_SECRET. Never choose a callback secret by first trusting an unverified payload.project_id.

Error handling

Handle common SDK errors so users can retry safely when a popup is blocked, closed, timed out, or the hosted flow fails.

Error handling

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

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

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

  if (result.verified_human) {
    // Update UI.
  }
} catch (error) {
  if (error instanceof HumanGatewayError) {
    if (error.code === "user_closed") {
      // The user closed the popup.
    }

    if (error.code === "popup_blocked") {
      // Ask the user to allow popups and retry from a direct click.
    }

    if (error.code === "timeout") {
      // The flow took too long.
    }

    if (error.code === "verification_failed") {
      // The hosted verification flow did not complete successfully.
    }
  }
}

SDK error codes

popup_blocked
user_closed
timeout
invalid_message
invalid_origin
verification_failed
auth_failed
unknown_error

Privacy model

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 SDK responses or callbacks.

Verify results may include scoped operational fields such as verified_human, unique_for_action, already_verified, and project_id. Auth results have their own session and identity fields.

Auth results expose Human Gateway abstractions such as the Project-scoped partner_user_id and the auth_session_id. Returning Auth may accept that prior partner_user_id for the same Project as partnerUserId, but Human Gateway does not expose the underlying World session identifier, internal World identity references, or proof internals to the Partner.

Integration checklist

SDK checklist

SDK integration checklist
- Install @human-gateway/sdk
- Keep Project and Action configuration explicit
- Use explicit actionKey values in production
- Namespace multi-Project and multi-Action values locally
- Launch Verify/Auth from direct user actions
- Treat frontend results as UX signals
- Configure a full backend callback URL
- Verify signed callbacks on the backend
- Validate the expected Project with expectedProjectId
- Keep Project callback secrets out of frontend code
- Process callback event_id idempotently
- Review Privacy, Terms, Security, and Cookies policies

Next steps

Start with the Quickstart for the recommended integration path, then use the Callbacks guide to verify backend events safely.