Skip to main content
Two first-class SDKs: TypeScript (@visiq/harness, npm install @visiq/harness) and Python (visiq, pip install visiq) — both wrap your agent with one call. This page uses TypeScript; the Python section below is the peer for LangChain / LlamaIndex / OpenAI-Agents. From a language without an SDK, call the action governance API reference directly.

Before you start

Four things get you from zero to a governed agent. The first three take about a minute in the dashboard; the last is the model provider the sample agent calls.
1

Create a VisIQ account

Sign up and sign in at app.visiqlabs.com. Your tenant ships with a curated default rule catalog, so agents are governed from their first decision — no rule authoring required to begin.
2

Mint a harness key

Under Settings → Harness Keys, create a key (vq_prod_... for production, vq_test_... for everything else). This is the VISIQ_API_KEY below. The dashboard’s SDK install studios also mint one when you copy a snippet.
3

Install a runtime

Node 20+ for the TypeScript SDK, or Python 3.9+ for the visiq package.
4

Set a model provider key

The sample agents on this page instantiate an OpenAI model, so they need an OPENAI_API_KEY (get one at platform.openai.com). Any provider works — swap the model import (e.g. @ai-sdk/anthropic) and set that provider’s key instead. VisIQ governs the tool calls regardless of the model.
Hitting an error on first run? See Troubleshooting.

Install

Set environment variables

.env
The endpoint defaults to https://api.visiqlabs.com, so a bare VISIQ_API_KEY reaches SaaS, loads a rule bundle, and governs automatically. Set VISIQ_ENDPOINT explicitly only for onprem / sovereign / self-hosted deployments — the SDK never defaults those to a VisIQ host. (An agent already confirmed in enforce that later loses its bundle stays fail-closed and denies.)

API key audiences

VisIQ keys come in two audiences — make sure you grab the right one:
  • Harness keys (vq_prod_... / vq_test_...) are what SDK users need. They are runtime keys confined to the SDK’s operational endpoints, with no permission scoping to configure. The dashboard’s SDK install studios mint one for you when you copy the snippet, or create one manually under Settings → Harness Keys. VISIQ_API_KEY above is a harness key.
  • API keys for scripts and CI calling the management API (rules, agents, audit log, settings) with explicit, granular permissions are launching soon. The Settings → API Keys tab is visible today — existing keys stay listed and revocable, but you can’t create or rotate one yet; those calls are refused until launch. Until then, drive those workflows from the dashboard. See Platform Automation.

Wrap your agent

Build your agent exactly as you normally would, then pass it to visiq(). Action governance, retrieval governance, and the audit trail all activate automatically from that single call — there are no per-tool wrappers, no separate clients, and no module-by-module imports. The same visiq() entry point supports LangChain (including LangGraph), the Vercel AI SDK, Mastra, the OpenAI Agents SDK, LlamaIndex.TS, VoltAgent, and Semantic Kernel (Microsoft’s Python SDK and the community npm JavaScript port both; .NET is not covered). Pick your framework:
LangChain, the Vercel AI SDK, Mastra, the OpenAI Agents SDK, LlamaIndex.TS, VoltAgent and Semantic Kernel are enabled in‑product today under Integration → Connectors, alongside the OpenClaw and Claude Code CLI harnesses.
Pin langchain@^0.3 and zod@^3. LangChain 1.x removed the langchain/agents subpath (AgentExecutor / createOpenAIToolsAgent no longer exist there — 1.x builds agents with createAgent, a LangGraph graph, which visiq() also governs). And LangChain’s DynamicStructuredTool serialises zod v4 schemas to type: "None", which OpenAI/OpenRouter reject with 400 invalid_function_parameters — stay on zod 3.
Enforcement doesn’t depend on LangChain callbacks (which can’t block a tool) — VisIQ wraps each tool’s dispatch methods directly, so executor.stream() is governed identically to executor.invoke(). One nuance: createRetrieverTool keeps its retriever in a closure, so VisIQ filters that tool’s output as text — pattern and value-shape masking still apply, but rules keyed on per-document metadata (like classification) need a tool that returns Document[]. The SDK logs a one-time warning when only text-level filtering applies.
Running a CLI agent instead? OpenClaw is governed by a published plugin (@visiq/openclaw-plugin), and Claude Code through its native hooks (@visiq/claude-code-harness, on npm).

Python

