---
title: "API reference"
description: "Every function @helix-id/node exports for the redirect flow, with its options, return value and errors."
source: "/docs/api"
updated: "2026-09-24"
---

# API reference

Every function @helix-id/node exports for the redirect flow, with its options, return value and errors.

## `createAuthUrl(options)`

`createAuthUrl(options)` -> `Promise<{ url, nonce, sig }>`

Generates an HMAC-signed redirect URL and a cryptographic nonce. **Async** - it signs via the Web Crypto API, so it returns a Promise and must be awaited. It performs no network call.

| Option         | Type                        | Required | Description                                                                                                                                                                      |
| -------------- | --------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spaceId`      | string                      | yes      | Your Space ID (UUID) from the Helix admin panel.                                                                                                                                 |
| `state`        | string                      | yes      | Opaque base64 payload echoed back in the callback.                                                                                                                               |
| `origin`       | string                      | yes      | The browser origin your app is served from, e.g. `https://app.example.com`. Helix targets its completion message at exactly this origin, so it must match. Sent as `sdk_origin`. |
| `secret`       | string                      | yes      | Shared secret from the Helix admin panel. Used to HMAC-SHA256-sign the URL params - server-side only.                                                                            |
| `baseUrl`      | string                      | no       | Override Helix portal URL. Defaults to `https://capsule.helix.id` when omitted.                                                                                                  |
| `env`          | `"sandbox" \| "production"` | no       | Selects which space config Helix looks up. Defaults to `production` - leave it unset against `capsule.helix.id`.                                                                 |
| `enrollmentId` | string                      | no       | Enrollment ID from a previous `verifyCallback` result. Pass it to verify this user against their existing enrollment; omit on their first session to enroll them.                |

**Returns** `Promise<{ url: string, nonce: string, sig: string }>` - store `nonce` in the user session and hand `url` to the browser.

### URL signing

The signature covers the canonical query string: every param except `sig`, sorted by key, joined as `key=value` pairs with `&`. That string is HMAC-SHA256'd with `secret` and appended as `sig` (64 lowercase hex chars):

```text
/voice-auth?space_id=...&nonce=...&state=...&env=...&sdk_origin=...&sig=<hmac-sha256-hex>
```

Because every other param is covered, changing any of them after signing invalidates `sig`. Build the URL once, on the server, and pass it through untouched.

## `verifyAuthUrlSignature(url, secret)`

`verifyAuthUrlSignature(url, secret)` -> `Promise<void>`

Verifies the `sig` on an auth URL produced by `createAuthUrl`. **Async.** Rebuilds the canonical string from the URL's remaining params and compares in constant time via `crypto.subtle.verify`. Server-side only - it needs the secret.

```js
import { verifyAuthUrlSignature, InvalidAuthUrlSignatureError } from "@helix-id/node";

try {
  await verifyAuthUrlSignature(url, process.env.HELIX_SECRET);
} catch (error) {
  if (error instanceof InvalidAuthUrlSignatureError) {
    // URL is unsigned or was tampered with - do not redirect the user
  }
}
```

**Returns** `Promise<void>` - resolves when the signature is valid.

**Throws** `InvalidAuthUrlSignatureError` when `sig` is missing or does not match.

Most integrations never call this: your own server produced the URL, so there is nothing to check. It is there for architectures where the URL crosses a trust boundary between services - a gateway, a BFF, or a queue - and the receiving side wants proof it was not rewritten in transit.

## `verifyCallback(query, options)`

`verifyCallback(query, options)` -> `Promise<VerifyCallbackResult>`

Verifies the HMAC-signed callback payload and returns the parsed result. **Async** - it uses the Web Crypto API, so it returns a Promise and must be awaited. The first argument is the raw callback query, every field a plain string.

| Option   | Type   | Required | Description                                               |
| -------- | ------ | -------- | --------------------------------------------------------- |
| `nonce`  | string | yes      | Nonce returned by `createAuthUrl`, stored in the session. |
| `secret` | string | yes      | Shared secret from the Helix admin panel.                 |

**Returns** `Promise<{ status, statusCode, logId, state, enrollmentId? }>` - `enrollmentId` is present when the space has Voice MFA or Banned List enabled, absent otherwise.

**Throws** `InvalidSignatureError`, `NonceMismatchError`, `ExpiredTimestampError`, `MalformedCallbackError`.


## Sitemap

See the full [sitemap](https://helix.id/sitemap.md) for all pages.
