Authentication
Secure your API requests with elizaOS Cloud authentication methods.
Overview
elizaOS Cloud supports multiple authentication methods:
| Method | Use Case | Header / flow |
|---|---|---|
| API Key | Server-to-server | Authorization: Bearer eliza_xxx or X-API-Key |
| Session | Browser apps | Cookie-based (Privy) |
| SIWE | Wallet sign-in, get API key | GET nonce → sign message → POST verify → use key |
| Wallet header | Per-request wallet auth | X-Wallet-Address, X-Timestamp, X-Wallet-Signature |
| x402 | Crypto payments | X-PAYMENT: ... |
API Keys
Creating an API Key
- Navigate to Dashboard → API Keys
- Click “Create API Key”
- Name your key and set permissions
- Copy and securely store the key
API keys are shown only once. Store them securely immediately after creation.
Using API Keys
cURL
curl -X GET "https://cloud.milady.ai/api/v1/dashboard" \
-H "Authorization: Bearer ek_live_xxxxxxxxxxxx"Key Types
| Prefix | Environment | Description |
|---|---|---|
ek_live_ | Production | Live API access |
ek_test_ | Testing | Sandbox environment |
Key Permissions
Restrict keys to specific endpoints:
{
"name": "Production Chat Key",
"permissions": [
"chat:read",
"chat:write",
"embeddings:read"
],
"rateLimit": 100
}Available Permissions
Permissions can be used to restrict what operations an API key can perform.
| Permission | Description |
|---|---|
chat | Chat completions |
embeddings | Generate embeddings |
images | Image generation |
video | Video generation |
voice | Voice/TTS |
knowledge | Knowledge base |
agents | Agent management |
apps | App management |
If no permissions are specified when creating an API key, the key has access to all endpoints by default. Use permissions to create restricted keys for specific use cases.
API Key Management
List Keys
curl -X GET "https://cloud.milady.ai/api/v1/api-keys" \
-H "Authorization: Bearer ek_live_xxxxxxxxxxxx"Regenerate Key
curl -X POST "https://cloud.milady.ai/api/v1/api-keys/{id}/regenerate" \
-H "Authorization: Bearer ek_live_xxxxxxxxxxxx"Revoke Key
curl -X DELETE "https://cloud.milady.ai/api/v1/api-keys/{id}" \
-H "Authorization: Bearer ek_live_xxxxxxxxxxxx"Session Authentication
For browser-based applications, use Privy authentication:
import { usePrivy } from "@privy-io/react-auth";
function MyComponent() {
const { login, authenticated, getAccessToken } = usePrivy();
const makeApiCall = async () => {
const token = await getAccessToken();
const response = await fetch("https://cloud.milady.ai/api/v1/dashboard", {
credentials: "include",
headers: {
Authorization: `Bearer ${token}`,
},
});
};
}Wallet & SIWE (Sign-In With Ethereum)
Wallet-based auth supports agents and headless clients that cannot use browser sessions.
SIWE flow (get an API key)
- GET /api/auth/siwe/nonce — Returns
{ nonce, domain, uri, chainId, version, statement }. Nonce is one-time, 5 min TTL (Redis). Why nonce? Prevents replay; timestamp-only can be replayed within the window. - Build the EIP-4361 message with the nonce and sign it with the wallet.
- POST /api/auth/siwe/verify — Body
{ message, signature }. Server validates domain and signature, consumes the nonce, then finds or creates user/org and returnsapiKeywithuserandorganization. New wallets get initial free credits (configurable viaINITIAL_FREE_CREDITS). - Use the returned API key:
X-API-Key: <key>orAuthorization: Bearer <key>on subsequent requests.
Wallet header signature (no API key)
Send on every request instead of storing an API key:
- X-Wallet-Address: Ethereum address (any case).
- X-Timestamp: Unix ms (must be within ±5 min of server time). Why? Binds the signature to a time window and limits replay.
- X-Wallet-Signature: Signature of the message
Eliza Cloud Authentication\nTimestamp: ${timestamp}\nMethod: ${method}\nPath: ${path}
so the signature is bound to this request. Why method + path? Prevents reusing the same signature on another endpoint.
If the wallet is unknown, the first valid signed request creates the account (same as SIWE signup). After that, any endpoint that uses requireAuthOrApiKey accepts wallet-header auth.
x402 topup with wallet
POST /api/v1/topup/10, /50, /100 (x402 payment-gated):
- With wallet sig headers: credits go to the signer’s wallet (no body
walletAddressneeded). - Without wallet sig: send body.walletAddress; that wallet’s org is credited. New wallets are created without initial free credits (payment only).
See Wallet API for full reference, WHYs, and file list.
x402 Authentication
Pay per request with cryptocurrency:
curl -X POST "https://cloud.milady.ai/api/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "X-PAYMENT: <x402-payment-header>" \
-d '{"model": "gpt-4o", "messages": [...]}'See the crypto payments section below for details.
Security Best Practices
Do’s
- ✅ Use environment variables for API keys
- ✅ Rotate keys regularly
- ✅ Use minimal permissions
- ✅ Monitor key usage
- ✅ Use different keys for different environments
Don’ts
- ❌ Commit keys to version control
- ❌ Share keys between applications
- ❌ Use production keys in development
- ❌ Expose keys in client-side code
- ❌ Log API keys
Environment Variables
# .env.local (never commit this file)
ELIZA_API_KEY=ek_live_xxxxxxxxxxxx// Access in your code
const apiKey = process.env.ELIZA_API_KEY;Error Responses
401 Unauthorized
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing authentication"
}
}Causes:
- Missing API key
- Invalid API key
- Expired session
403 Forbidden
{
"error": {
"code": "FORBIDDEN",
"message": "Insufficient permissions"
}
}Causes:
- Key lacks required permission
- Resource access denied
Rate Limiting
API keys have rate limits based on your plan:
| Plan | Rate Limit |
|---|---|
| Free | 60 req/min |
| Pro | 300 req/min |
| Enterprise | Custom |
Rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1705312860