Quick Start
Add cryptographic identity, signed receipts, and audit trails to your AI agents in under 10 minutes. This guide uses the official TypeScript SDK and works with any agent framework.
Option 1: Zero-Code Proxy (Fastest)
The fastest way to audit your AI agents. Point your existing AI tool at Viatoris instead of directly at OpenAI or Anthropic. No code changes beyond one URL. Every request creates a signed audit receipt automatically.
Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
api_key="sk-your-openai-key",
base_url="https://proxy.viatoris.ai/v1/openai/at_live_YOUR_KEY"
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Summarize Q3 sales"}],
)
print(resp.choices[0].message.content)Python (Anthropic SDK)
from anthropic import Anthropic
client = Anthropic(
api_key="sk-ant-your-key",
base_url="https://proxy.viatoris.ai/v1/anthropic/at_live_YOUR_KEY"
)
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
messages=[{"role": "user", "content": "Draft a reply to this support ticket"}],
)
print(resp.content[0].text)Node.js
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "sk-your-openai-key",
baseURL: "https://proxy.viatoris.ai/v1/openai/at_live_YOUR_KEY",
});
const resp = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Summarize Q3 sales" }],
});
console.log(resp.choices[0].message.content);Any of 25+ Supported Providers
Send the X-Upstream-URL header with any Viatoris-allowlisted provider to route your request there. Your provider key is forwarded untouched; the proxy writes the receipt.
client = OpenAI(
api_key="gsk_your_groq_key",
base_url="https://proxy.viatoris.ai/v1/openai/at_live_YOUR_KEY",
default_headers={"X-Upstream-URL": "https://api.groq.com/openai"},
)client = OpenAI(
api_key="your_mistral_key",
base_url="https://proxy.viatoris.ai/v1/openai/at_live_YOUR_KEY",
default_headers={"X-Upstream-URL": "https://api.mistral.ai"},
)client = OpenAI(
api_key="your_azure_key",
base_url="https://proxy.viatoris.ai/v1/openai/at_live_YOUR_KEY",
default_headers={"X-Upstream-URL": "https://your-resource.openai.azure.com"},
)Full allowlist: OpenAI, Anthropic, xAI, Mistral, Cohere, Groq, Cerebras, SambaNova, OpenRouter, Together, Fireworks, DeepInfra, Perplexity, DeepSeek, AI21, Replicate, HuggingFace, Novita, Anyscale, OctoAI, Nvidia NIM, Writer, Upstage, Google Gemini, Google Vertex AI, Azure OpenAI, Azure Cognitive Services, Databricks, Azure Databricks.
Self-Hosted LLMs
For Ollama, vLLM, LM Studio, TGI, or any OpenAI-compatible self-hosted server, addX-Allow-Private-Upstream: trueto opt in to private-network destinations.
client = OpenAI(
api_key="ollama",
base_url="https://proxy.viatoris.ai/v1/openai/at_live_YOUR_KEY",
default_headers={
"X-Upstream-URL": "http://localhost:11434",
"X-Allow-Private-Upstream": "true",
},
)
resp = client.chat.completions.create(
model="llama3.1",
messages=[{"role": "user", "content": "Explain edge inference"}],
)Business Context (Optional)
Tag any request with business context so compliance and audit views have something human-readable. All three headers are optional; auto-classification fills gaps when they are absent.
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Reset password for user 48291"}],
extra_headers={
"X-Action-Label": "password-reset",
"X-Action-Category": "security",
"X-Action-Description": "AI agent reset password for user 48291",
},
)What Gets Captured
Every proxied request creates one receipt with:
- Timestamp, duration, HTTP status code
- Provider name and endpoint (OpenAI, Groq, Anthropic, etc.)
- Model identifier and input / output token counts
- SHA-256 hashes of the request and response bodies (never the raw content)
- Auto-detected action label, category, and a 200-character description drawn from the last user message
- Any tool or function names the model invoked
- Customer-supplied X-Action-Label / Category / Description when present
Option 2: Developer SDK (More Control)
Install the SDK when you want agent-signed receipts (each agent holds its own Ed25519 key), fine-grained per-action metadata, or a setup that runs entirely inside your own process. The remaining sections walk through SDK setup.
1. Install the SDK
The SDK ships as @viatorisai/sdk on npm. Install it and you're ready to go.
npm install @viatorisai/sdk2. Sign up and get your API key
You need a Viatoris API key to call any authenticated endpoint. There are two ways to get one:
- Dashboard (recommended): Visit dashboard.viatoris.ai/signup, verify your email, then grab your API key from the Settings page.
- CLI: Initialize a new project and provision an org + key in one shot:
npx @viatorisai/cli initEither way, you'll end up with a key shaped like at_live_XXXX. Store it as an environment variable; never check it into source control.
3. Create an agent
Each agent gets its own W3C DID and Ed25519 key pair. The SDK generates the key pair locally. Only the public key is sent to Viatoris servers.
import { AgentTrust } from '@viatorisai/sdk';
const trust = new AgentTrust({
orgApiKey: process.env.VIATORIS_API_KEY,
});
const passport = await trust.createPassport({
agentId: 'scout-1',
controllerDid: 'did:web:acme.ai',
metadata: {
name: 'Scout',
description: 'Research agent that searches the web',
version: '1.0.0',
agentType: 'autonomous',
capabilities: ['web-search', 'summarization'],
},
});
console.log(passport.did);
// did:web:acme.ai:agents:scout-1
// IMPORTANT: passport.privateKeyJwk is only returned ONCE.
// Save it now (env var, secrets manager, KMS). There is no way to recover it later.
console.log(JSON.stringify(passport.privateKeyJwk));4. Sign and submit a receipt
A receipt is a tamper-proof, timestamped record of one agent action. The SDK's Signer handles canonical hashing, EdDSA signing, and submission for you.
import { AgentTrust } from '@viatorisai/sdk';
const trust = new AgentTrust({
orgApiKey: process.env.VIATORIS_API_KEY,
});
// Reconstruct the signer from the values you saved when you created the agent.
const signer = trust.createSigner({
did: process.env.AGENT_DID!,
keyId: process.env.AGENT_DID! + '#key-1',
privateKeyJwk: JSON.parse(process.env.AGENT_PRIVATE_KEY!),
passport: {},
});
const receipt = await signer.recordAction({
action: 'web-search',
capability: 'research',
inputs: { query: 'recent papers on AI safety' },
outputs: { results: 12, topResult: 'arxiv.org/abs/2024.xxxxx' },
result: 'success', // 'success' | 'failure' | 'partial' | 'disputed'
duration: 1240, // ms
});
console.log(receipt.id);
// 7f3a... (UUID)Inputs and outputs are hashed client-side before signing. Only the SHA-256 hash leaves your machine, so even Viatoris can't see the raw payload.
5. Verify any agent
Anyone can verify an agent's identity, controller, and status with no API key. Just hit the public verification endpoint:
// /v1/verify/:did is a public endpoint. No API key needed
const did = 'did:web:acme.ai:agents:scout-1';
const res = await fetch(
`https://api.viatoris.ai/v1/verify/${encodeURIComponent(did)}`
);
const verification = await res.json();
console.log(verification.status); // 'active' | 'revoked'
console.log(verification.passport); // full W3C DID document
console.log(verification.org); // controller org infoUse this endpoint anywhere you receive an agent-signed message (webhooks, marketplace listings, A2A protocols) to confirm the agent is real, current, and bound to a verified org.
6. Already have agents in production?
Viatoris is a trust layer that sits on top of whatever agent stack you already run: LangChain, CrewAI, AutoGen, custom orchestration, all of it. You don't rewrite anything. You just emit a receipt after each action you want to make auditable.
Option A: Wrap your existing tool calls
Drop a one-line wrapper around the actions you care about. The receipt submission is fire-and-forget, so it never adds latency to your agent loop.
async function searchWithReceipt(query: string) {
const start = Date.now();
const results = await myExistingSearchAgent(query); // your code, unchanged
// Fire-and-forget. Never blocks your agent
signer.recordAction({
action: 'web-search',
capability: 'research',
inputs: { query },
outputs: { count: results.length },
result: 'success',
duration: Date.now() - start,
}).catch((err) => console.error('receipt failed:', err));
return results;
}Option B: Express middleware
If your agent runs behind an HTTP API, attach a single middleware to receipt every response:
import express from 'express';
const app = express();
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
if (!req.path.startsWith('/agent/')) return;
signer.recordAction({
action: req.path.replace('/agent/', ''),
capability: 'api',
inputs: req.body,
outputs: { status: res.statusCode },
result: res.statusCode < 400 ? 'success' : 'failure',
duration: Date.now() - start,
}).catch(() => { /* never crash the response */ });
});
next();
});Option C: LangChain
The viatoris-langchain package ships a drop-in BaseCallbackHandler that emits a signed receipt for every tool call your LangChain agent makes. Pass it via callbacks=[handler] on any AgentExecutor.
pip install viatoris-langchain viatorisaifrom viatoris_langchain import ViatorisCallbackHandler
from langchain.agents import AgentExecutor
PRIVATE_KEY_JWK = {} # paste the JWK saved when you created the agent
handler = ViatorisCallbackHandler(
org_api_key="YOUR_API_KEY",
agent_did="YOUR_AGENT_DID",
private_key_jwk=PRIVATE_KEY_JWK,
key_id="YOUR_AGENT_DID#key-1",
)
# Add to any LangChain agent. Every tool call gets a signed receipt.
# Submission is fire-and-forget on a background thread.
agent = AgentExecutor(agent=..., tools=..., callbacks=[handler])
agent.invoke({"input": "Analyze Q3 sales data"})Option D: CrewAI
ViatorisCrewCallback is callable, so you pass an instance directly as step_callback on a Task or a Crew. Every step CrewAI emits produces a signed receipt.
pip install viatoris-crewai viatorisaifrom viatoris_crewai import ViatorisCrewCallback
from crewai import Agent, Task, Crew
PRIVATE_KEY_JWK = {} # paste the JWK saved when you created the agent
callback = ViatorisCrewCallback(
org_api_key="YOUR_API_KEY",
agent_did="YOUR_AGENT_DID",
private_key_jwk=PRIVATE_KEY_JWK,
key_id="YOUR_AGENT_DID#key-1",
)
analyst = Agent(
role="Data Analyst",
goal="Analyze quarterly sales data",
backstory="Expert analyst for enterprise reporting",
)
task = Task(
description="Analyze Q3 sales",
agent=analyst,
expected_output="A short summary report",
step_callback=callback,
)
crew = Crew(agents=[analyst], tasks=[task])
crew.kickoff()Option E: AutoGen
ViatorisAutoGenHandler installs itself as an observer via register_reply and watches every message that flows through a ConversableAgent. It always returns None, so your agent's reply chain is unaffected.
pip install viatoris-autogen viatorisaiimport autogen
from viatoris_autogen import ViatorisAutoGenHandler
PRIVATE_KEY_JWK = {} # paste the JWK saved when you created the agent
handler = ViatorisAutoGenHandler(
org_api_key="YOUR_API_KEY",
agent_did="YOUR_AGENT_DID",
private_key_jwk=PRIVATE_KEY_JWK,
key_id="YOUR_AGENT_DID#key-1",
)
assistant = autogen.AssistantAgent(
name="assistant",
llm_config={"config_list": [{"model": "gpt-4o", "api_key": "sk-..."}]},
)
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
human_input_mode="NEVER",
code_execution_config={"work_dir": "coding", "use_docker": False},
)
# One line per agent. Observer only, never interferes with the reply chain.
handler.register(assistant)
handler.register(user_proxy)
user_proxy.initiate_chat(assistant, message="Analyze Q3 sales data")Option F: Claude MCP Server
The @viatorisai/mcp-server package lets Claude Desktop, Claude Code, Cursor, and any other Model Context Protocol client interact with Viatoris directly. Your AI client can create agents, list them, verify other agents, and check reputation, all without writing any integration code. Your AI client gains six new tools and can manage your agent fleet conversationally.
Add the following to claude_desktop_config.json (Claude → Settings → Developer → Edit Config) or your Cursor MCP config:
{
"mcpServers": {
"viatoris": {
"command": "npx",
"args": ["@viatorisai/mcp-server"],
"env": {
"VIATORIS_API_KEY": "YOUR_API_KEY"
}
}
}
}For Claude Code, the same setup is one command:
claude mcp add viatoris npx @viatorisai/mcp-server --env VIATORIS_API_KEY=YOUR_API_KEYThe server exposes six tools:
create_agent: create a new agent with a cryptographic identity. Auto-discovers your org DID from the API key.list_agents: list every agent in your organization.verify_agent: check another agent's identity, status, reputation, and compliance frameworks. Public endpoint, works for any DID.get_reputation: fetch the full reputation profile and trust signals for an agent.list_receipts: list recent signed action receipts, optionally filtered by agent.submit_receipt_info: explains how to submit signed receipts (which must be done via the SDK, see below).
Note on signing. The MCP server only needs VIATORIS_API_KEY, not an agent private key. Submitting a signed receipt requires your agent's Ed25519 private key to produce a JWS signature, and the MCP server intentionally never holds private keys. Receipt signing belongs inside your agent process via the SDK (Options A through E above). Run submit_receipt_info from inside your MCP client for a copy-pasteable example.
7. Webhooks: Get notified when actions happen
Viatoris can send a signed webhook to your server every time an agent submits a receipt. Use webhooks to pipe agent activity into Slack, your ticketing system, or any tool that accepts HTTP callbacks. Configure webhooks in your dashboard under Settings > Webhooks.
Payload format
{
"event": "receipt.created",
"timestamp": "2026-04-09T14:30:00.000Z",
"data": {
"receiptId": "7f3a1b2c-...",
"agentDid": "did:web:api.viatoris.ai:agents:scout",
"action": "data_retrieval",
"result": "success",
"timestamp": "2026-04-09T14:30:00.000Z",
"counterpartyDid": null
}
}Every webhook includes these headers:
Content-Type: application/jsonX-Webhook-Signature: HMAC-SHA256 hex digest of the raw body, signed with your webhook secretX-Webhook-Event: the event type (e.g. receipt.created)X-Webhook-Timestamp: ISO 8601 timestamp of when the webhook was sent
Verify the signature
Compute the HMAC-SHA256 of the raw request body using your webhook secret. Compare it to the X-Webhook-Signature header. If they match, the payload is authentic and has not been tampered with.
import crypto from 'crypto';
function verifyWebhook(req, secret) {
const signature = req.headers['x-webhook-signature'];
const computed = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(req.body))
.digest('hex');
return signature === computed;
}Example: Send to Slack
app.post('/webhook/viatoris', (req, res) => {
const { data } = req.body;
fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `Agent ${data.agentDid} performed ${data.action}: ${data.result}`
})
});
res.sendStatus(200);
});Works with any HTTP endpoint
Any tool that accepts incoming webhooks can receive Viatoris events. Paste your endpoint URL into the dashboard and select which events to subscribe to. Works with Zapier, Make, n8n, PagerDuty, ConnectWise, and any custom HTTP server.
Available on Developer tier and above
Webhooks are available on the Developer ($19/mo), Pro ($79/mo), and Enterprise plans. Free tier users can upgrade from the Settings page.
SIEM Integration
Viatoris can deliver webhooks in the native wire format of your SIEM. When you create a webhook endpoint, pick one of four formats: json (default), cef, ecs, or syslog. The delivery, retry, and HMAC signing flow is unchanged; only the body bytes change. The HMAC always covers the final body the receiver sees.
Splunk
Stream Viatoris events to Splunk via HTTP Event Collector (HEC).
- In Splunk, go to Settings > Data Inputs > HTTP Event Collector, create a new token.
- Important: set the sourcetype on the HEC token to
cefso Splunk parses CEF correctly. - Copy the HEC endpoint URL, usually
https://your-splunk.com:8088/services/collector/event. - In Viatoris, create a webhook with that URL and select format CEF.
- Configure Splunk to accept the HEC token for authentication; this is separate from the Viatoris HMAC signature.
Sumo Logic
Use an HTTP Source collector to receive Viatoris events.
- In Sumo Logic, create an HTTP Source collector and copy the unique URL.
- In Viatoris, create a webhook with that URL.
- Select format JSON.
- Sumo Logic auto-parses the events and indexes them.
Elastic / OpenSearch
Index Viatoris events into Elasticsearch (or OpenSearch) for Kibana dashboards.
- Set up an HTTP input endpoint in Logstash, or use a direct Elasticsearch ingest pipeline.
- In Viatoris, create a webhook pointing to your Logstash HTTP input URL.
- Select format ECS.
- Events land with proper ECS fields and integrate with Elastic's pre-built security dashboards.
ignore_above: 32768) may drop large receipts with deep tool-call traces. If receipts appear truncated, raise the limit on the viatoris.receipt field in your index mapping.Datadog Logs
Send Viatoris events straight to Datadog Logs.
- Get your Datadog API key from Organization Settings > API Keys.
- Use the logs intake URL:
https://http-intake.logs.datadoghq.com/v1/input/<api_key>. - In Viatoris, create a webhook with that URL.
- Select format JSON.
- Events appear in Datadog Logs within seconds.
Microsoft Sentinel (via Azure Logic Apps)
Microsoft Sentinel's HTTP Data Collector API requires HMAC-SHA256 signatures using its own scheme, which isn't compatible with our standard webhook signing. Use Azure Logic Apps as the middleware that converts our auth to Sentinel's auth.
- In Azure, create a Logic App with an HTTP trigger and copy the URL it generates.
- Add a "Send Data" action configured for your Log Analytics workspace.
- In Viatoris, create a webhook pointing to the Logic App trigger URL.
- Select format ECS.
- The Logic App handles authentication to Sentinel and forwards events with proper auth.
Custom Syslog Server
Forward events to any syslog-compatible system via an HTTP-to-syslog bridge.
- Run rsyslog with the
omhttpmodule configured to receive HTTP POST and forward to syslog, or use a lightweight HTTP-to-syslog relay. - In Viatoris, create a webhook pointing to the relay URL.
- Select format Syslog (RFC 5424).
- Events arrive at your syslog server as standard RFC 5424 messages.
Testing
Test any format without a real SIEM:
- Go to webhook.site and copy the unique URL.
- Create a webhook in Viatoris with that URL and your chosen format.
- Trigger an event (create an agent, submit a receipt).
- See the formatted event on webhook.site.
8. What's next?
View your audit trail
Browse every receipt your agents have ever signed, with full provenance and verification status.
Set up webhooks
Get notified in real-time when your agents create receipts. HMAC-signed, retried automatically.
Add compliance profiles
Attach HIPAA, SOC2, GDPR, or custom policy declarations to your agents and let anyone verify them.
Upgrade to Pro
Higher rate limits, longer retention, team members, compliance evaluation, and priority support.
Questions? Email jared@viatoris.ai