Skip to content

Server SDK

@valgix/humanpass is the official server-side SDK for Node.js 20+ and Bun. It uses standards-based fetch and must run only in trusted backend code.

Terminal window
npm install @valgix/humanpass

Or with Bun:

Terminal window
bun add @valgix/humanpass

Create one reusable client for each backend process:

import { HumanPass } from "@valgix/humanpass";
export const humanpass = new HumanPass({
baseUrl: "https://humanpass.valgix.com",
secret: process.env.HUMANPASS_SECRET_KEY!,
timeoutMs: 5_000,
});

Use the official HumanPass service URL shown above.

const result = await humanpass.verify({
response: submittedResponse,
remoteIp: requestIp,
expectedAction: "signup",
expectedHostname: "app.example.com",
idempotencyKey: requestId,
});
if (!result.success) {
// Reject or ask the visitor to retry.
return { ok: false, reasons: result.error_codes };
}
return {
ok: true,
verificationId: result.verification_id,
};

expectedAction and expectedHostname are checked by the SDK after HumanPass verifies the response. Use both whenever your deployment has stable values.

A completed API request returns a discriminated result with success: true or success: false. Network failures, invalid service responses, and invalid client configuration throw typed errors:

import {
HumanPassApiError,
HumanPassConfigurationError,
HumanPassTransportError,
} from "@valgix/humanpass";
try {
const result = await humanpass.verify({ response });
if (!result.success) return rejectVerification(result.error_codes);
return continueRequest();
} catch (error) {
if (error instanceof HumanPassTransportError) {
return showTemporaryFailure();
}
if (error instanceof HumanPassApiError) {
reportRequestId(error.requestId);
return showTemporaryFailure();
}
if (error instanceof HumanPassConfigurationError) {
throw error; // Fix deployment configuration.
}
throw error;
}

The SDK does not automatically retry verification. A response is single-use, so retries require a stable idempotencyKey bound to the same request.

const controller = new AbortController();
const result = await humanpass.verify({
response,
signal: controller.signal,
});
  • Load the secret from server-only configuration.
  • Never pass the HumanPass client to browser bundles or serialize it.
  • Do not include the response token or secret in application logs.
  • Rotate secrets using the rotation guide.