Skip to main content
@humanity-org/connect-sdk is the official TypeScript helper for Humanity’s Public API. It wraps the generated REST client with ergonomic helpers for OAuth, preset verification, feeds, and error handling so partner teams can ship integrations quickly.

Installation

npm install @humanity-org/connect-sdk
# or
yarn add @humanity-org/connect-sdk
# or
pnpm add @humanity-org/connect-sdk
import { HumanitySDK } from '@humanity-org/connect-sdk';

Initialization & configuration

OptionRequiredDescription
clientIdIssued when your app is approved.
redirectUriMust match one of the URIs registered with Humanity.
environmentsandbox or production. Sets the Humanity base URL automatically (defaults to sandbox).
baseUrlAdvanced override for regional/private deployments (takes precedence over environment).
clientSecretOnly required for confidential clients or service-to-service flows. Never ship it to the browser.
clockToleranceMsAdjusts token expiry validation for skewed environments.
defaultHeadersCustom headers to include with every request (e.g., for tracing).
fetchCustom fetch implementation for environments without native fetch or for request interception.
const sdk = new HumanitySDK({
  clientId: process.env.HUMANITY_CLIENT_ID!,
  redirectUri: process.env.HUMANITY_REDIRECT_URI!,
  environment: process.env.HUMANITY_ENVIRONMENT ?? 'sandbox',
  clientSecret: process.env.HUMANITY_CLIENT_SECRET, // optional
});
Create an instance per incoming request (ideal for serverless) or share a singleton and pass tokens into each helper—whichever matches your runtime. Store secrets in your platform’s secret manager; never embed them in client-side bundles.
Next.js / SSR frameworks: Do not instantiate the SDK at module level during build time, as environment variables may not be available. Use lazy initialization instead:
let sdk: HumanitySDK | null = null;

export function getHumanitySDK() {
  if (!sdk) {
    sdk = new HumanitySDK({
      clientId: process.env.HUMANITY_CLIENT_ID!,
      redirectUri: process.env.HUMANITY_REDIRECT_URI!,
      environment: process.env.HUMANITY_ENVIRONMENT ?? 'sandbox',
    });
  }
  return sdk;
}

OAuth helpers

const sdk = new HumanitySDK({
  clientId: process.env.HUMANITY_CLIENT_ID!,
  redirectUri: process.env.HUMANITY_REDIRECT_URI!,
  environment: 'sandbox',
});

// Generate state for CSRF protection
const state = HumanitySDK.generateState();

const { url, codeVerifier } = sdk.buildAuthUrl({
  // Use OAuth scopes (not preset names) - see /concepts/scopes
  scopes: ['identity:read', 'identity:date_of_birth', 'kyc:read'],
  state, // Pass state as input - it is NOT returned by buildAuthUrl
  additionalQueryParams: { prompt: 'consent' },
});

// Store state and codeVerifier server-side, then redirect user to `url`
// On callback, verify state matches before exchanging the code:
const token = await sdk.exchangeCodeForToken({
  code: callbackQuery.get('code')!,
  codeVerifier,
});

await sdk.revokeToken({
  token: token.refreshToken,
  tokenType: 'refresh_token',
});
Every helper maps to an OAuth endpoint (/oauth/authorize, /oauth/token, /oauth/revoke) and enforces the PKCE + grant-type requirements documented in the API reference.

buildAuthUrl options

OptionRequiredDescription
scopesArray of OAuth scopes to request (e.g., ['identity:read', 'kyc:read']).
stateCSRF protection token. Generate with HumanitySDK.generateState() and verify on callback.
nonceReplay protection for ID tokens. Generate with HumanitySDK.generateNonce().
codeVerifierProvide your own PKCE code verifier, or let the SDK generate one.
codeVerifierLengthLength of auto-generated code verifier (default: 43).
additionalQueryParamsExtra query parameters like { prompt: 'consent' } or { login_hint: 'user@example.com' }.
Returns: { url: string, codeVerifier: string } — the state is NOT returned; you must pass it in and store it yourself.

TokenResult

The exchangeCodeForToken helper returns a fully typed TokenResult:
PropertyTypeDescription
accessTokenstringBearer token for API requests.
tokenTypestringAlways "Bearer".
expiresInnumberSeconds until the access token expires.
scopestringSpace-separated list of granted scopes.
grantedScopesstring[]Array of granted scopes.
presetKeysstring[]Preset keys available for verification.
authorizationIdstringUnique ID for this authorization grant.
appScopedUserIdstringUser ID scoped to your app—use this for user identification.
issuedAtstring?ISO timestamp when the token was issued.
refreshTokenstring?Refresh token (confidential clients only).
refreshTokenExpiresInnumber?Seconds until the refresh token expires.
refreshIssuedAtstring?ISO timestamp when the refresh token was issued.
idTokenstring?OIDC ID token (when openid scope is requested).
rawobjectRaw API response for advanced use cases.
rateLimitobject?Rate limit info from response headers.

