Authentication
All API requests to Agent OTP require authentication using API keys. This guide covers how to authenticate your requests.
API Keys
API keys are used to authenticate requests from your agents. Each agent has its own API key, which is used to identify and authorize the agent.
Creating an API Key
Generate an API key using the CLI after starting your self-hosted instance:
# Create a new agent and generate API key
docker compose exec api bun run cli agent:create --name "my-assistant"
# Output:
# Agent created successfully!
# API Key: ak_live_xxxxxxxxxxxxxxxxxxxxImportant: API keys are only shown once. Store them securely in your environment variables or secrets manager.
API Key Format
API keys follow this format:
ak_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
└─┬──┘ └─┬─┘ └──────────────┬──────────────┘
│ │ │
│ │ └── 32-character random string
│ └── Environment (live or test)
└── Key type prefixUsing API Keys
Bearer Token (Recommended)
Include your API key in the Authorization header:
curl -X POST https://api.agentotp.com/v1/permissions/request \
-H "Authorization: Bearer ak_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"action": "email.send", "scope": {}}'X-API-Key Header
Alternatively, use the X-API-Key header:
curl -X POST https://api.agentotp.com/v1/permissions/request \
-H "X-API-Key: ak_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"action": "email.send", "scope": {}}'SDK Authentication
When using the SDK, pass the API key to the constructor:
import { AgentOTPClient } from '@orrisai/agent-otp-sdk';
const client = new AgentOTPClient({
apiKey: process.env.AGENT_OTP_API_KEY!,
});Test vs. Live Keys
| Key Type | Prefix | Purpose |
|---|---|---|
| Live | ak_live_ | Production use, counts against quotas |
| Test | ak_test_ | Development use, does not count against quotas |
Test keys auto-approve all requests and do not send notifications. Use them for development and testing only.
Key Rotation
You can rotate API keys without downtime:
- Create a new API key for the agent
- Update your application to use the new key
- Verify the new key is working
- Revoke the old key
// Support multiple keys during rotation
const client = new AgentOTPClient({
apiKey: process.env.AGENT_OTP_API_KEY_NEW
|| process.env.AGENT_OTP_API_KEY!,
});Revoking Keys
Revoke compromised or unused keys immediately using the CLI:
# List agents to find the one to revoke
docker compose exec api bun run cli agent:list
# Revoke an API key
docker compose exec api bun run cli agent:revoke --id AGENT_IDRevoked keys will receive a 401 Unauthorized response.
Rate Limits
Rate limits are configurable in your self-hosted instance. Default limits:
| Limit Type | Default | Environment Variable |
|---|---|---|
| Requests per minute | 60 | RATE_LIMIT_PER_MIN |
| Requests per hour | 1000 | RATE_LIMIT_PER_HOUR |
Authentication Errors
| Status | Code | Description |
|---|---|---|
| 401 | MISSING_API_KEY | No API key provided |
| 401 | INVALID_API_KEY | API key is malformed or doesn't exist |
| 401 | EXPIRED_API_KEY | API key has been revoked or expired |
Security Best Practices
- Never expose keys in client-side code - Only use API keys in server-side code
- Use environment variables - Store keys in environment variables, not in code
- Rotate keys regularly - Rotate API keys every 90 days
- Monitor usage - Set up alerts for unusual API usage
- Use separate keys per environment - Different keys for dev, staging, production