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:

Terminal
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:

Terminal
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

Install globally
npm install -g @agentkeys-io/cli

Or use it without installing:

Run with npx
npx @agentkeys-io/cli <command>

Authentication

Initialize and log in to link the CLI to your AgentKeys account:

Terminal
# 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:

~/.agentkeys/config.json
{
  "apiKey": "ak_ws_...",
  "apiUrl": "https://app.agentkeys.io",
  "workspaceId": "ws_..."
}

Credentials

Terminal
# 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

Terminal
# 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:

Terminal
# 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:

Terminal
npx @agentkeys-io/mcp

Configuration

Add AgentKeys to your MCP client configuration. Use your workspace API key (ak_ws_...):

Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "agentkeys": {
      "command": "npx",
      "args": ["@agentkeys-io/mcp"],
      "env": {
        "AGENTKEYS_API_KEY": "ak_ws_..."
      }
    }
  }
}
Cursor / Windsurf — .cursor/mcp.json
{
  "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_credentials

List all credentials in the workspace (names and types, not secrets).

create_credential

Create a new encrypted credential (API key, cookie, basic auth, etc.).

delete_credential

Delete a credential by ID.

list_agents

List all agents in the workspace.

create_agent

Create a new agent with a given name.

delete_agent

Delete an agent by ID.

assign_credential

Assign a credential to an agent, returning a proxy token.

proxy_request

Make 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

Terminal
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:

.env
AGENTKEYS_API_KEY=ak_ws_your_key...
AGENTKEYS_PROXY_URL=https://proxy.agentkeys.io

Alternative — per-credential proxy tokens:

.env
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.io

Usage

Once the skill is installed, just talk to your agent naturally:

Chat with your agent
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.56

API 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:

Base URL
https://app.agentkeys.io/api/v1

Example: 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:

HTTP header
Authorization: Bearer ak_ws_YOUR_WORKSPACE_KEY

Your API key is available in the dashboard under Settings → API Keys.

Credentials

GET/api/v1/credentials
List all credentials in the workspace (names and types, never plaintext secrets).
Response
{
  "credentials": [
    {
      "id": "cred_abc123",
      "name": "Resend Production",
      "type": "API_KEY",
      "createdAt": "2025-01-15T10:30:00Z"
    }
  ]
}
POST/api/v1/credentials
Create a new credential. The secret is encrypted immediately.
Request body
{
  "name": "Resend Production",
  "type": "API_KEY",
  "value": "sk-..."
}
GET/api/v1/credentials/:id
Get a credential by ID (metadata only, no plaintext).
DELETE/api/v1/credentials/:id
Delete a credential permanently. All associated proxy tokens are revoked.

Agents

GET/api/v1/agents
List all agents in the workspace.
Response
{
  "agents": [
    {
      "id": "agent_xyz789",
      "name": "marketing-bot",
      "createdAt": "2025-01-15T10:30:00Z"
    }
  ]
}
POST/api/v1/agents
Create a new agent.
Request body
{
  "name": "marketing-bot"
}
GET/api/v1/agents/:id
Get an agent by ID.
DELETE/api/v1/agents/:id
Delete an agent. All proxy tokens issued to this agent are revoked.
POST/api/v1/agents/:id/credentials
Assign a credential to an agent. Returns a proxy token (shown once, store it securely).
Request body
{
  "credentialId": "cred_abc123"
}
Response
{
  "proxyToken": "pxr_...",
  "agentId": "agent_xyz789",
  "credentialId": "cred_abc123"
}

Workspace

GET/api/v1/workspace/status
Get workspace status — plan, usage, limits.
Response
{
  "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 response
{
  "error": "Credential not found",
  "code": "NOT_FOUND",
  "status": 404
}
StatusMeaning
400Bad Request — missing or invalid parameters
401Unauthorized — missing or invalid API key
403Forbidden — insufficient permissions
404Not Found — resource does not exist
429Too Many Requests — rate limit exceeded
500Internal 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.expired

A credential has expired. The proxy will start returning 401 errors for this credential.

credential.expiring_soon

A credential is expiring within 7 days. Time to rotate.

credential.error

The target API returned an auth error (401/403) for this credential.

usage.limit_reached

Your workspace has reached the request limit for the current billing period.

Payload format

Webhook POST body
{
  "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).

Node.js verification
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);
});
Python verification
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

PermissionOwnerAdminMember
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/proxy

Headers

HeaderRequiredDescription
AuthorizationBearer pxr_... (proxy token) or Bearer ak_ws_... (API key)
X-Target-UrlThe full URL to forward the request to
X-Credential-Name⚠️Credential name — required when using API key auth (ak_ws_)
X-Target-MethodOverride HTTP method (defaults to request method)
Content-TypePassed 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

  1. Your agent sends a request to the proxy with a pxr_ token or ak_ws_ API key + X-Credential-Name
  2. The proxy validates the token and resolves the credential (by token hash or by name)
  3. The real credential is decrypted from AES-256-GCM storage (in memory only)
  4. The credential is injected into the request headers (or URL for query params)
  5. The request is forwarded to X-Target-Url
  6. The response is streamed back to your agent
  7. The request is logged in the audit trail (no credential values logged)

Examples

Resend:

curl
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
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
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
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_KEY

A single secret sent as Authorization: Bearer header. Works with Stripe, Resend, Twilio, and most APIs.

Authorization: Bearer <key>

Cookie

COOKIE

Browser 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_AUTH

Username + password pair for Jira, Twilio, Jenkins, Elasticsearch, and enterprise tools.

Authorization: Basic base64(user:pass)

Custom Headers

CUSTOM_HEADER

One 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_PARAM

Auth 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.

GitHub
Google
Twitter / X
Slack
Notion
Linear
Discord
HubSpot

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

install
npm install @agentkeys-io/sdk

With API key — access any credential by name:

usage.ts
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:

scoped.ts
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:

proxy-token.ts
const ak = new AgentKeys({ token: "pxr_resend_abc123..." });
const res = await ak.proxy("ignored", { url: "https://api.resend.com/emails", method: "POST", body: { ... } });

Python

install
pip install agentkeys

With API key — access any credential by name:

usage.py
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:

scoped.py
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:

proxy-token.py
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

PlanCredentialsAgentsRequests/moPrice
Free31100$0
Starter25510,000$19/mo
Pro10025100,000$79/mo
Scale500100500,000$199/mo
EnterpriseUnlimitedUnlimitedUnlimitedCustom