> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ai-coustics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js VAD API

> Read dedicated speech predictions and configure voice activity detection.

**Version:** `@ai-coustics/aic-sdk` 0.24.0, Core SDK 0.24.0. [API index](/reference/sdk/api/node/index) · [Node.js quickstart](/reference/sdk/language-bindings/nodejs).

<span id="node-vad" />

## `Vad`

Synchronous dedicated voice activity detection (VAD). Use a dedicated VAD model and one instance per stream. Initialize before processing. Input audio is read without mutation. Feed original audio before synchronous enhancement changes that buffer.

<span id="node-vad-constructor" />

### `Vad.constructor`

```typescript theme={null}
constructor(model: Model, licenseKey: string, otelConfig?: OtelConfig | undefined | null)
```

`model` must be a live model handle of the required type. `licenseKey` is the SDK credential string; see [authentication](/models/get-started/authenticate-apps). Construction is synchronous and can throw for an invalid key, a disposed model or a model-type mismatch. Omitted or `null` `otelConfig` uses environment settings; otherwise pass an [OtelConfig](/reference/sdk/api/node/models-and-config#node-otelconfig) object. There is no automatic initialization.

<span id="node-vad-dispose" />

### `Vad.dispose`

```typescript theme={null}
dispose(): void
```

Destroys the native VAD synchronously. Idempotent. Later methods on the VAD object throw `Vad has been disposed`. Retained contexts remain readable but no new predictions are produced.

<span id="node-vad-initialize" />

### `Vad.initialize`

```typescript theme={null}
initialize(sampleRate: number, blockSize: number, variableBlockSize?: boolean | undefined | null): void
```

`sampleRate` is a whole-number rate in Hz; `blockSize` is a positive whole-number mono sample count. Query `model.getOptimalBlockSize(sampleRate)` for the preferred size. Omitted, `undefined` or `null` `variableBlockSize` means `false`, requiring exactly `blockSize` samples. Variable mode allows shorter blocks, with possible buffering delay, but rejects larger blocks. Unsupported configurations throw an SDK error. Initialization allocates memory. The streaming SDK accepts supported rates from 8,000 through 192,000 Hz. Call before `process`.

<span id="node-vad-process" />

### `Vad.process`

```typescript theme={null}
process(audio: Float32Array): void
```

Reads mono normalized `Float32Array` samples without modifying the caller's input. The native VAD copies the samples into its processing buffer. Returns `void`; read the updated prediction through `getContext`. Input length must match the initialized block contract. Throws before initialization, for a mismatch, after disposal or when processing is disallowed. Do not concurrently modify a shared input buffer.

<span id="node-vad-getcontext" />

### `Vad.getContext`

```typescript theme={null}
getContext(): VadContext
```

Returns an independent handle to this VAD's shared prediction and control state. Throws after disposal of the VAD object.

<span id="node-vad-terminatesession" />

### `Vad.terminateSession`

```typescript theme={null}
terminateSession(): void
```

Requests termination of the associated session. Once termination is handled, further processing is disallowed. This does not release the native object; still call `dispose()`. Completion may involve asynchronous session handling when another session remains active. Do not use it as a flush operation. Runs synchronously and may block.

<span id="node-vadasync" />

## `VadAsync`

Dedicated VAD through Node's shared libuv worker pool. Construction and disposal are synchronous. Await initialization and each processing call in stream order. Concurrent calls on one instance share a lock but have no guaranteed submission order. Use separate instances for independent streams.

<span id="node-vadasync-constructor" />

### `VadAsync.constructor`

```typescript theme={null}
constructor(model: Model, licenseKey: string, otelConfig?: OtelConfig | undefined | null)
```

`model` must be a live model handle of the required type. `licenseKey` is the SDK credential string; see [authentication](/models/get-started/authenticate-apps). Construction is synchronous and can throw for an invalid key, a disposed model or a model-type mismatch. Omitted or `null` `otelConfig` uses environment settings; otherwise pass an [OtelConfig](/reference/sdk/api/node/models-and-config#node-otelconfig) object. There is no automatic initialization.

<span id="node-vadasync-dispose" />

### `VadAsync.dispose`

```typescript theme={null}
dispose(): void
```

Synchronous and idempotent. Can block while a worker holds the native lock. Invalidates both the original object and any `withConfig` handle. Work that acquires the lock after disposal rejects. Await pending operations before disposing.

<span id="node-vadasync-withconfig" />

### `VadAsync.withConfig`

```typescript theme={null}
withConfig(sampleRate: number, blockSize: number, variableBlockSize?: boolean | undefined | null): Promise<VadAsync>
```

`sampleRate` is a whole-number rate in Hz; `blockSize` is a positive whole-number mono sample count. Query `model.getOptimalBlockSize(sampleRate)` for the preferred size. Omitted, `undefined` or `null` `variableBlockSize` means `false`, requiring exactly `blockSize` samples. Variable mode allows shorter blocks, with possible buffering delay, but rejects larger blocks. Unsupported configurations reject the promise with an SDK error. Initialization allocates memory. Initializes on a worker and resolves to another handle sharing the same native VAD. Disposing either handle invalidates both. Keep the original object available for cleanup if initialization rejects.

<span id="node-vadasync-initialize" />

### `VadAsync.initialize`

```typescript theme={null}
initialize(sampleRate: number, blockSize: number, variableBlockSize?: boolean | undefined | null): Promise<void>
```

`sampleRate` is a whole-number rate in Hz; `blockSize` is a positive whole-number mono sample count. Query `model.getOptimalBlockSize(sampleRate)` for the preferred size. Omitted, `undefined` or `null` `variableBlockSize` means `false`, requiring exactly `blockSize` samples. Variable mode allows shorter blocks, with possible buffering delay, but rejects larger blocks. Unsupported configurations reject the promise with an SDK error. Initialization allocates memory. Runs on a libuv worker. Await the promise before processing; initialization errors reject it.

<span id="node-vadasync-process" />

### `VadAsync.process`

```typescript theme={null}
process(audio: Float32Array): Promise<Float32Array<ArrayBuffer>>
```

Copies `audio` on the JavaScript thread before queuing work. Resolves to a new `Float32Array<ArrayBuffer>` containing the original samples, not enhanced audio or VAD probabilities. The original input is unchanged. Read predictions from `VadContext` after awaiting the call. Format and block constraints match `Vad.process`; native failures reject.

<span id="node-vadasync-getcontext" />

### `VadAsync.getContext`

```typescript theme={null}
getContext(): Promise<VadContext>
```

Resolves to a `VadContext` after worker access to the instance lock. The returned context's methods are synchronous. Rejects if the VAD was disposed before the worker acquired it.

<span id="node-vadasync-terminatesession" />

### `VadAsync.terminateSession`

```typescript theme={null}
terminateSession(): Promise<void>
```

Requests termination of the associated session. Once termination is handled, further processing is disallowed. This does not release the native object; still call `dispose()`. Completion may involve asynchronous session handling when another session remains active. Do not use it as a flush operation. Runs on a libuv worker; await it before disposal.

<span id="node-vadcontext" />

## `VadContext`

Read predictions and control a `Vad` or `VadAsync`. Obtain it through the corresponding `getContext()` method; there is no public constructor or `dispose()`. All methods on this context are synchronous, including a context obtained asynchronously. The handle survives disposal of the VAD, but its prediction stops updating.

<span id="node-vadcontext-setparameter" />

### `VadContext.setParameter`

```typescript theme={null}
setParameter(parameter: VadParameter, value: number): void
```

Sets `parameter` to `value`, converted to a 32-bit float. Throws for an unknown enum value, an out-of-range value or a non-finite value. Timing controls are seconds; see `VadParameter` below.

<span id="node-vadcontext-getparameter" />

### `VadContext.getParameter`

```typescript theme={null}
getParameter(parameter: VadParameter): number
```

Returns the current stored 32-bit float value widened to a JavaScript number. The effective detector timing is frame-quantized; do not treat this readback as an observed speech-boundary time. Unknown parameters throw.

<span id="node-vadcontext-isspeechdetected" />

### `VadContext.isSpeechDetected`

```typescript theme={null}
isSpeechDetected(): boolean
```

Returns the latest boolean decision after sensitivity and speech-timing controls. The result stops changing when no new audio is processed. It lags the corresponding input by `getPredictionDelay()` samples.

<span id="node-vadcontext-getrawvadprobability" />

### `VadContext.getRawVadProbability`

```typescript theme={null}
getRawVadProbability(): number
```

Returns the latest model speech probability from 0 to 1 before sensitivity thresholding, speech hold and minimum duration. The same prediction delay applies. This is not a guarantee that speech is present.

<span id="node-vadcontext-getpredictiondelay" />

### `VadContext.getPredictionDelay`

```typescript theme={null}
getPredictionDelay(): number
```

Returns prediction delay in samples at the configured input rate, including input buffering and model processing. Convert with `delaySamples * 1000 / sampleRate`. It is separate from enhancement audio delay: VAD does not delay or modify the caller's samples.

<span id="node-vadcontext-reset" />

### `VadContext.reset`

```typescript theme={null}
reset(): void
```

Clears the published decision and probability immediately and requests processing-state reset for subsequent audio. Preserves initialization. Reset before unrelated audio or after a discontinuity to prevent stale speech decisions.

<span id="node-vadcontext-updatebearertoken" />

### `VadContext.updateBearerToken`

```typescript theme={null}
updateBearerToken(token: string): void
```

`token` replaces a bearer token on a JWT-authenticated session. Both the original credential and replacement must be JWT-form licenses. A synchronous failure preserves the previous token. Return without error confirms local format acceptance, not backend acceptance; subsequent reporting can reject the token and eventually disable work. Obtain a valid replacement to recover. This operation allocates and takes a lock; keep it outside audio callbacks. See [authentication](/models/get-started/authenticate-apps).

<span id="node-vadparameter" />

## `VadParameter`

Exported numeric enum used by `VadContext`. All defaults come from the loaded model; read them with `getParameter`. Timing values are seconds. The detector operates on model frames, so effective timing is quantized to frame boundaries. The stored parameter is a 32-bit float, not a measurement of the resulting decision delay.

<span id="node-vadparameter-speechholdduration" />

### `VadParameter.SpeechHoldDuration`

```typescript theme={null}
SpeechHoldDuration = 0
```

Numeric enum value `0`. Duration in seconds, from 0 through 300 times the model window length. Controls how recent speech sustains a positive decision when the current probability is at or below the threshold: speech is reported when at least half of the frames in the lookback window (twice the hold duration) contain speech. When the current probability is above the threshold, the consecutive-frame rule set by `MinimumSpeechDuration` applies instead. Effective timing is rounded to model frames. Default is model-specific.

<span id="node-vadparameter-sensitivity" />

### `VadParameter.Sensitivity`

```typescript theme={null}
Sensitivity = 1
```

Numeric enum value `1`. Probability threshold from 0 to 1. A probability above this value counts as speech; higher values require stronger evidence. Default is model-specific.

<span id="node-vadparameter-minimumspeechduration" />

### `VadParameter.MinimumSpeechDuration`

```typescript theme={null}
MinimumSpeechDuration = 2
```

Numeric enum value `2`. Duration in seconds from 0 to 1. Controls the speech duration required before a positive decision. Effective timing is rounded to model frames. Default is model-specific.

## Example

With the pinned package installed, set `AIC_SDK_LICENSE` and run `node detect-block.cjs path/to/vad.aicmodel`. The object printed contains a decision, probability, prediction delay and model sensitivity. One silent block does not measure detection quality. Feed representative speech and pauses in sequence to evaluate decisions.

```javascript detect-block.cjs theme={null}
const { Model, Vad, VadParameter } = require('@ai-coustics/aic-sdk');

const key = process.env.AIC_SDK_LICENSE;
const modelPath = process.argv[2];
if (!key || !modelPath) throw new Error('Set AIC_SDK_LICENSE and pass a dedicated VAD model path');
const model = Model.fromFile(modelPath);
let vad;
try {
  vad = new Vad(model, key);
  const rate = model.getOptimalSampleRate();
  const size = model.getOptimalBlockSize(rate);
  vad.initialize(rate, size);
  const context = vad.getContext();
  const input = new Float32Array(size);
  vad.process(input);
  console.log({
    speech: context.isSpeechDetected(),
    probability: context.getRawVadProbability(),
    delaySamples: context.getPredictionDelay(),
    sensitivity: context.getParameter(VadParameter.Sensitivity),
  });
} finally {
  if (vad) vad.dispose();
  model.dispose();
}
```

## Related

[Node.js API index](/reference/sdk/api/node/index) · [Errors and recovery](/reference/sdk/api/node/errors) · [Stream lifecycle](/reference/concepts/streams-and-state).
