Quickstart
Connect your first agent and see governed activity in a few minutes.
Veragent is a vendor-neutral control plane for AI agents — you send your agent's activity to Veragent, and you get audit trails, policy enforcement, and compliance evidence over it. The SDKs are dependency-free and work with any framework. Here's the whole flow end to end.
1. Install the SDK
Pick your language — the wire format is identical, so you can mix agents across both.
Python
pip install veragentNode
npm install veragent2. Set your API key
Create an agent API key in your dashboard (Agents → API keys), then expose it to your environment. Keys are scoped to your organisation and never leave it.
macOS / Linux
export VERAGENT_API_KEY="vak_your_key_here"Windows (PowerShell)
$env:VERAGENT_API_KEY = "vak_your_key_here"3. Send your first event
Create a client and record an action. The SDK reads VERAGENT_API_KEY from the environment automatically, and tracking is non-blocking — it never slows or crashes your agent.
Python
from veragent import Veragent
va = Veragent(agent="my-agent")
va.track("answered question", event_type="tool_call", tool="search")Node
import { Veragent } from "veragent";
const va = new Veragent({ agent: "my-agent" });
va.track("answered question", { eventType: "tool_call", tool: "search" });4. See it in your dashboard
Open the audit log in your Veragent dashboard — your event appears within seconds, attributed to the agent you named. From there you can write policies, set alerts, and generate compliance evidence over the same activity.
Pre-action authorization
Tracking tells you what an agent did. Pre-action authorization lets an agent ask permission before a high-stakes action — and routes the call to a human when it matters. The agent calls authorize() before acting; your policies decide allow, deny, or escalate; an escalation pauses the agent and waits for an admin to approve or deny it in the dashboard. The agent only proceeds once it has a verdict.
This is the intervention half of oversight — the EU AI Act's Article 14 human-oversight expectation in practice: a real person can step in and stop a consequential action before it happens, not just read about it afterward.
Required — authorize() is inert until you turn enforcement on
By default authorize() does nothing: it returns allowed = true and makes no network call. That's deliberate — you can wire it through your codebase safely before you're ready to enforce. But until you construct the client with the enforcement flag, no decision is ever made and no escalation is ever raised.
Turn it on explicitly:
Python
va = Veragent(agent="payments-agent", enforcement_enabled=True)Node
const va = new Veragent({ agent: "payments-agent", enforcementEnabled: true });Make an action escalate
An authorize() call only escalates if a policy says so. On the Policies page, create a policy with an authorization effect of escalate matching the actions you want a human to sign off on. Allow and deny effects resolve instantly; escalate is what pauses the agent for a person.
Each escalating policy also has a fail mode — what happens if nobody answers in time, or Veragent can't be reached:
- fail_closedOn timeout or outage the request is denied. Use it for high-stakes, low-frequency actions — a wire transfer should never go through just because an approver was at lunch.
- fail_openOn timeout or outage the request is allowed. Use it for high-frequency actions where blocking the agent would do more harm than the occasional un-reviewed pass.
Mark sensitive permissions
On the Permissions page, turn on requires elevation for any permission sensitive enough that approving it should itself be a deliberate act. When an escalation carries an elevated permission, the admin must re-authenticate before their approval is accepted — so a logged-in session left open can't rubber-stamp a payment or an admin grant.
Approve in the dashboard
Escalated requests appear live on the Approvals page — and on the approvals indicator in the top bar — for admins, the moment an agent raises them. Each shows the agent, the action, the permission, the matching policy, and a countdown to its timeout. Approve or deny resolves it, and the waiting agent's next poll returns that verdict and it proceeds. Approving a request on an elevation-marked permission prompts for re-authentication first. Approval happens in the dashboard; the approver and their reason are written to the audit trail as oversight evidence.
Handle the decision
Authorization can say no — and an agent must be ready for it. A decision is allowed or not, and a not-allowed decision has a status worth distinguishing:
- deniedA real no — policy or a human refused the action. Don't do it.
- timed_outNobody answered in time; the policy's fail mode decided the outcome.
- errorVeragent couldn't be reached. Fall back to your own safe default.
The SDK READMEs cover the full decision object, timeouts, and context payloads — Python (PyPI) and Node (npm).
Failure semantics
What happens when things go wrong is part of the contract. Three layers fail differently, on purpose:
- Enforcement is off by defaultThe deliberate fail-open default: without the enforcement flag,
authorize()makes no network call and returnsallowed = true. Out of the box nothing is ever blocked — wire it in safely, then opt in. - Enforcement on + unreachable → fails safeWith enforcement on, if Veragent can't be reached the decision is
status: "error", allowed: false— never a fabricated "yes". If you honorallowed(the enforcing adapters do), the guarded action does not proceed. An outage is fail-closed at the SDK boundary. - Escalation timeout → the policy's fail mode decidesWhen a human doesn't answer in time, the matching policy's
fail_closed(deny) orfail_open(allow) setting resolves it, returned asstatus: "timed_out". This is the only place the fail-open / fail-closed choice lives, and it's per policy.
Unlike track(), which drops failures silently so it never slows your agent, authorize() failures are always legible — surfaced in the returned decision, never swallowed.
End to end
Construct with enforcement on, ask before the action, and branch on the verdict.
Python
from veragent import Veragent
# Enforcement ON — without this flag, authorize() is a no-op.
va = Veragent(agent="payments-agent", enforcement_enabled=True)
decision = va.authorize("Refund €420 to customer 8821", permission="PAYMENT")
if decision.allowed:
issue_refund()
else:
# denied (a real no) / timed_out (fail mode) / error (unreachable)
log.warning("refund not authorized: %s", decision.status)Node
import { Veragent } from "veragent";
// Enforcement ON — without this flag, authorize() is a no-op.
const va = new Veragent({ agent: "payments-agent", enforcementEnabled: true });
const decision = await va.authorize("Refund €420 to customer 8821", { permission: "PAYMENT" });
if (decision.allowed) {
await issueRefund();
} else {
// denied (a real no) / timed_out (fail mode) / error (unreachable)
console.warn(`refund not authorized: ${decision.status}`);
}Framework adapters
If you build on a framework, Veragent ships drop-in adapters so you don't have to instrument calls by hand. Install the matching extra (Python) or import the matching subpath (Node):
Python
- LangChain
pip install "veragent[langchain]" - OpenAI Agents
pip install "veragent[openai-agents]" - MCP
pip install "veragent[mcp]" - CrewAI
pip install "veragent[crewai]"
Node
- Vercel AI SDK
veragent/vercel-ai - MCP
veragent/mcp - LangChain.js
veragent/langchain
Copy-paste examples for each framework are in the integration guide inside the app.
Ready to start?
Create a free account to get your API key, or read how we handle your data on our Security & Trust page.