Static security helpers

The SDK provides static methods for OAuth security parameters:
// Generate cryptographically secure state for CSRF protection
const state = HumanitySDK.generateState();

// Generate nonce for replay protection (when using openid scope)
const nonce = HumanitySDK.generateNonce();

// Verify state matches on callback (timing-safe comparison)
if (!HumanitySDK.verifyState(storedState, callbackState)) {
  throw new Error('State mismatch - possible CSRF attack');
}

// Verify nonce in ID token
if (!HumanitySDK.verifyNonce(storedNonce, idTokenNonce)) {
  throw new Error('Nonce mismatch - possible replay attack');
}

Preset verification

const presets = await sdk.verifyPresets({
  accessToken: token.accessToken,
  presets: ['is_human', 'age_over_21', 'kyc_passed'],
});
  • verifyPreset, verifyPresets, and getPreset expose the /presets/* endpoints with fully typed responses (including evidence payloads).
  • Use listPresets() to discover all available presets with their metadata.
  • Maximum of 10 presets per batch request; the helper enforces this before hitting the API.

PresetBatchResult

The verifyPresets helper returns a PresetBatchResult with two arrays:
interface PresetBatchResult {
  results: PresetCheckResult[];  // Successful verifications
  errors: PresetError[];         // Failed verifications
}

interface PresetCheckResult {
  preset: string;                // The preset key (e.g., "is_human")
  value: boolean | string | number | null;  // The verification result
  status: 'valid' | 'expired' | 'pending' | 'unavailable';
  evidence?: object;             // Credential evidence (varies by preset)
  expiresAt?: string;            // ISO timestamp when the result expires
}

interface PresetError {
  preset: string;
  error: {
    error: string;               // Error code
    error_description?: string;  // Human-readable description
  };
}

Query Engine

For declarative queries against user credentials, use the Query Engine:
// Predicate query (boolean check)
const ageCheck = await sdk.evaluateQuery({
  accessToken: token.accessToken,
  query: {
    check: { claim: 'identity.age', operator: '>=', value: 21 }
  }
});

if (ageCheck.passed) {
  // User is 21+
}

// Compound policy with multiple conditions
const eligibility = await sdk.evaluateQuery({
  accessToken: token.accessToken,
  query: {
    policy: {
      allOf: [
        { check: { claim: 'kyc.passed', operator: '==', value: true } },
        { check: { claim: 'identity.country', operator: 'in', value: ['US', 'CA'] } }
      ]
    }
  }
});

// Projection query (data extraction)
const userData = await sdk.evaluateQuery({
  accessToken: token.accessToken,
  query: {
    projections: [
      { claim: 'identity.email', lens: 'pluck' },
      { claim: 'identity.country', lens: 'pluck' }
    ]
  }
});
See the Query Engine documentation for operators and examples.

Dropping down to the raw client

The generated sdk.client exposes every controller method exactly as declared in the OpenAPI. Use it whenever you need lower-level access or when rolling your own abstractions.
const preset = await sdk.client.presets.getPreset('humanity_user', {
  headers: { Authorization: `Bearer ${token.accessToken}` },
});
Because the SDK and API reference regenerate from the same DTOs (src/contracts), you can rely on TypeScript to catch breaking changes long before runtime.

Error handling

The SDK exports typed error classes for precise error handling:
import { HumanitySDKError, HttpError } from '@humanity-org/connect-sdk';

try {
  const token = await sdk.exchangeCodeForToken(code, codeVerifier);
} catch (error) {
  if (error instanceof HumanitySDKError) {
    console.error('SDK error:', {
      message: error.message,
      code: error.code,        // e.g., "invalid_grant", "E4003"
      status: error.status,    // HTTP status code
      details: error.details,  // Additional context from the API
    });
  }
}
Error ClassDescription
HumanitySDKErrorBase error for all SDK operations. Includes message, code, status, and details.
HttpErrorNetwork-level errors (timeouts, connection failures).
  • Rate limits follow the guidance in Environments & tooling. Honor Retry-After headers and reuse idempotency_key values when retrying POSTs.
  • If you lose track of the SDK abstraction, call sdk.client directly—both layers share the same authentication headers and transport pipeline.