You are on the Managed plan. The difference from bring-your-own-key: AgentGuard provisions the OpenRouter key and delivers it to a registered server process. Calls made through the configured binding are checked against the policy below. Signing remains optional and requires local signing keys. Your monthly inference allowance is included.
# Node / TypeScript
npm install @agentguard-run/spend openai
# Python
pip install agentguard-spend openai
Your license key arrived by email after checkout (starts with ag_) and is also in dashboard settings. Provide it any one of three ways:
# A) CLI (saves it to ~/.agentguard, mode 600)
agentguard auth license-key ag_your_key_here
agentguard auth status # confirm it is configured
# B) Environment variable
export AGENTGUARD_LICENSE_KEY=ag_your_key_here
# C) Pass it in code (shown in step 3 as licenseKey)
On Managed you do not set an OpenRouter key. Construct any OpenAI-compatible client pointed at OpenRouter; the guard injects your managed key for OpenRouter calls automatically.
import OpenAI from 'openai';
import { withSpendGuardOpenRouter } from '@agentguard-run/spend/frameworks/openrouter';
// apiKey is a placeholder on Managed. The guard fetches the provisioned
// tenant key for the OpenRouter host, then caches it in-process for 15 minutes.
const client = new OpenAI({
apiKey: 'managed',
baseURL: 'https://openrouter.ai/api/v1',
});
const scope = { tenantId: 'acme', agentId: 'support-bot' };
const guarded = withSpendGuardOpenRouter(client, {
licenseKey: process.env.AGENTGUARD_LICENSE_KEY, // or omit if set via CLI
policy: {
id: 'managed-support-v1',
name: 'Managed support cap',
scope,
caps: [{ amountCents: 2000, window: 'per_day', action: 'block' }],
mode: 'enforce',
requiredCapability: 'read_only',
version: 1,
effectiveFrom: '2026-01-01T00:00:00.000Z'
},
scope,
capabilityClaim: 'read_only'
});
This example uses in-memory stores and does not sign. Run agentguard wizard, or add config.signingKeys and config.logStore, for persistent signed entries.
Use the guarded client exactly like the native one. Calls through this binding are checked against the configured cap and capability requirement before dispatch, then billed to your managed allowance. The known-cost model below can be evaluated locally.
const res = await guarded.chat.completions.create({
model: 'openai/gpt-4o-mini',
messages: [{ role: 'user', content: 'Draft a one line refund note.' }],
});
console.log(res.choices[0].message.content);
// Over your cap? The call throws AgentGuardBlockedError before OpenRouter is touched.
When signing keys and a decision-log store are configured, paste an exported signed entry at agentguard.run/verify. A valid result authenticates the recorded policy and model-decision metadata under the supplied public key; it does not prove an external event. Retained receipts remain independently verifiable after cancellation.
| Property | Behavior |
|---|---|
| Where the key comes from | The SDK requests the provisioned tenant key from /api/tenant/openrouter-key using your license key in a registered server process. Browser runtimes are not supported. |
| Cache and lifecycle | Cached in-process up to 15 minutes, then fetched again. The underlying OpenRouter key remains provisioned until rotation, refund, or deprovisioning. |
| Where it is injected | Only on calls whose base URL is the OpenRouter host. Any other provider client is left untouched. |
| What you pay | Inference is drawn from your plan allowance (Solo Managed includes $40/mo), then at cost. Governance stays free regardless. |
| If the fetch fails | Managed fetch errors stop key injection. To use bring-your-own-key instead, construct the OpenAI client with your real OPENROUTER_API_KEY and omit the Managed license path. |
OPENROUTER_API_KEY, and follow the bring-your-own-key quickstart. The same guard and optional signing path apply without an AgentGuard inference proxy.