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

# Node.js SDK reference

> Every public class, function and method in promptguard-sdk 2.4.1, generated from the published package

> [!NOTE]
>
> Generated from **promptguard-sdk 2.4.1** as published on npm (sha256 `f33873379c9b…`). Signatures, parameters and descriptions are read from the package itself, so this page changes only when the pinned SDK version does. For a walkthrough, start with the [guide](https://docs.promptguard.co/guides/node-sdk.md).

```bash theme={"system"}
npm install promptguard-sdk@2.4.1
```

## `promptguard-sdk`

PromptGuard Node.js SDK

Drop-in security for AI applications.

**Option 1 - Auto-instrumentation (recommended)**
@example

```ts theme={"system"}
import { init } from 'promptguard-sdk';
init({ apiKey: 'pg_live_xxx' });
// All LLM calls are now secured automatically.
```

**Option 2 - Proxy mode**
@example

```ts theme={"system"}
import { PromptGuard } from 'promptguard-sdk';
const pg = new PromptGuard({ apiKey: 'pg_live_xxx' });
const response = await pg.chat.completions.create({ ... });
```

**Option 3 - Framework integrations**
@example

```ts theme={"system"}
import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
import { promptGuardMiddleware } from 'promptguard-sdk/integrations/vercel-ai';
```

### `detectedUnpatched`

Function · `import { detectedUnpatched } from "promptguard-sdk"` or `import { detectedUnpatched } from "promptguard-sdk/auto"`

```ts theme={"system"}
function detectedUnpatched(): string[]
```

### `getAppliedPatches`

Function · `import { getAppliedPatches } from "promptguard-sdk"` or `import { getAppliedPatches } from "promptguard-sdk/auto"`

```ts theme={"system"}
function getAppliedPatches(): string[]
```

Runtime canary: the names of the auto-instrumentation patches that were
actually applied by `init` (e.g. `["openai", "anthropic"]`).

Because patches attach to the CJS-resolved provider modules, an ESM app can
call `init()` successfully and still be unprotected (see the dual-package
hazard note on `init`). Assert on this at startup when you rely on
enforce mode:

```ts theme={"system"}
init({ apiKey: "pg_live_xxx" });
if (!getAppliedPatches().includes("openai")) {
  throw new Error("PromptGuard did not patch the openai SDK");
}
```

### `InitOptions`

Interface · `import { InitOptions } from "promptguard-sdk"` or `import { InitOptions } from "promptguard-sdk/auto"`

```ts theme={"system"}
interface InitOptions
```

**Fields**

* `apiKey?: string`
* `baseUrl?: string`
* `mode?: "enforce" | "monitor"` — `"enforce"` blocks violations, `"monitor"` logs only (default: `"enforce"`).
* `failOpen?: boolean` — Allow LLM calls when Guard API is unreachable (default: `true`).
* `scanResponses?: boolean` — Also scan LLM responses (default: `false`).
* `timeout?: number` — HTTP timeout in ms for Guard API calls (default: `10000`).
* `maxRetries?: number` — Retry attempts for transient Guard API failures (network errors and 429/5xx responses) before the `failOpen` policy governs. Default: `3`. Retries never change the eventual decision — see `GuardClientConfig`.
* `retryDelay?: number` — Base delay in ms between Guard API retries (exponential backoff). Default: `1000`.
* `logLevel?: LogLevel` — SDK log verbosity (default: `"warn"`). Set to `"silent"` to suppress all SDK logging, or `"info"`/`"debug"` for the init banner and more detail. NOTE: this sets the **process-global** SDK log level (shared with the framework integrations); the most recent setter wins.
* `silent?: boolean` — Convenience shorthand for `logLevel: "silent"`.

### `init`

Function · `import { init } from "promptguard-sdk"` or `import { init } from "promptguard-sdk/auto"`

```ts theme={"system"}
function init(options?: InitOptions): void
```

Initialise PromptGuard auto-instrumentation.

Patches the provider SDKs (`openai`, `@anthropic-ai/sdk`,
`@google/generative-ai`, `cohere-ai`, `@aws-sdk/client-bedrock-runtime`)
so every LLM call they make is scanned by the Guard API.

**Limitation — ESM apps (dual-package hazard):** patches are applied to the
module instances resolved via CommonJS `require()`. If your application runs
as native ESM (`"type": "module"` / `.mjs`) and the provider ships separate
ESM builds, your `import`ed module instances can be *different objects* from
the patched CJS ones — in that case auto-instrumentation silently protects
nothing. Use `getAppliedPatches` as a runtime canary to verify the
providers you use were actually patched, and prefer the ESM-safe
alternatives: the LangChain callback handler
(`promptguard-sdk/integrations/langchain`), the Vercel AI SDK middleware
(`promptguard-sdk/integrations/vercel-ai`), or explicit `GuardClient.scan()`
calls. See README "Limitations: ESM apps".

When zero patches could be applied, a warning is logged so a
misconfiguration never fails silently.

| Parameter | Type | Required |
| - | - | - |
| `options` | `InitOptions` | no |

### `instrumentationReport`

Function · `import { instrumentationReport } from "promptguard-sdk"` or `import { instrumentationReport } from "promptguard-sdk/auto"`

```ts theme={"system"}
function instrumentationReport(): {
    patched: string[];
    detectedUnpatched: string[];
    middleware: string[];
    adviceUrl: string;
}
```

What is and is not instrumented, as data rather than a log line.

A startup warning is only read by whoever is watching at startup. The same
facts in this form can be asserted in the caller's own CI:

```ts theme={"system"}
expect(instrumentationReport().detectedUnpatched).toEqual([])
```

which turns "we told you" into "you cannot ship without knowing".

### `shutdown`

Function · `import { shutdown } from "promptguard-sdk"` or `import { shutdown } from "promptguard-sdk/auto"`

```ts theme={"system"}
function shutdown(): void
```

### `ChatCompletionRequest`

Interface · `import { ChatCompletionRequest } from "promptguard-sdk"`

```ts theme={"system"}
interface ChatCompletionRequest
```

**Fields**

* `model: string`
* `messages: Message[]`
* `temperature?: number`
* `maxTokens?: number` — Maximum tokens to generate. Serialized to the wire as `max_tokens`.
* `[key: string]: unknown` — OpenAI-compatible escape hatch: any additional keys (e.g. `top_p`, `frequency_penalty`, `stop`, `tools`) are forwarded verbatim to the proxy. Because these keys are not type-checked, a misspelled parameter is silently passed through rather than flagged at compile time — double-check the spelling of options not listed above. (`stream: true` is the one key rejected: the client parses a single JSON response body, so it throws at runtime instead of forwarding.)

### `ChatCompletionResponse`

Interface · `import { ChatCompletionResponse } from "promptguard-sdk"`

```ts theme={"system"}
interface ChatCompletionResponse
```

**Fields**

* `id: string`
* `object: string`
* `created: number`
* `model: string`
* `choices: Array<{ index: number; message: Message; finish_reason: string; }>`
* `usage?: { prompt_tokens: number; completion_tokens: number; total_tokens: number; }`

### `Message`

Interface · `import { Message } from "promptguard-sdk"`

```ts theme={"system"}
interface Message
```

**Fields**

* `role: "system" | "user" | "assistant" | "tool" | "function"`
* `content: string`

### `PromptGuardConfig`

Interface · `import { PromptGuardConfig } from "promptguard-sdk"`

```ts theme={"system"}
interface PromptGuardConfig
```

PromptGuard proxy client — OpenAI-compatible API with built-in
security scanning, retry logic, and namespace helpers.

**Fields**

* `apiKey: string`
* `baseUrl?: string` — API base URL. Defaults to the public PromptGuard proxy (`https://api.promptguard.co/api/v1/proxy`) or `PROMPTGUARD_BASE_URL`. The `/proxy` suffix is appended automatically when missing.
* `timeout?: number` — HTTP timeout in milliseconds for each request attempt. Default: `30000`.
* `maxRetries?: number` — Number of retry attempts for transient failures (network errors and 429/5xx responses). Default: `3`. Set to `0` for strict at-most-once semantics. Negative values are clamped to `0`.
* `retryDelay?: number` — Base delay in ms between retries (exponential backoff). Default: `1000`.

### `RedactResult`

Interface · `import { RedactResult } from "promptguard-sdk"`

```ts theme={"system"}
interface RedactResult
```

**Fields**

* `original: string`
* `redacted: string`
* `piiFound: string[]`

### `RedTeamSummary`

Interface · `import { RedTeamSummary } from "promptguard-sdk"`

```ts theme={"system"}
interface RedTeamSummary
```

**Fields**

* `totalTests: number` — Normalized from the wire field `total_tests`.
* `blocked: number`
* `allowed: number`
* `blockRate: number` — Normalized from the wire field `block_rate`.
* `results: RedTeamTestResult[]`

### `RedTeamTestResult`

Interface · `import { RedTeamTestResult } from "promptguard-sdk"`

```ts theme={"system"}
interface RedTeamTestResult
```

**Fields**

* `testName: string` — Normalized from the wire field `test_name`.
* `prompt: string`
* `decision: string`
* `reason: string`
* `threatType?: string` — Normalized from the wire field `threat_type`.
* `confidence: number`
* `blocked: boolean`
* `details: Record<string, unknown>`

### `SecurityScanResult`

Interface · `import { SecurityScanResult } from "promptguard-sdk"`

```ts theme={"system"}
interface SecurityScanResult
```

**Fields**

* `blocked: boolean`
* `decision: "allow" | "block" | "redact"`
* `reason?: string`
* `threatType?: string`
* `confidence?: number`

### `ToolValidationResult`

Interface · `import { ToolValidationResult } from "promptguard-sdk"`

```ts theme={"system"}
interface ToolValidationResult
```

**Fields**

* `allowed: boolean`
* `riskScore: number` — Normalized from the wire field `risk_score`.
* `riskLevel: string` — Normalized from the wire field `risk_level`.
* `reason: string`
* `warnings: string[]`
* `blockedReasons: string[]` — Normalized from the wire field `blocked_reasons`.

### `PromptGuard`

Class · `import { PromptGuard } from "promptguard-sdk"`

```ts theme={"system"}
class PromptGuard
```

**Properties**

* `chat: Chat`
* `security: Security`
* `agent: Agent`
* `redteam: RedTeam`
* `get baseUrl(): string` — The base URL requests actually go to, after normalization.

#### `new PromptGuard(...)`

```ts theme={"system"}
constructor(config: PromptGuardConfig)
```

| Parameter | Type | Required |
| - | - | - |
| `config` | `PromptGuardConfig` | yes |

#### `PromptGuard.request`

```ts theme={"system"}
request<T>(method: string, path: string, body?: unknown): Promise<T>
```

| Parameter | Type | Required |
| - | - | - |
| `method` | `string` | yes |
| `path` | `string` | yes |
| `body` | `unknown` | no |

### `PromptGuard.chat`

Reached as `PromptGuard.chat` on an instance (a `Chat`; not constructed directly).

```ts theme={"system"}
class Chat
```

**Properties**

* `completions: ChatCompletions`

### `PromptGuard.chat.completions`

Reached as `PromptGuard.chat.completions` on an instance (a `ChatCompletions`; not constructed directly).

```ts theme={"system"}
class ChatCompletions
```

#### `PromptGuard.chat.completions.create`

```ts theme={"system"}
create(params: ChatCompletionRequest): Promise<ChatCompletionResponse>
```

| Parameter | Type | Required |
| - | - | - |
| `params` | `ChatCompletionRequest` | yes |

### `PromptGuard.security`

Reached as `PromptGuard.security` on an instance (a `Security`; not constructed directly).

```ts theme={"system"}
class Security
```

#### `PromptGuard.security.scan`

```ts theme={"system"}
scan(content: string, type?: "prompt" | "response"): Promise<SecurityScanResult>
```

| Parameter | Type | Required |
| - | - | - |
| `content` | `string` | yes |
| `type` | `"prompt" \| "response"` | no |

#### `PromptGuard.security.redact`

```ts theme={"system"}
redact(content: string, piiTypes?: string[]): Promise<RedactResult>
```

| Parameter | Type | Required |
| - | - | - |
| `content` | `string` | yes |
| `piiTypes` | `string[]` | no |

### `PromptGuard.agent`

Reached as `PromptGuard.agent` on an instance (a `Agent`; not constructed directly).

```ts theme={"system"}
class Agent
```

#### `PromptGuard.agent.validateTool`

```ts theme={"system"}
validateTool(agentId: string, toolName: string, args: Record<string, unknown>, sessionId?: string): Promise<ToolValidationResult>
```

| Parameter | Type | Required |
| - | - | - |
| `agentId` | `string` | yes |
| `toolName` | `string` | yes |
| `args` | `Record<string, unknown>` | yes |
| `sessionId` | `string` | no |

#### `PromptGuard.agent.stats`

```ts theme={"system"}
stats(agentId: string): Promise<Record<string, unknown>>
```

| Parameter | Type | Required |
| - | - | - |
| `agentId` | `string` | yes |

### `PromptGuard.redteam`

Reached as `PromptGuard.redteam` on an instance (a `RedTeam`; not constructed directly).

```ts theme={"system"}
class RedTeam
```

Run the adversarial corpus against your own policy configuration.

Every method here used to target `/internal/redteam`, which requires
platform-admin auth -- so all of them returned 401 for every customer who
called them. The customer-facing plane is `/api/v1/security-testing`,
reachable with an ordinary API key carrying the `proxy` scope.

`runAutonomous` and `intelligenceStats` were removed rather than repointed:
the autonomous mutation loop is a cost-attack surface and stays back-office,
and `/intelligence/stats` exists on no plane at all (a 404 even for admins).

#### `PromptGuard.redteam.listTests`

```ts theme={"system"}
listTests(): Promise<{
    total: number;
    tests: Array<Record<string, unknown>>;
}>
```

#### `PromptGuard.redteam.runTest`

```ts theme={"system"}
runTest(testName: string, targetPreset?: string): Promise<RedTeamTestResult>
```

| Parameter | Type | Required |
| - | - | - |
| `testName` | `string` | yes |
| `targetPreset` | `string` | no |

#### `PromptGuard.redteam.runAll`

```ts theme={"system"}
runAll(targetPreset?: string): Promise<RedTeamSummary>
```

| Parameter | Type | Required |
| - | - | - |
| `targetPreset` | `string` | no |

#### `PromptGuard.redteam.runCustom`

```ts theme={"system"}
runCustom(prompt: string, targetPreset?: string): Promise<RedTeamTestResult>
```

| Parameter | Type | Required |
| - | - | - |
| `prompt` | `string` | yes |
| `targetPreset` | `string` | no |

### `PromptGuardError`

Class · `import { PromptGuardError } from "promptguard-sdk"`

```ts theme={"system"}
class PromptGuardError extends Error
```

**Properties**

* `code: string` — Machine-readable error code. Server-forwarded codes pass through verbatim (their own casing). Codes minted by the SDK itself use lower\_snake\_case: `missing_api_key`, `streaming_not_supported`, `invalid_response_body`, `max_retries`, and the fallback `unknown`.
* `statusCode: number`
* `errorType?: string`
* `upgradeUrl?: string`
* `currentPlan?: string`
* `requestsUsed?: number`
* `requestsLimit?: number`

#### `new PromptGuardError(...)`

```ts theme={"system"}
constructor(message: string, code: string, statusCode: number, extra?: {
    type?: string;
    upgradeUrl?: string;
    currentPlan?: string;
    requestsUsed?: number;
    requestsLimit?: number;
})
```

| Parameter | Type | Required |
| - | - | - |
| `message` | `string` | yes |
| `code` | `string` | yes |
| `statusCode` | `number` | yes |
| `extra` | `{ type?: string; upgradeUrl?: string; currentPlan?: string; requestsUsed?: number; requestsLimit?: number; }` | no |

### `GuardApiError`

Class · `import { GuardApiError } from "promptguard-sdk"` or `import { GuardApiError } from "promptguard-sdk/guard"`

```ts theme={"system"}
class GuardApiError extends Error
```

**Properties**

* `readonly statusCode?: number`

#### `new GuardApiError(...)`

```ts theme={"system"}
constructor(message: string, statusCode?: number)
```

| Parameter | Type | Required |
| - | - | - |
| `message` | `string` | yes |
| `statusCode` | `number` | no |

#### `GuardApiError.safeDescription`

```ts theme={"system"}
safeDescription(): string
```

A content-free description safe to write to logs.

The `.message` of a `GuardApiError` may embed the raw Guard API
response body (see `GuardClient.scan`), which can echo prompt
content. Loggers must use this instead of `.message` so they never
leak prompt content, response bodies, or the API key.

### `GuardClient`

Class · `import { GuardClient } from "promptguard-sdk"` or `import { GuardClient } from "promptguard-sdk/guard"`

```ts theme={"system"}
class GuardClient
```

#### `new GuardClient(...)`

```ts theme={"system"}
constructor(config: GuardClientConfig)
```

| Parameter | Type | Required |
| - | - | - |
| `config` | `GuardClientConfig` | yes |

#### `GuardClient.scan`

```ts theme={"system"}
scan(messages: GuardMessage[], options?: ScanOptions): Promise<GuardDecision>
```

Scan messages via the Guard API.

Throws `GuardApiError` on network/API errors so the caller
can decide whether to fail open or closed.

Two call styles are supported:

```ts theme={"system"}
// Options object (preferred, matches the rest of the SDK):
await guard.scan(messages, { direction: "input", model: "gpt-5-nano" })
// Positional (back-compat):
await guard.scan(messages, "input", "gpt-5-nano")
```

| Parameter | Type | Required |
| - | - | - |
| `messages` | `GuardMessage[]` | yes |
| `options` | `ScanOptions` | no |

#### `GuardClient.scan`

```ts theme={"system"}
scan(messages: GuardMessage[], direction?: "input" | "output", model?: string, context?: GuardContext): Promise<GuardDecision>
```

Scan messages via the Guard API.

Throws `GuardApiError` on network/API errors so the caller
can decide whether to fail open or closed.

Two call styles are supported:

```ts theme={"system"}
// Options object (preferred, matches the rest of the SDK):
await guard.scan(messages, { direction: "input", model: "gpt-5-nano" })
// Positional (back-compat):
await guard.scan(messages, "input", "gpt-5-nano")
```

| Parameter | Type | Required |
| - | - | - |
| `messages` | `GuardMessage[]` | yes |
| `direction` | `"input" \| "output"` | no |
| `model` | `string` | no |
| `context` | `GuardContext` | no |

### `GuardClientConfig`

Interface · `import { GuardClientConfig } from "promptguard-sdk"` or `import { GuardClientConfig } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface GuardClientConfig
```

**Fields**

* `apiKey: string`
* `baseUrl?: string`
* `timeout?: number`
* `maxRetries?: number` — Number of retry attempts for transient Guard API failures (network errors and 429/5xx responses). Default: `3`. Set to `0` for strict at-most-once semantics. Retries never change the eventual decision — after they are exhausted a `GuardApiError` is thrown so the caller's `failOpen` policy governs, exactly as with no retries.
* `retryDelay?: number` — Base delay in ms between retries (exponential backoff). Default: `1000`.

### `GuardContext`

Interface · `import { GuardContext } from "promptguard-sdk"` or `import { GuardContext } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface GuardContext
```

**Fields**

* `framework?: string`
* `chainName?: string` — Chain/pipeline name (camelCase, preferred).
* `agentId?: string` — Agent identifier (camelCase, preferred).
* `sessionId?: string` — Session identifier (camelCase, preferred).
* `toolCalls?: Array<Record<string, unknown>>` — Tool-call records for this turn (camelCase, preferred).
* `metadata?: Record<string, unknown>`
* `chain_name?: string` — @deprecated snake\_case alias for `chainName`; kept for back-compat.
* `agent_id?: string` — @deprecated snake\_case alias for `agentId`; kept for back-compat.
* `session_id?: string` — @deprecated snake\_case alias for `sessionId`; kept for back-compat.
* `tool_calls?: Array<Record<string, unknown>>` — @deprecated snake\_case alias for `toolCalls`; kept for back-compat.

### `GuardContextWire`

Interface · `import { GuardContextWire } from "promptguard-sdk"` or `import { GuardContextWire } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface GuardContextWire
```

Wire-format context (snake\_case) sent in the request body.

**Fields**

* `framework?: string`
* `chain_name?: string`
* `agent_id?: string`
* `session_id?: string`
* `tool_calls?: Array<Record<string, unknown>>`
* `metadata?: Record<string, unknown>`

### `GuardDecision`

Class · `import { GuardDecision } from "promptguard-sdk"` or `import { GuardDecision } from "promptguard-sdk/guard"`

```ts theme={"system"}
class GuardDecision
```

**Properties**

* `readonly decision: string`
* `readonly eventId: string`
* `readonly confidence: number`
* `readonly threatType?: string`
* `readonly redactedMessages?: GuardMessage[]`
* `readonly threats: ThreatDetail[]`
* `readonly latencyMs: number`
* `get blocked(): boolean`
* `get redacted(): boolean`
* `get allowed(): boolean`

#### `new GuardDecision(...)`

```ts theme={"system"}
constructor(data: Partial<GuardResponseBody>)
```

@throws \{GuardApiError} when `data.decision` is missing or not one of
`allow` / `block` / `redact`. A malformed body must never silently
default to "allow" — surfacing it as a `GuardApiError` lets the
caller's explicit `failOpen` policy govern instead.

| Parameter | Type | Required |
| - | - | - |
| `data` | `Partial<GuardResponseBody>` | yes |

### `GuardMessage`

Interface · `import { GuardMessage } from "promptguard-sdk"` or `import { GuardMessage } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface GuardMessage
```

Guard client - calls the PromptGuard Guard API for content scanning.

Used internally by auto-instrumentation patches and framework
integrations.  Sends messages to POST /api/v1/guard and returns
the decision (allow / block / redact).

**Fields**

* `role: string`
* `content: string`

### `GuardRequestBody`

Interface · `import { GuardRequestBody } from "promptguard-sdk"` or `import { GuardRequestBody } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface GuardRequestBody
```

**Fields**

* `messages: GuardMessage[]`
* `direction: "input" | "output"`
* `model?: string`
* `context?: GuardContextWire`

### `GuardResponseBody`

Interface · `import { GuardResponseBody } from "promptguard-sdk"` or `import { GuardResponseBody } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface GuardResponseBody
```

**Fields**

* `decision: "allow" | "block" | "redact"`
* `event_id: string`
* `confidence: number`
* `threat_type?: string`
* `redacted_messages?: GuardMessage[]`
* `threats: ThreatDetail[]`
* `latency_ms: number`

### `PromptGuardBlockedError`

Class · `import { PromptGuardBlockedError } from "promptguard-sdk"` or `import { PromptGuardBlockedError } from "promptguard-sdk/guard"`

```ts theme={"system"}
class PromptGuardBlockedError extends Error
```

**Properties**

* `readonly decision: GuardDecision`

#### `new PromptGuardBlockedError(...)`

```ts theme={"system"}
constructor(decision: GuardDecision)
```

| Parameter | Type | Required |
| - | - | - |
| `decision` | `GuardDecision` | yes |

### `ScanOptions`

Interface · `import { ScanOptions } from "promptguard-sdk"` or `import { ScanOptions } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface ScanOptions
```

Options-object form for `GuardClient.scan`.

**Fields**

* `direction?: "input" | "output"`
* `model?: string`
* `context?: GuardContext`

### `ThreatDetail`

Interface · `import { ThreatDetail } from "promptguard-sdk"` or `import { ThreatDetail } from "promptguard-sdk/guard"`

```ts theme={"system"}
interface ThreatDetail
```

**Fields**

* `type: string`
* `confidence: number`
* `details: string`

### `PromptGuardCallbackHandler`

Class · `import { PromptGuardCallbackHandler } from "promptguard-sdk"` or `import { PromptGuardCallbackHandler } from "promptguard-sdk/integrations/langchain"`

```ts theme={"system"}
class PromptGuardCallbackHandler
```

LangChain callback handler that scans prompts and responses via the
PromptGuard Guard API.

**Redact decisions block in enforce mode:** LangChain callbacks observe
calls but cannot rewrite the inputs of the in-flight LLM call, so a
`redact` decision cannot be honored here. In enforce mode it is escalated
to a block (a `PromptGuardBlockedError` is thrown) rather than
silently sending the content the Guard API asked us to redact. If you need
actual redaction, use auto-instrumentation (`init()`) or explicit
`GuardClient.scan()` calls, which can rewrite the outgoing messages.

**Properties**

* `readonly name = "promptguard"`
* `readonly raiseError = true` — Tell LangChain's callback manager to re-throw errors from this handler.
* `readonly awaitHandlers = true` — Tell LangChain to await this handler before continuing.

#### `new PromptGuardCallbackHandler(...)`

```ts theme={"system"}
constructor(options: PromptGuardCallbackOptions)
```

| Parameter | Type | Required |
| - | - | - |
| `options` | `PromptGuardCallbackOptions` | yes |

#### `PromptGuardCallbackHandler.handleLLMStart`

```ts theme={"system"}
handleLLMStart(serialized: Record<string, unknown>, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>): Promise<void>
```

| Parameter | Type | Required |
| - | - | - |
| `serialized` | `Record<string, unknown>` | yes |
| `prompts` | `string[]` | yes |
| `runId` | `string` | yes |
| `parentRunId` | `string` | no |
| `_extraParams` | `Record<string, unknown>` | no |
| `tags` | `string[]` | no |
| `metadata` | `Record<string, unknown>` | no |

#### `PromptGuardCallbackHandler.handleChatModelStart`

```ts theme={"system"}
handleChatModelStart(serialized: Record<string, unknown>, messages: unknown[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>): Promise<void>
```

| Parameter | Type | Required |
| - | - | - |
| `serialized` | `Record<string, unknown>` | yes |
| `messages` | `unknown[][]` | yes |
| `runId` | `string` | yes |
| `parentRunId` | `string` | no |
| `_extraParams` | `Record<string, unknown>` | no |
| `tags` | `string[]` | no |
| `metadata` | `Record<string, unknown>` | no |

#### `PromptGuardCallbackHandler.handleLLMEnd`

```ts theme={"system"}
handleLLMEnd(output: unknown, runId: string): Promise<void>
```

| Parameter | Type | Required |
| - | - | - |
| `output` | `unknown` | yes |
| `runId` | `string` | yes |

#### `PromptGuardCallbackHandler.handleLLMError`

```ts theme={"system"}
handleLLMError(_error: Error, runId: string): void
```

| Parameter | Type | Required |
| - | - | - |
| `_error` | `Error` | yes |
| `runId` | `string` | yes |

#### `PromptGuardCallbackHandler.handleChainStart`

```ts theme={"system"}
handleChainStart(serialized: Record<string, unknown>, _inputs: Record<string, unknown>, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>): Promise<void>
```

| Parameter | Type | Required |
| - | - | - |
| `serialized` | `Record<string, unknown>` | yes |
| `_inputs` | `Record<string, unknown>` | yes |
| `runId` | `string` | yes |
| `parentRunId` | `string` | no |
| `tags` | `string[]` | no |
| `metadata` | `Record<string, unknown>` | no |

#### `PromptGuardCallbackHandler.handleChainEnd`

```ts theme={"system"}
handleChainEnd(_outputs: Record<string, unknown>, runId: string): void
```

| Parameter | Type | Required |
| - | - | - |
| `_outputs` | `Record<string, unknown>` | yes |
| `runId` | `string` | yes |

#### `PromptGuardCallbackHandler.handleChainError`

```ts theme={"system"}
handleChainError(_error: Error, runId: string): void
```

| Parameter | Type | Required |
| - | - | - |
| `_error` | `Error` | yes |
| `runId` | `string` | yes |

#### `PromptGuardCallbackHandler.handleToolStart`

```ts theme={"system"}
handleToolStart(serialized: Record<string, unknown>, input: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>): Promise<void>
```

| Parameter | Type | Required |
| - | - | - |
| `serialized` | `Record<string, unknown>` | yes |
| `input` | `string` | yes |
| `runId` | `string` | yes |
| `parentRunId` | `string` | no |
| `tags` | `string[]` | no |
| `metadata` | `Record<string, unknown>` | no |

#### `PromptGuardCallbackHandler.handleToolEnd`

```ts theme={"system"}
handleToolEnd(output: unknown, runId: string): Promise<void>
```

| Parameter | Type | Required |
| - | - | - |
| `output` | `unknown` | yes |
| `runId` | `string` | yes |

#### `PromptGuardCallbackHandler.handleToolError`

```ts theme={"system"}
handleToolError(_error: Error, runId: string): void
```

| Parameter | Type | Required |
| - | - | - |
| `_error` | `Error` | yes |
| `runId` | `string` | yes |

### `promptGuardMiddleware`

Function · `import { promptGuardMiddleware } from "promptguard-sdk"` or `import { promptGuardMiddleware } from "promptguard-sdk/integrations/vercel-ai"`

```ts theme={"system"}
function promptGuardMiddleware(options?: PromptGuardMiddlewareOptions): {
    specificationVersion: "v3";
    transformParams: <P extends object>({ params, model, }: {
        params: P;
        model?: ModelIdentity;
    }) => Promise<P>;
    wrapGenerate: (<R>({ doGenerate, params, model, }: {
        doGenerate: () => PromiseLike<R>;
        params?: object;
        model?: ModelIdentity;
    }) => Promise<R>) | undefined;
    wrapStream: (<R>({ doStream, params, model, }: {
        doStream: () => PromiseLike<R>;
        params?: object;
        model?: ModelIdentity;
    }) => Promise<R>) | undefined;
}
```

Create a Vercel AI SDK middleware that scans inputs/outputs via
the PromptGuard Guard API.

Returns an object conforming to the Vercel AI SDK `LanguageModelMiddleware`
interface (`transformParams`, plus `wrapGenerate` and `wrapStream` when
`scanResponses` is set). The hooks are generic over the call options and
results they pass through, so the object is assignable to the middleware
type of each supported `ai` major (checked by `tests/vercel-ai-types.test.ts`).

| Parameter | Type | Required |
| - | - | - |
| `options` | `PromptGuardMiddlewareOptions` | no |

### `promptguard`

Function · `import { promptguard } from "promptguard-sdk"` or `import { promptguard } from "promptguard-sdk/integrations/vercel-ai"`

```ts theme={"system"}
function promptguard<M extends LanguageModelLike>(model: M, options?: PromptGuardMiddlewareOptions): M
```

Wrap an AI SDK language model so every call it makes is scanned by
PromptGuard, exactly as `promptGuardMiddleware(options)` would scan it
under `wrapLanguageModel` — generated and streamed alike.

The wrapped model is the model it wraps in every other respect: its own
specification version, provider, model id, supported URLs and any other
property, so it is accepted wherever the original was and has the same
type. Options are the middleware's; the API key defaults to
`PROMPTGUARD_API_KEY`, and a missing one throws here rather than on the
first call.

```ts theme={"system"}
const model = promptguard(openai('gpt-5-nano'), { scanResponses: true });
const result = streamText({ model, prompt: 'Hello!' });
```

| Parameter | Type | Required |
| - | - | - |
| `model` | `M` | yes |
| `options` | `PromptGuardMiddlewareOptions` | no |

### `getLogLevel`

Function · `import { getLogLevel } from "promptguard-sdk"`

```ts theme={"system"}
function getLogLevel(): LogLevel
```

Get the current global SDK log level.

### `LogLevel`

Type · `import { LogLevel } from "promptguard-sdk"`

```ts theme={"system"}
type LogLevel = "debug" | "info" | "warn" | "error" | "silent"
```

Minimal namespaced, leveled logger for the PromptGuard SDK.

Node has no equivalent of Python's `logging` module, so this provides a
small, suppressible logger so the SDK does not write to stdout/stderr by
default. Mirrors the suppressibility of the Python SDK's `logging` usage.

Levels (most → least verbose): "debug" \< "info" \< "warn" \< "error" \< "silent".
Default level is "warn": warnings/errors surface, info/debug are suppressed.
Set verbosity via `setLogLevel` (or the `logLevel` / `silent` options
on `init()` / integration constructors).

NOTE: the log level is **process-global**, not per-instance. Passing
`logLevel` / `silent` to `init()`, `PromptGuardCallbackHandler`, or
`promptGuardMiddleware` mutates the shared level for the whole process —
the most recently constructed instance wins. If you need different
verbosity for different clients, call `setLogLevel` around the
code paths you care about instead.

### `setLogLevel`

Function · `import { setLogLevel } from "promptguard-sdk"`

```ts theme={"system"}
function setLogLevel(level: LogLevel): void
```

Set the global SDK log level.

| Parameter | Type | Required |
| - | - | - |
| `level` | `LogLevel` | yes |

### `CheckStatus`

Type · `import { CheckStatus } from "promptguard-sdk"`

```ts theme={"system"}
type CheckStatus = "pass" | "warn" | "fail"
```

### `VerifyCheck`

Interface · `import { VerifyCheck } from "promptguard-sdk"`

```ts theme={"system"}
interface VerifyCheck
```

**Fields**

* `name: string`
* `status: CheckStatus`
* `detail: string`

### `VerifyOptions`

Interface · `import { VerifyOptions } from "promptguard-sdk"`

```ts theme={"system"}
interface VerifyOptions
```

**Fields**

* `apiKey?: string`
* `baseUrl?: string`
* `timeout?: number` — Per-request timeout in milliseconds.
* `maxRetries?: number` — Retry attempts per probe. Defaults to `1`, not the client's `3`.
* `retryDelay?: number` — Backoff between retries, in milliseconds. Defaults to `250`.

### `VerifyReport`

Interface · `import { VerifyReport } from "promptguard-sdk"`

```ts theme={"system"}
interface VerifyReport
```

**Fields**

* `ok: boolean` — True when no check failed. Warnings do not clear it.
* `checks: VerifyCheck[]`
* `checksPassed: number`
* `checksFailed: number`
* `checksWarned: number`
* `instrumentation: ReturnType<typeof instrumentationReport>`
* `baseUrl: string` — The URL that was actually called, after base-URL normalization.
* `sdkVersion: string`

### `verify`

Function · `import { verify } from "promptguard-sdk"`

```ts theme={"system"}
function verify(options?: VerifyOptions): Promise<VerifyReport>
```

Run the integration checks and return what happened.

Credentials resolve exactly as they do everywhere else — explicit option,
then `PROMPTGUARD_API_KEY` / `PROMPTGUARD_BASE_URL` from the environment.

Never rejects for a failed check: a check that threw would be useless in the
place this is most needed, which is a CI step or a pre-flight script that
wants every problem at once rather than only the first. A missing API key is
the one exception — that is a caller error, not a finding, and it throws
`PromptGuardError` with code `missing_api_key` like the rest of the SDK.

A **warn** means the request worked but the answer was not what a protected
setup should give — an injection that came back allowed, or a PII sample with
nothing detected. That is a policy question rather than a broken integration,
which is why it does not clear `ok`; it is still the thing to look at before
trusting the setup.

| Parameter | Type | Required |
| - | - | - |
| `options` | `VerifyOptions` | no |

## `promptguard-sdk/auto`

Auto-instrumentation for PromptGuard (Node.js).

Call `init` once at application startup to automatically
secure **all** LLM calls made through popular SDKs - regardless of
which framework (LangChain.js, Vercel AI SDK, etc.) sits on top.

@example

```ts theme={"system"}
import { init } from 'promptguard-sdk/auto';

init({ apiKey: 'pg_live_xxx' });

// Everything below is now secured transparently.
import OpenAI from 'openai';
const client = new OpenAI();
await client.chat.completions.create({ ... }); // ← scanned by PromptGuard
```

### `getGuardClient`

Function · `import { getGuardClient } from "promptguard-sdk/auto"`

```ts theme={"system"}
function getGuardClient(): GuardClient | null
```

### `getMode`

Function · `import { getMode } from "promptguard-sdk/auto"`

```ts theme={"system"}
function getMode(): "enforce" | "monitor"
```

### `isFailOpen`

Function · `import { isFailOpen } from "promptguard-sdk/auto"`

```ts theme={"system"}
function isFailOpen(): boolean
```

### `shouldScanResponses`

Function · `import { shouldScanResponses } from "promptguard-sdk/auto"`

```ts theme={"system"}
function shouldScanResponses(): boolean
```

### `knownPatchNames`

Function · `import { knownPatchNames } from "promptguard-sdk/auto"`

```ts theme={"system"}
function knownPatchNames(): string[]
```

Every provider-patch name this SDK is capable of reporting in `patched`.

Not re-exported from `index.ts`: the package's public surface is unchanged,
and this mirrors the Python SDK's private `_known_patches()`. It exists so
the cross-SDK contract's `instrumentation_introspection` section can assert
that both SDKs name the same providers — they did not, until v1.6.0 of the
contract: this SDK reported `bedrock` while Python reported `boto3-bedrock`.

## `promptguard-sdk/guard`

Guard client - calls the PromptGuard Guard API for content scanning.

Used internally by auto-instrumentation patches and framework
integrations.  Sends messages to POST /api/v1/guard and returns
the decision (allow / block / redact).

### `serializeGuardContext`

Function · `import { serializeGuardContext } from "promptguard-sdk/guard"`

```ts theme={"system"}
function serializeGuardContext(context: GuardContext): GuardContextWire
```

Normalize a public `GuardContext` (camelCase, with deprecated
snake\_case aliases) into the snake\_case wire shape. camelCase fields win
over their deprecated snake\_case aliases; only defined fields are emitted so
the serialized body carries no camelCase keys and no explicit `undefined`s.

| Parameter | Type | Required |
| - | - | - |
| `context` | `GuardContext` | yes |

### `safeErrorLabel`

Function · `import { safeErrorLabel } from "promptguard-sdk/guard"`

```ts theme={"system"}
function safeErrorLabel(err: unknown): string
```

Return a log-safe description for an error caught on the fail-open path.

For a `GuardApiError` this emits only HTTP status + a static message
(never the response body or prompt content). Any other error type is a real
bug that the fail-open paths re-throw before reaching here, so we fall back
to a generic label rather than risk logging arbitrary contents.

| Parameter | Type | Required |
| - | - | - |
| `err` | `unknown` | yes |

## `promptguard-sdk/integrations/langchain`

LangChain.js integration - PromptGuardCallbackHandler.

Implements the LangChain BaseCallbackHandler interface to scan prompts
before LLM calls and responses after, with rich context about chains,
tools, and agent steps.

@example

```ts theme={"system"}
import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';

const handler = new PromptGuardCallbackHandler({ apiKey: 'pg_live_xxx' });

const llm = new ChatOpenAI({ callbacks: [handler] });
// or
await chain.invoke({ input: '...' }, { callbacks: [handler] });
```

Every scan names its Conversation in `session_id` with the call's own
thread id: the `thread_id` LangGraph puts in every callback's metadata, or a
`thread_id` / `session_id` / `conversation_id` set in `config.metadata`. A
call that names no thread sends no session id, unless the handler was given
a `sessionId` of its own.

### `PromptGuardCallbackOptions`

Interface · `import { PromptGuardCallbackOptions } from "promptguard-sdk/integrations/langchain"`

```ts theme={"system"}
interface PromptGuardCallbackOptions extends GuardClientConfig
```

**Fields**

* `mode?: "enforce" | "monitor"`
* `scanResponses?: boolean` — Also scan LLM/tool outputs (default: `false`, consistent with `init()` and the Vercel AI middleware). Enable explicitly if you want output scanning — every scan is a billable Guard API call.
* `failOpen?: boolean`
* `logLevel?: LogLevel` — SDK log verbosity (default: `"warn"`). Set to `"silent"` to suppress logs. NOTE: this sets the **process-global** SDK log level (shared with `init()` and other integrations); the most recently constructed instance wins.
* `silent?: boolean` — Convenience shorthand for `logLevel: "silent"`.
* `sessionId?: string` — The Conversation to name when a call carries no thread id of its own — for a handler that serves one conversation. A call's `thread_id` (or `session_id` / `conversation_id`) in its metadata always wins. Without either, no session id is sent.

## `promptguard-sdk/integrations/vercel-ai`

Vercel AI SDK integration for the `ai` package.

Two ways in, with the same scanning:

* `promptguard(model)` wraps a language model of ai 5, 6 or 7
  (specification v2, v3 or v4), and the wrapped model is used wherever the
  original was:

```ts theme={"system"}
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
import { promptguard } from 'promptguard-sdk/integrations/vercel-ai';

const model = promptguard(openai('gpt-5-nano'), { scanResponses: true });
const { text } = await generateText({ model, prompt: 'Hello!' });
```

* `promptGuardMiddleware(options)` is the same scanning as AI SDK
  middleware, for `wrapLanguageModel` — useful alongside other middleware,
  and the way in on ai 4:

```ts theme={"system"}
import { wrapLanguageModel } from 'ai';
import { promptGuardMiddleware } from 'promptguard-sdk/integrations/vercel-ai';

const model = wrapLanguageModel({
  model: openai('gpt-5-nano'),
  middleware: promptGuardMiddleware({ apiKey: 'pg_live_xxx' }),
});
```

With `scanResponses: true`, `streamText()` output is scanned too: in
enforce mode text is held until it has been scanned, a window
(`streamWindowChars`, default 1000 characters) at a time, and the complete
text is scanned before the stream finishes. See `vercel-ai-output.ts` for
the full behaviour and its guarantee.

Neither imports `ai`: the wrapper calls the middleware's hooks the way
`wrapLanguageModel` does, so it works with whichever `ai` the application
has (ai\@7 is ESM-only; this package is CommonJS) and loads without one.

### `PromptGuardMiddlewareOptions`

Interface · `import { PromptGuardMiddlewareOptions } from "promptguard-sdk/integrations/vercel-ai"`

```ts theme={"system"}
interface PromptGuardMiddlewareOptions extends Omit<GuardClientConfig, "apiKey">
```

**Fields**

* `apiKey?: string` — PromptGuard API key (default: the `PROMPTGUARD_API_KEY` environment variable).
* `mode?: "enforce" | "monitor"`
* `scanResponses?: boolean` — Scan the model's output as well as its input (default: `false`). Applies to `generateText()` and to `streamText()` alike.
* `failOpen?: boolean`
* `streamWindowChars?: number` — With `scanResponses` in enforce mode, how many new characters of streamed output are collected before the held text is scanned (default: `1000`; see `DEFAULT_STREAM_WINDOW_CHARS` for why). A smaller window delivers the first text sooner at the cost of more scans; `Infinity` holds the whole response for a single scan at the end.
* `logLevel?: LogLevel` — SDK log verbosity (default: `"warn"`). Set to `"silent"` to suppress logs. NOTE: this sets the **process-global** SDK log level (shared with `init()` and other integrations); the most recently constructed instance wins.
* `silent?: boolean` — Convenience shorthand for `logLevel: "silent"`.
* `sessionId?: string` — The Conversation to name when a call names none of its own. The AI SDK has no conversation id, so a call names one with `providerOptions: { promptguard: { sessionId } }` (`providerMetadata` on `ai@4`), which wins over this. Without either, no session id is sent.

### `LanguageModelLike`

Interface · `import { LanguageModelLike } from "promptguard-sdk/integrations/vercel-ai"`

```ts theme={"system"}
interface LanguageModelLike
```

What every AI SDK language model specification (V1 to V4) has in common,
which is all `promptguard()` relies on.

**Fields**

* `readonly specificationVersion: string`
* `readonly modelId: string`

#### `LanguageModelLike.doGenerate`

```ts theme={"system"}
doGenerate(options: never): PromiseLike<unknown>
```

| Parameter | Type | Required |
| - | - | - |
| `options` | `never` | yes |

#### `LanguageModelLike.doStream`

```ts theme={"system"}
doStream(options: never): PromiseLike<unknown>
```

| Parameter | Type | Required |
| - | - | - |
| `options` | `never` | yes |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.