Documentation
Everything you need to secure your AI agent credentials with AgentKeys.
Getting Started
Get your first agent proxying secrets in under 5 minutes.
1. Create an account
Sign up at https://app.agentkeys.io and create a workspace. You'll get a workspace API key automatically (starts with ak_ws_).
2. Add a credential
Go to Credentials and click Add Credential. Choose the auth type (API Key, Cookie, Basic Auth, etc.) and paste your secret. It's encrypted immediately with AES-256-GCM — the plaintext is never stored.
3. Create an agent
Go to Agents and click Create Agent. Give it a name that identifies your AI tool or script (e.g. marketing-bot or data-pipeline).
4. Assign a credential
Click Assign Credential on your agent and select a credential. AgentKeys generates a proxy token (starts with pxr_). Copy it — it's shown only once.
5. Make your first proxy call
With API key — reference any credential by name:
curl -X POST https://proxy.agentkeys.io/v1/proxy \ -H "Authorization: Bearer ak_ws_YOUR_API_KEY" \ -H "X-Credential-Name: Resend" \ -H "X-Target-Url: https://api.resend.com/emails" \ -H "Content-Type: application/json" \ -d '{"from": "hi@example.com", "to": "user@example.com", "subject": "Hello", "text": "Sent via AgentKeys"}'
With proxy token — direct credential access:
curl -X POST https://proxy.agentkeys.io/v1/proxy \ -H "Authorization: Bearer pxr_YOUR_PROXY_TOKEN" \ -H "X-Target-Url: https://api.resend.com/emails" \ -H "Content-Type: application/json" \ -d '{"from": "hi@example.com", "to": "user@example.com", "subject": "Hello", "text": "Sent via AgentKeys"}'
AgentKeys decrypts the real credential, injects it into the request headers, forwards to the target API, and returns the response. Your agent never touches the real secret.
CLI
The AgentKeys CLI lets you manage credentials, agents, and proxy calls from the terminal. Useful for scripting, CI/CD pipelines, and local development.
Installation
npm install -g @agentkeys-io/cli
Or use it without installing:
npx @agentkeys-io/cli <command>
Authentication
Initialize and log in to link the CLI to your AgentKeys account:
# Initialize config and authenticate agentkeys init # Log in with your workspace API key agentkeys login # Check current status agentkeys status
Config is stored at ~/.agentkeys/config.json:
{ "apiKey": "ak_ws_...", "apiUrl": "https://app.agentkeys.io", "workspaceId": "ws_..." }
Credentials
# List all credentials agentkeys credentials list # Add a new API key credential agentkeys credentials add \ --name "Resend Production" \ --type API_KEY \ --value "sk-..." # Add a basic auth credential interactively agentkeys credentials add --name "Jira" --type BASIC_AUTH # Remove a credential agentkeys credentials remove <credential-id>
Agents
# List all agents agentkeys agents list # Create a new agent agentkeys agents create --name "marketing-bot" # Create an agent and assign a credential in one step agentkeys agents create \ --name "data-pipeline" \ --credential <credential-id> # Remove an agent agentkeys agents remove <agent-id>
Proxy
Make a one-off proxied request from the CLI:
# Proxy a GET request agentkeys proxy <proxy-token> https://api.github.com/user/repos # Proxy a POST request with JSON body agentkeys proxy <proxy-token> https://api.resend.com/emails \ --method POST \ --data '{"from":"hi@example.com","to":"user@example.com","subject":"Hello","text":"Test"}'
MCP Server
AgentKeys ships an MCP (Model Context Protocol) server that exposes your credentials, agents, and proxy as tools. Any MCP-compatible AI assistant — Claude Desktop, Cursor, Windsurf, and others — can call these tools to securely manage and use credentials without ever seeing the real secrets.
Installation
No separate install needed — the server runs via npx:
npx @agentkeys-io/mcp
Configuration
Add AgentKeys to your MCP client configuration. Use your workspace API key (ak_ws_...):
{ "mcpServers": { "agentkeys": { "command": "npx", "args": ["@agentkeys-io/mcp"], "env": { "AGENTKEYS_API_KEY": "ak_ws_..." } } } }
{ "mcpServers": { "agentkeys": { "command": "npx", "args": ["@agentkeys-io/mcp"], "env": { "AGENTKEYS_API_KEY": "ak_ws_..." } } } }
Available Tools
Once connected, your AI assistant has access to these tools:
list_credentialsList all credentials in the workspace (names and types, not secrets).
create_credentialCreate a new encrypted credential (API key, cookie, basic auth, etc.).
delete_credentialDelete a credential by ID.
list_agentsList all agents in the workspace.
create_agentCreate a new agent with a given name.
delete_agentDelete an agent by ID.
assign_credentialAssign a credential to an agent, returning a proxy token.
proxy_requestMake a proxied HTTP request using a proxy token. The real credential is injected by AgentKeys.
OpenClaw Integration
OpenClaw is an autonomous AI agent platform. AgentKeys has a dedicated OpenClaw skill that enables your agent to manage credentials naturally through conversation — no MCP configuration required. Install the skill from ClawHub.
Install the skill
clawhub install agentkeys
Or manually: download the skill folder and place it in your OpenClaw workspace at skills/agentkeys/.
Configure
Add credentials to your OpenClaw workspace .env. The skill reads these automatically. Pick one option:
Recommended — one API key, access all credentials by name:
AGENTKEYS_API_KEY=ak_ws_your_key...
AGENTKEYS_PROXY_URL=https://proxy.agentkeys.ioAlternative — per-credential proxy tokens:
AGENTKEYS_PROXY_TOKEN_RESEND=pxr_resend_abc123...
AGENTKEYS_PROXY_TOKEN_STRIPE=pxr_stripe_def456...
AGENTKEYS_PROXY_TOKEN_GITHUB=pxr_github_ghi789...
AGENTKEYS_PROXY_URL=https://proxy.agentkeys.ioUsage
Once the skill is installed, just talk to your agent naturally:
You: Send an email via Resend to user@example.com
Agent: (uses AgentKeys proxy → Resend API) ✅ Email sent!
You: Create a Jira ticket for this bug
Agent: (uses AgentKeys proxy → Jira API) ✅ Ticket PROJ-42 created!
You: Check my Stripe balance
Agent: (uses AgentKeys proxy → Stripe API) Current balance: $1,234.56API Reference
The AgentKeys REST API lets you manage credentials, agents, and workspace settings programmatically. All endpoints require authentication.
Base URL
All API requests should be sent to:
https://app.agentkeys.io/api/v1Example: to list all credentials, send a GET request to https://app.agentkeys.io/api/v1/credentials.
Authentication
Pass your workspace API key in the Authorization header:
Authorization: Bearer ak_ws_YOUR_WORKSPACE_KEYYour API key is available in the dashboard under Settings → API Keys.
Credentials
/api/v1/credentials{ "credentials": [ { "id": "cred_abc123", "name": "Resend Production", "type": "API_KEY", "createdAt": "2025-01-15T10:30:00Z" } ] }
/api/v1/credentials{ "name": "Resend Production", "type": "API_KEY", "value": "sk-..." }
/api/v1/credentials/:id/api/v1/credentials/:idAgents
/api/v1/agents{ "agents": [ { "id": "agent_xyz789", "name": "marketing-bot", "createdAt": "2025-01-15T10:30:00Z" } ] }
/api/v1/agents{ "name": "marketing-bot" }
/api/v1/agents/:id/api/v1/agents/:id/api/v1/agents/:id/credentials{ "credentialId": "cred_abc123" }
{ "proxyToken": "pxr_...", "agentId": "agent_xyz789", "credentialId": "cred_abc123" }
Workspace
/api/v1/workspace/status{ "workspace": { "id": "ws_...", "name": "My Workspace", "plan": "pro", "usage": { "credentials": 12, "agents": 4, "requestsThisMonth": 8432 }, "limits": { "credentials": 100, "agents": 25, "requestsPerMonth": 100000 } } }
Error Responses
All errors follow a consistent format:
{ "error": "Credential not found", "code": "NOT_FOUND", "status": 404 }
| Status | Meaning |
|---|---|
| 400 | Bad Request — missing or invalid parameters |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — insufficient permissions |
| 404 | Not Found — resource does not exist |
| 429 | Too Many Requests — rate limit exceeded |
| 500 | Internal Server Error |
Webhooks
AgentKeys can send HTTP webhooks to your server when key events happen — credential expiry, errors, or usage limits. Use webhooks to automate rotation, alerting, or integrations with your existing tooling.
Setting up webhooks
Go to Settings → Webhooks in your workspace and click Add Endpoint. Enter your HTTPS URL and select which events to subscribe to.
Your endpoint must respond with HTTP 200 within 10 seconds. Failed deliveries are retried up to 3 times with exponential backoff.
Event types
credential.expiredA credential has expired. The proxy will start returning 401 errors for this credential.
credential.expiring_soonA credential is expiring within 7 days. Time to rotate.
credential.errorThe target API returned an auth error (401/403) for this credential.
usage.limit_reachedYour workspace has reached the request limit for the current billing period.
Payload format
{ "id": "evt_01J...", "event": "credential.expiring_soon", "workspaceId": "ws_...", "timestamp": "2025-06-01T09:00:00Z", "data": { "credentialId": "cred_abc123", "credentialName": "Resend Production", "expiresAt": "2025-06-08T09:00:00Z" } }
Verifying signatures
Each webhook request includes an X-AgentKeys-Signature header. Verify it to ensure the payload came from AgentKeys and hasn't been tampered with.
The signature is an HMAC-SHA256 of the raw request body, signed with your webhook secret (available in Settings → Webhooks).
import crypto from "crypto"; const WEBHOOK_SECRET = process.env.AGENTKEYS_WEBHOOK_SECRET; export function verifyWebhook( rawBody: string, signature: string ): boolean { const expected = crypto .createHmac("sha256", WEBHOOK_SECRET) .update(rawBody, "utf8") .digest("hex"); // Use timingSafeEqual to prevent timing attacks return crypto.timingSafeEqual( Buffer.from(signature, "hex"), Buffer.from(expected, "hex") ); } // Express example app.post("/webhooks/agentkeys", express.raw({ type: "*/*" }), (req, res) => { const sig = req.headers["x-agentkeys-signature"] as string; if (!verifyWebhook(req.body.toString(), sig)) { return res.status(401).json({ error: "Invalid signature" }); } const event = JSON.parse(req.body.toString()); console.log("Received event:", event.event); res.sendStatus(200); });
import hmac import hashlib def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode("utf-8"), raw_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected) # Flask example @app.route("/webhooks/agentkeys", methods=["POST"]) def handle_webhook(): sig = request.headers.get("X-AgentKeys-Signature", "") if not verify_webhook(request.data, sig, WEBHOOK_SECRET): return jsonify({"error": "Invalid signature"}), 401 event = request.get_json(force=True) print(f"Received event: {event['event']}") return "", 200
Team Management
Invite team members to your workspace and control what they can do with role-based access control.
Roles
| Permission | Owner | Admin | Member |
|---|---|---|---|
| View credentials | ✅ | ✅ | ✅ |
| Add / edit credentials | ✅ | ✅ | ❌ |
| Delete credentials | ✅ | ✅ | ❌ |
| Create / edit agents | ✅ | ✅ | ✅ |
| Delete agents | ✅ | ✅ | ❌ |
| View audit logs | ✅ | ✅ | ✅ |
| Invite members | ✅ | ✅ | ❌ |
| Remove members | ✅ | ✅ | ❌ |
| Manage billing | ✅ | ❌ | ❌ |
| Delete workspace | ✅ | ❌ | ❌ |
| Rotate workspace API key | ✅ | ✅ | ❌ |
| Configure webhooks | ✅ | ✅ | ❌ |
Inviting members
Go to Settings → Team and click Invite Member. Enter their email address and select a role. They'll receive an invitation email with a link to join.
Invitations expire after 7 days. You can re-send or cancel pending invitations from the same page.
Multiple workspaces
You can be a member of multiple workspaces. Switch between them using the workspace switcher in the top-left of the dashboard, or via the API by passing a different API key.
Create a new workspace from the switcher dropdown or via Settings → Create Workspace. Each workspace has its own credentials, agents, billing, and team.
Proxy
The AgentKeys proxy is the core of the platform. Your AI agents send requests to the proxy instead of directly to the target API. The proxy injects the real credential and forwards the request — your agent never sees the secret.
Endpoint
POST https://proxy.agentkeys.io/v1/proxyHeaders
| Header | Required | Description |
|---|---|---|
| Authorization | ✅ | Bearer pxr_... (proxy token) or Bearer ak_ws_... (API key) |
| X-Target-Url | ✅ | The full URL to forward the request to |
| X-Credential-Name | ⚠️ | Credential name — required when using API key auth (ak_ws_) |
| X-Target-Method | ❌ | Override HTTP method (defaults to request method) |
| Content-Type | ❌ | Passed through to the target API |
All other headers (except Host) are passed through to the target API.
Proxy token format
Proxy tokens are prefixed with pxr_ and are unique per agent-credential pair. Each token is SHA-256 hashed in the database — even if the database is compromised, the token itself can't be recovered.
pxr_<random_256_bit_token>Tokens are generated when you assign a credential to an agent. You can revoke a token at any time by removing the agent-credential assignment in the dashboard.
How it works
- Your agent sends a request to the proxy with a
pxr_token orak_ws_API key +X-Credential-Name - The proxy validates the token and resolves the credential (by token hash or by name)
- The real credential is decrypted from AES-256-GCM storage (in memory only)
- The credential is injected into the request headers (or URL for query params)
- The request is forwarded to
X-Target-Url - The response is streamed back to your agent
- The request is logged in the audit trail (no credential values logged)
Examples
Resend:
curl -X POST https://proxy.agentkeys.io/v1/proxy \ -H "Authorization: Bearer pxr_resend_abc123" \ -H "X-Target-Url: https://api.resend.com/emails" \ -H "Content-Type: application/json" \ -d '{"from": "hi@example.com", "to": "user@example.com", "subject": "Hello", "text": "Sent via AgentKeys"}'
Anthropic:
curl -X POST https://proxy.agentkeys.io/v1/proxy \ -H "Authorization: Bearer pxr_anthropic_def456" \ -H "X-Target-Url: https://api.anthropic.com/v1/messages" \ -H "Content-Type: application/json" \ -H "anthropic-version: 2023-06-01" \ -d '{"model": "claude-opus-4-5", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello!"}]}'
GitHub (GET request):
curl https://proxy.agentkeys.io/v1/proxy \ -H "Authorization: Bearer pxr_github_ghi789" \ -H "X-Target-Url: https://api.github.com/user/repos"
Resend (email):
curl -X POST https://proxy.agentkeys.io/v1/proxy \ -H "Authorization: Bearer pxr_resend_jkl012" \ -H "X-Target-Url: https://api.resend.com/emails" \ -H "Content-Type: application/json" \ -d '{"from": "hi@yourdomain.com", "to": "user@example.com", "subject": "Hello", "text": "Hello!"}'
Credential Types
API Key
API_KEYA single secret sent as Authorization: Bearer header. Works with Stripe, Resend, Twilio, and most APIs.
→ Authorization: Bearer <key>
Cookie
COOKIEBrowser cookies for services without API keys — Twitter/X, LinkedIn, etc. Supports paste-all mode for easy import from DevTools.
→ Cookie: name=value; name2=value2
Basic Auth
BASIC_AUTHUsername + password pair for Jira, Twilio, Jenkins, Elasticsearch, and enterprise tools.
→ Authorization: Basic base64(user:pass)
Custom Headers
CUSTOM_HEADEROne or more custom HTTP headers. For Anthropic (x-api-key), Cloudflare, Supabase, and APIs with non-standard auth.
→ Custom header key-value pairs injected as-is
Query Parameter
QUERY_PARAMAuth value appended to URL. Used by Google Maps, Telegram Bot API, and legacy APIs.
→ ?key=value appended to target URL
Core Concepts
Workspace
A workspace is your organization. It contains credentials, agents, and audit logs. Each workspace has its own encryption master key and API key.
Credential
A secret stored in AgentKeys — API key, OAuth token, password, cookies, or headers. Encrypted with AES-256-GCM at rest. The plaintext is never stored.
Agent
Represents your AI tool, bot, or script. Each agent can be assigned specific credentials and receives a unique proxy token for each one.
Proxy Token
A unique token (prefixed pxr_) that maps to one credential + one agent. The agent uses this token to make API calls through the proxy. The real credential is resolved and injected at request time.
OAuth Connect
Connect services with one click. AgentKeys handles the OAuth flow, stores tokens encrypted, and auto-refreshes them before expiry.
To connect, go to Credentials → Connect OAuth and select a provider. You'll be redirected to authorize, then the token is automatically saved and encrypted.
SDKs
TypeScript
npm install @agentkeys-io/sdk
With API key — access any credential by name:
import { AgentKeys } from "@agentkeys-io/sdk"; const ak = new AgentKeys({ token: "ak_ws_your_key...", proxyUrl: "https://proxy.agentkeys.io", }); // Proxy by credential name const res = await ak.proxy("resend", { url: "https://api.resend.com/emails", method: "POST", body: { from: "hi@example.com", to: "user@example.com", subject: "Hello", text: "Sent via AgentKeys" }, }); console.log(await res.json());
Scoped client — bind to a credential for cleaner code:
const stripe = ak.for("stripe"); const resend = ak.for("resend"); const balance = await stripe.get("https://api.stripe.com/v1/balance"); await resend.post("https://api.resend.com/emails", { from: "hi@example.com", to: "user@example.com", subject: "Test", text: "Hello" });
With proxy token — single credential, no name needed:
const ak = new AgentKeys({ token: "pxr_resend_abc123..." }); const res = await ak.proxy("ignored", { url: "https://api.resend.com/emails", method: "POST", body: { ... } });
Python
pip install agentkeys
With API key — access any credential by name:
from agentkeys import AgentKeys ak = AgentKeys( token="ak_ws_your_key...", proxy_url="https://proxy.agentkeys.io", ) # Proxy by credential name res = ak.proxy( credential="resend", url="https://api.resend.com/emails", method="POST", body={"from": "hi@example.com", "to": "user@example.com", "subject": "Hello", "text": "Sent via AgentKeys"}, ) print(res.json())
Scoped client:
stripe = ak.for_credential("stripe") resend = ak.for_credential("resend") balance = stripe.get("https://api.stripe.com/v1/balance") resend.post("https://api.resend.com/emails", body={"from": "hi@example.com", "to": "user@example.com", "subject": "Test", "text": "Hello"})
With proxy token:
ak = AgentKeys(token="pxr_resend_abc123...") res = ak.proxy(credential="ignored", url="https://api.resend.com/emails", method="POST", body={...})
Security
Encryption at rest
All credentials encrypted with AES-256-GCM. Per-workspace master keys. Plaintext never stored in the database.
Proxy tokens are hashed
Proxy tokens are SHA-256 hashed in the database. Even if the DB is compromised, tokens can't be reversed.
Zero-knowledge proxy
Credentials are decrypted only in memory at request time. They're never logged, cached, or written to disk.
Full audit trail
Every proxied request is logged: agent identity, target URL, HTTP method, status code, latency, and timestamp.
Instant revocation
Revoke any credential or agent assignment instantly from the dashboard. Takes effect immediately.
HMAC-signed webhooks
Webhook payloads are signed with HMAC-SHA256 so you can verify they came from AgentKeys.
Limits & Pricing
| Plan | Credentials | Agents | Requests/mo | Price |
|---|---|---|---|---|
| Free | 3 | 1 | 100 | $0 |
| Starter | 25 | 5 | 10,000 | $19/mo |
| Pro | 100 | 25 | 100,000 | $79/mo |
| Scale | 500 | 100 | 500,000 | $199/mo |
| Enterprise | Unlimited | Unlimited | Unlimited | Custom |