`@authdog/node-sdk` 0.2.0 is the official Node.js client for the [Authdog REST API](/docs/api). It lives in [`node/`](https://github.com/authdog/sdk/tree/main/node) of [authdog/sdk](https://github.com/authdog/sdk). It is a management and userinfo client, not a web-framework session binding.

The public npm registry does not host this package. Need to protect an Express, Fastify, Hono, or Koa route? Use a [backend SDK](/docs/backend).

## Install

Clone the monorepo and build the package:

```bash
git clone https://github.com/authdog/sdk.git
cd sdk/node
pnpm install
pnpm build
```

The package is ESM and ships TypeScript types from `dist/`. Depend on that build from your app (a `file:` dependency, or your own registry). `npm install @authdog/node-sdk` does not resolve on the public registry.

## Configure

Construct one client with the public API base URL. Pass a management Bearer credential (`ad_…`) when you call privileged endpoints:

```ts
import { AuthdogClient } from "@authdog/node-sdk"

const client = new AuthdogClient({
  baseUrl: "https://api.authdog.com",
  apiKey: process.env.AUTHDOG_API_TOKEN,
})
```

Keep the token server-side. `getUserInfo` still uses the caller access token, not the management key.

Optional config fields `environmentSecret` (`adenv_`), `scimToken` (`adscim_`), and `hrisToken` (`adhris_`) are the AuthZEN/MCP runtime, SCIM, and HRIS Bearers. `timeout` is milliseconds and defaults to `10000`.

`health()` is public and works without an API key:

```ts
const probe = await client.health()
```

Call `client.close()` when the process is done with the client.

## Resolve a user from an access token

```ts
import { APIError, AuthenticationError, AuthdogClient } from "@authdog/node-sdk"

const client = new AuthdogClient({ baseUrl: "https://api.authdog.com" })

try {
  const info = await client.getUserInfo(accessToken)
  console.log(info.user.displayName)
  console.log(info.user.emails[0]?.value)
} catch (error) {
  if (error instanceof AuthenticationError) {
    // 401: missing, invalid, or expired access token
    throw error
  }
  if (error instanceof APIError) {
    // transport or non-401 HTTP failure
    throw error
  }
  throw error
}
```

`GET /v1/userinfo` always sends `Authorization: Bearer <access-token>`. A constructor API key does not replace that header.

`UserInfoResponse` uses camelCase fields (`user.displayName`, `session.remainingSeconds`).

## Call the management API

Namespaces on the client wrap Waves 1–5 of the public `/v1` surface:

| Attribute | Resources |
| --- | --- |
| `organizations` | Organizations, invitations, members, keys |
| `tenants` | Tenants, domains, seats |
| `projects` | Applications under a tenant |
| `environments` | Environment records |
| `users` | Directory users in a tenant + environment |
| `groups` | Groups and membership |
| `rbac` | Roles, permissions, resources, mappings, ABAC |
| `audit` | Administrative audit logs |
| `events` | Identity event stream |
| `webhooks` | Webhook subscriptions |
| `notificationChannels` | SIEM / notification channels |
| `serviceAccounts` | Service accounts |
| `personalAccessTokens` | PATs |
| `apiSecrets` | Environment API secrets |
| `authzen` | AuthZEN evaluate, search, and discovery |
| `scim` | SCIM 2.0 directory |
| `hris` | HRIS employees and departments |
| `mcp` | MCP runtime |
| `otel` | OpenTelemetry exporters |
| `oidcClients` | OIDC clients |
| `actions` | Environment actions |
| `addons` | Add-ons |
| `billing` | Billing |
| `settings` | Environment settings |
| `elevate` | Elevate |
| `emailProviders` | Email providers |
| `featureFlags` | Feature flags |
| `forms` | Forms |
| `provisioningTokens` | Provisioning tokens |
| `impersonation` | Impersonation |
| `portal` | Account portal |
| `security` | Security settings |
| `threats` | Threats |
| `vanityDomains` | Vanity domains |
| `widgets` | Widgets |
| `smsProviders` | SMS providers |
| `connectedApps` | Connected-app grants |

```ts
const orgs = await client.organizations.list()
const users = await client.users.list("ten_123", "env_456")
```

Directory calls take the tenant id, then the environment id. AuthZEN discovery is unauthenticated. Evaluate, search, and the MCP runtime use `environmentSecret`. SCIM uses `scimToken`. HRIS uses `hrisToken`. OpenAPI at [`/v1/openapi`](https://api.authdog.com/v1/openapi) is the field-level contract.

## Errors

| Error | When |
| --- | --- |
| `AuthenticationError` | HTTP 401 |
| `APIError` | Other HTTP failures and transport errors |

## Other languages

| Language | Guide |
| --- | --- |
| Python | [Python SDK](/docs/sdks/python) |
| Go | [Go SDK](/docs/sdks/go) |
| Rust | [Rust SDK](/docs/sdks/rust) |
| Java | [Java SDK](/docs/sdks/java) |
| C# | [C# SDK](/docs/sdks/csharp) |
| Zig | [Zig SDK](/docs/sdks/zig) |

## Next

- [API reference](/docs/api): auth, versioning, and resource families
- [Backend requests](/docs/backend): validate sessions on incoming requests
- [Users](/docs/users): directory model the `users` namespace talks to
