# Node.js SDK API Reference Reference for CoreLicense Node.js SDK classes, methods, configuration, and error handling. Canonical HTML URL: https://corelicense.net/docs/nodejs-sdk/api-reference Plain-text URL: https://corelicense.net/docs/nodejs-sdk/api-reference.txt ---# API Reference Public API `@corelicense/node` v0.5.9. --- ## CoreLicense ### Constructor ```ts new CoreLicense(options: CoreLicenseOptions) ``` ### Lifecycle | Method | Returns | Description | |--------|---------|-------------| | `boot()` | `Promise` | Initialize, sync server, fail-closed | | `refresh()` | `Promise` | Force refresh policy | | `startBackgroundCheck()` | `void` | Enable sync interval | | `stopBackgroundCheck()` | `void` | Disable interval | ### License gates | Method | Description | |--------|-------------| | `requireActive()` | Throw if not active | | `requireFeature(feature)` | Throw + audit if feature is off | | `checkLimit(name, current)` | Throw if limit exceeded | | `consumeQuota(name, amount?)` | Consume local quota | | `getStatus()` | Current status | | `getPolicy()` | Verified policy (null if not yet available) | | `getRuntimeConfig()` | Config derived from policy | ### HTTP integrations | Method | Description | |--------|-------------| | `express(options?)` | Express `RequestHandler` | | `fastifyPlugin(options?)` | Fastify plugin | ### Worker / CLI | Method | Description | |--------|-------------| | `guardWorker(name)` | Guard worker process | | `guardCommand(name)` | Guard CLI/cron command | ### Deep integration | Method | Description | |--------|-------------| | `bootstrap(options)` | Register modules + services | | `createLicensedRegistry()` | Dedicated `LicensedModuleRegistry` | | `createLicensedContainer()` | Dedicated `LicensedServiceContainer` | ### Events ```ts license.on(event, handler) ``` Events: `statusChanged` | `policyUpdated` | `licenseRevoked` | `licenseSuspended` | `offlineMode` > `CoreLicense` only exposes `on()`. To unsubscribe, keep a reference to the handler and use the internal `EventBus` if custom wiring is needed. --- ## LicensedModuleRegistry | Method | Description | |--------|-------------| | `bootstrap(definitions, ctx)` | Bulk register | | `registerLicensed(def, ctx)` | Register a single module | | `has(name)` | Is module bound? | | `get(name)` | Get module + re-check license | | `list()` | Names of registered modules | --- ## LicensedServiceContainer | Method | Description | |--------|-------------| | `bootstrap(definitions, ctx)` | Bind services | | `resolve(name)` | Resolve + re-check license | | `has(name)` | Is service bound? | --- ## Helpers ```ts loadOptionsFromEnv(overrides?: Partial): CoreLicenseOptions resolveApiUrl(options, cachedApiUrl?): string parseEmbeddedApiUrl(licenseKey): string | null registerLicensedRoutes(app, registry, routes): string[] isLicenseError(error): boolean formatLicenseError(error): string isFeatureEnabled(policy, feature): boolean ``` --- ## Subpath exports ### `@corelicense/node/express` ```ts createExpressMiddleware(license, options?): RequestHandler ``` ### `@corelicense/node/fastify` ```ts createFastifyPlugin(license, options?): FastifyPluginAsync coreLicenseFastifyPlugin ``` ### `@corelicense/node/nestjs` ```ts CoreLicenseModule.forRoot(options): DynamicModule CoreLicenseGuard CoreLicenseFeatureGuard CoreLicenseExceptionFilter RequireFeature(feature) // decorator REQUIRE_FEATURE_KEY ``` --- ## Types ### `CoreLicenseOptions` See [installation.md](/docs/nodejs-sdk/quick-start#4-corelicenseoptions-constructor). ### `ExpressGuardOptions` / `FastifyGuardOptions` ```ts { allowPaths?: string[]; mode?: 'block' | 'limited'; } ``` ### `BootstrapResult` ```ts { modules: LicensedModuleRegistry; services: LicensedServiceContainer; registeredModules: string[]; registeredServices: string[]; skipped: { name: string; feature: string; reason: 'feature_disabled' }[]; } ``` ### `LicenseStatus` ```ts { status: 'active' | 'suspended' | 'revoked' | 'expired' | 'invalid' | 'blocked' | 'offline' | 'grace_expired' | 'limited'; policyVersion?: string; expiresAt?: number; graceUntil?: number; offline?: boolean; // ... } ``` --- ## Error codes Every `LicenseError` has `code`, `source`, `message`, `toClientPayload()`, `toJSON()`. | Code | HTTP (middleware) | |------|-------------------| | `LICENSE_REVOKED` | 403 | | `LICENSE_SUSPENDED` | 403 | | `LICENSE_EXPIRED` | 403 | | `LICENSE_INVALID` | 403 | | `LICENSE_NOT_FOUND` | 403 | | `LICENSE_NOT_STARTED` | 403 | | `OFFLINE_GRACE_EXPIRED` | 403 | | `FEATURE_DISABLED` | 403 | | `MODULE_NOT_LICENSED` | 403 | | `QUOTA_EXCEEDED` | 403 | | `MAX_INSTANCES` | 403 | | `INSTANCE_BLOCKED` | 403 | | `CONFIG_MISSING_ENV` | — (boot fail) | | `PRODUCT_NOT_FOUND` | — (boot fail) | | `PUBLIC_KEYS_NOT_PUBLISHED` | — (boot fail) | | `PUBLIC_KEYS_FETCH_FAILED` | — (boot fail) | | `LICENSE_API_UNREACHABLE` | — (boot fail) | | `LICENSE_API_TIMEOUT` | — (boot fail) | | `POLICY_SIGNATURE_ERROR` | — (boot fail) | | `BOOT_NOT_CALLED` | — | | `POLICY_NOT_AVAILABLE` | — (boot fail) | | `RUNTIME_CONFIG_UNAVAILABLE` | — | | `POLICY_TOKEN_MISSING` | — | | `POLICY_LOAD_FAILED` | — | | `POLICY_PRODUCT_MISMATCH` | — | | `POLICY_INSTANCE_MISMATCH` | — | | `INSTANCE_ID_UNRESOLVED` | — | | `PUBLIC_KEY_PINNED_MISMATCH` | — | | `PUBLIC_KEYS_EMPTY` | — | | `MODULE_NOT_REGISTERED` | 403 | | `SERVICE_NOT_BOUND` | 403 | | `RATE_LIMITED` | — (retryable) | | `WORKER_NOT_ALLOWED` | — | | `COMMAND_NOT_ALLOWED` | — | Full list in source: `src/errors/codes.ts` `formatLicenseError(error)` also returns `retryable` and `httpStatus` (when available) for transport/API errors. ### License Server response → SDK mapping **Client API** (`POST /v1/client/*`) — HTTP 200, body `ok: false`: | Server `code` | SDK `code` | Retry? | |---------------|------------|--------| | `LICENSE_REVOKED` | `LICENSE_REVOKED` | No | | `LICENSE_SUSPENDED` | `LICENSE_SUSPENDED` | No | | `LICENSE_EXPIRED` | `LICENSE_EXPIRED` | No | | `LICENSE_NOT_STARTED` | `LICENSE_NOT_STARTED` | No | | `INVALID_PRODUCT` | `PRODUCT_NOT_FOUND` | No | | `PRODUCT_NOT_FOUND` | `PRODUCT_NOT_FOUND` | No | | `INVALID_LICENSE` | `LICENSE_INVALID` | No | | `LICENSE_NOT_FOUND` | `LICENSE_NOT_FOUND` | No | | `LICENSE_INVALID` | `LICENSE_INVALID` | No | | `INSTANCE_BLOCKED` | `INSTANCE_BLOCKED` | No | | `MAX_INSTANCES` | `MAX_INSTANCES` | No | | `POLICY_SIGN_FAILED` | `POLICY_SIGNATURE_ERROR` | No | **Public keys** (`GET /v1/public/products/{id}/keys`) — HTTP error, body `{ code, message }`: | Server `code` / HTTP | SDK `code` | Retry? | |----------------------|------------|--------| | `PRODUCT_NOT_FOUND` / 404 | `PRODUCT_NOT_FOUND` | No | | `PUBLIC_KEYS_NOT_PUBLISHED` / 404 | `PUBLIC_KEYS_NOT_PUBLISHED` | No | | `NOT_FOUND` / 404 (legacy) | `PUBLIC_KEYS_NOT_PUBLISHED` | No | | `RATE_LIMITED` / 429 | `RATE_LIMITED` | Yes | | 5xx / 408 | `PUBLIC_KEYS_FETCH_FAILED` | Yes | | Other 4xx | `PUBLIC_KEYS_FETCH_FAILED` | No | | Network / DNS / refused | `LICENSE_API_UNREACHABLE` | Yes | | Timeout | `LICENSE_API_TIMEOUT` | Yes | **License API HTTP errors** (400, 502, …) — not an `ok: false` body: | Case | SDK `code` | Retry? | |------|------------|--------| | 429 | `RATE_LIMITED` | Yes | | 5xx / 408 | `LICENSE_API_ERROR` | Yes | | Other 4xx | `LICENSE_API_ERROR` | No | | Network / DNS / refused | `LICENSE_API_UNREACHABLE` | Yes | | Timeout | `LICENSE_API_TIMEOUT` | Yes | --- ## Client API (License Server) The SDK calls these endpoints (not typically called directly from the app): | Endpoint | Description | |----------|-------------| | `POST /v1/client/activate` | First activation | | `POST /v1/client/check` | Periodic check | | `POST /v1/client/refresh` | Force refresh | | `GET /v1/public/products/{id}/keys` | Public keys | Details: [Client API Reference](/docs/client-api)