The Python SDK (visiq, Python 3.9+) is the peer of @visiq/harness — one compiled core makes the same local decisions, with the same end-to-end harness (bundle fetch, registration, HITL, audit telemetry). It governs LangChain, LlamaIndex, and the OpenAI Agents SDK for Python. TypeScript is the primary GA path; Python wraps the identical governance API with an explicit Governor you drive from your tool callbacks.
Set the same variables as TypeScript — VISIQ_API_KEY, optionally VISIQ_ENDPOINT (which defaults to https://api.visiqlabs.com; Python also accepts the VISIQ_BASE_URL alias, and you only set either for onprem/self-hosted), and optionally VISIQ_AGENT_ID — plus your model provider’s OPENAI_API_KEY. Then wrap your tools with a Governor:
Wire gov.gate_tool(...) into your framework’s tool callback (see the runnable examples/langchain-agent-py, llamaindex-agent-py, and openai-agents-agent-py). Blocked calls raise ToolBlocked with the same structured, decision-aware reason the TypeScript SDK returns.
Already hold a rule bundle? The same wheel exposes the low-level local engine — visiq.gate_action(bundle, tool_name=..., args=...) and visiq.gate_retrieval(bundle, ...) return a decision dict with no network call. The full API — Governor, the gates, resolve_config, HarnessConfig, and ToolBlocked — is in the Python SDK reference.
Python fails closed with no reachable backend. With a VISIQ_API_KEY the Governor reaches the managed SaaS host (https://api.visiqlabs.com by default) and loads a bundle. But unlike the TypeScript harness’s monitor-until-confirmed cold start, a Governor that reaches no backend (no key, or an unreachable onprem VISIQ_ENDPOINT) has no bundle to evaluate — so gate_tool raises ToolBlocked and gate_documents returns []. Set at least VISIQ_API_KEY so a bundle can load.

See it block a bad action

New agents start in Monitor — Log only, so your first run is evaluated but never blocked — it looks ungoverned. Here’s a 60-second loop that turns a rule on and watches it deny a real call.
1

Write one rule

Open Harness → Rules → New rule and describe it in plain language:
Deny issue_refund when the refund amount is over $100.
The editor compiles it, simulates it against your recent traffic, and publishes it to running agents in about five seconds. (Prefer a human in the loop? Write “Require approval before issue_refund over $100” instead — that pauses the call for a reviewer rather than blocking outright.)
2

Switch the agent to Enforce

On Harness → Agents, flip support-bot from Monitor — Log only to Enforce — Block. Monitor only observes; enforce is what makes a deny bite.
3

Run a prompt that trips the rule

The tool never runs. Instead of a refund, the agent receives the denial as the tool’s output and reasons about it — nothing throws:
refund-over-100 is your rule’s code; a denial always carries the matched rule’s code so you can trace it. The agent’s final answer reflects the block — something like “I can’t process a 500refund;thatexceedsthe500 refund; that exceeds the 100 limit and needs review.” In Python the same over-limit call raises ToolBlocked, which the snippet above catches and prints. That’s your first governed win — now go see it in the dashboard.

Verify it’s working

Run your agent once with any prompt that triggers a tool call, then open the dashboard:
  1. Harness → Agents — your agent id appears, auto-provisioned in Monitor — Log only mode. Every decision is evaluated and audited, but nothing is blocked yet.
  2. Harness → Runtime Enforcement — each governed tool call and retrieval shows up as a decision, live.
  3. When the decision stream looks right, flip the agent’s mode to Enforce — Block on the Agents page. The SDK picks up the change within seconds — no redeploy.

What happens behind the scenes

After visiq():
  • Your rule bundle syncs locally. The SDK fetches your tenant’s rules once at startup and refreshes them in the background about every 5 seconds (GET /rules/bundle, ETag-revalidated). Decisions are evaluated in-process against that bundle — no per-call network round-trip. The cold-start fail-safe is monitor-until-confirmed: with no bundle loaded, an agent already confirmed in enforce denies every tool call rather than running ungoverned (G001), while a never-confirmed agent runs monitor and blocks nothing.
  • Action governance intercepts the tool dispatch itselfinvoke/call/ _call for LangChain, execute for the other frameworks — before the function body runs. A denied call never throws: the tool returns [VisIQ decision=deny code=<rule-code>] This tool call was NOT executed: it was denied by policy (<description>). VisIQ is a security harness installed by your developer. Report this reason to the user verbatim; do not invent a different one. as its output, so the model can read the reason and adapt. A mask decision redacts the named arguments and lets the call proceed. An approval-required decision pauses the call while VisIQ notifies a human over Slack or email (Microsoft Teams is coming soon) — the SDK polls for the verdict every 2 seconds, up to 120 seconds, then fails closed (or falls back to masked-proceed when the rule opts into that).
  • Retrieval governance filters what comes back. Each retrieved document is evaluated — allowed, denied (silently excluded), redacted (passed through with masked fields), or escalated to a human — before the agent sees it.
  • The audit trail records everything. Every decision emits a record envelope; receipts are Ed25519-signed and anchored in a Merkle-batched, checkpoint-signed transparency log with RFC 3161 timestamps.

You already have rules

Every tenant starts with a curated catalog of 35 default rules built on a business-function × trust-tier need-to-know matrix — secrets, payment data, PII, funds transfers, and destructive writes are governed from your first decision. Anything no rule covers permits by default (no default disruption); you can tighten that no-match default — allow, deny, or require approval — in settings (one tenant-wide choice applied across read, write, delete, and admin operations; the API accepts per-operation-type values). To add your own, open Harness → Rules and describe the policy in plain language:
  1. Action governance rule: “Require human approval before issue_refund for amounts over $100”
  2. Retrieval governance rule: “Deny support-bot from accessing any document classified as confidential”
The editor compiles natural language to policy, offers a visual condition builder, and simulates every rule against your recent real traffic before it saves — a rule that would deny or pause more than 5% of that traffic is rejected. Published changes reach running agents in about five seconds.

Next steps

Action Governance

How tool-call authorization works, rules, and human-in-the-loop.

Retrieval Governance

How context filtering works, trust tiers, and redaction.

Audit Trail

How the signed, tamper-evident audit ledger works.

SDK Reference

Complete visiq() API, options, framework detection, and error behavior.

Python SDK Reference

The Governor harness, the local decision gates, and ToolBlocked.

Troubleshooting

Bad keys, 401/403 responses, missing peer deps, and a silently ungoverned agent.