API Keys
API keys are the credentials your external agent uses to authenticate MCP tool calls. Each key carries a scope that determines which tools the agent is allowed to call. Balchemy's API key system is built around the principle of least privilege — you create the narrowest scope that gets the job done.
What you'll learn
- What API keys are and how they work with MCP
- The three scope levels and which tools each grants
- How to create, view, and revoke keys from the Hub UI
- Security practices: expiry, rotation, and what never to do with keys
What API keys are
An API key is a bearer token your agent sends in the Authorization header of every MCP request. The key is validated by Balchemy's ApiKeyScopeGuard, which checks the key against the bot's MCP configuration and enforces scope restrictions before the request reaches any tool handler.
Keys are associated with a specific bot. Each bot can have multiple keys with different scopes, allowing you to give different agents or services different levels of access to the same bot.
The key format is balc_ followed by 43 random base64url characters, giving a total key length of approximately 48 characters. The Hub UI displays only the first 13 characters (the balc_ prefix plus 8 characters) as a safe preview — the full key is shown once at creation time and never again. Store it immediately in your secrets manager.
Quick start
Step 1 — Navigate to API Keys
Go to /hub/api-keys in the Hub navigation.
Step 2 — Select a bot
Use the bot selector dropdown to choose which bot this key will control. API keys are per-bot.
Step 3 — Click Create API Key
The create dialog opens. Enter a descriptive name (e.g., "My trading agent — production"), select a scope, and click Create Key (or Continue for manage scope which requires an extra verification step).
Step 4 — Copy the key immediately
A one-time reveal modal shows the full API key. Copy it now — it auto-dismisses after 30 seconds and will never be shown again. If you lose it, revoke the key and create a new one.
Step 5 — Use the key in your agent
curl https://api.balchemy.ai/mcp/YOUR_PUBLIC_ID \
-H "Authorization: Bearer balc_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'Scope selection
Every API key carries exactly one scope. Choose the scope that matches what your agent needs to do and nothing more.
| Scope | Icon | What it allows |
|---|---|---|
read | Eye | View portfolio, positions, bot status, trade history, ask bot |
trade | Trending up | Everything in read + submit orders, cancel orders, manage strategies |
manage | Shield | Everything in trade + create/revoke keys, configure bot settings, delete bot |
The scope hierarchy is cumulative. A trade key can do everything a read key can do. A manage key can do everything both read and trade keys can do.
Most integrations should use trade scope. Use read for monitoring agents or dashboards that never place orders. Reserve manage for orchestration agents that need to reconfigure the system.
Creating a key
Navigate to /hub/api-keys and click Create API Key.
For read and trade scope
The creation dialog has two fields:
| Field | Description |
|---|---|
| Key Name | Human-readable label. Use something that identifies the agent and environment (e.g., "Arbitrage bot — staging") |
| Scope | Select read or trade from the radio group |
Click Create Key. The key is created immediately and the one-time reveal modal opens.
For manage scope (step-up required)
Manage-scope keys can perform destructive operations, so creation requires an extra identity verification step:
- Select Manage scope and click Continue
- Read the elevated access warning (the modal lists exactly what
managekeys can do) - Click Proceed to Verify
- Enter the 6-digit code from your authenticator app (TOTP)
- Click Verify & Create Key
After successful verification, the key is created and the one-time reveal modal opens.
Viewing existing keys
The API Keys table shows all keys for the selected bot. Each row displays:
| Column | Content |
|---|---|
| Name | The label you gave the key at creation |
| Prefix | First 13 characters of the key (safe to display) |
| Secret | Always masked as balc_***…*** — the actual secret is never re-shown |
| Scope | Scope badge: read, trade, or manage |
| Created | Relative time since creation |
| Expires | System-set expiry date (90 days from creation, not user-configurable) |
| Status | active or revoked badge |
Revoked keys are shown with reduced opacity and a strikethrough on the name. They cannot be re-activated.
Revoking a key
Click Revoke on any active key row. A confirmation dialog explains that the action cannot be undone and that any agents using the key will immediately lose access. Confirm to revoke.
Revocation is immediate and permanent. The key is marked revoked in the database and all future requests with that key will receive a 401 Unauthorized response.
Scope TTLs
Each API key scope carries a different JWT TTL on the underlying identity token. This is separate from the 90-day physical key expiry — it is how long a single issued token is valid before the SDK must re-authenticate.
| Scope | Token TTL | Why |
|---|---|---|
read | 3600 s (1 hour) | Low-risk reads; longer window reduces re-auth overhead |
trade | 300 s (5 minutes) | Shorter window limits blast radius of a leaked trade token |
manage | 60 s (1 minute) | Step-up tokens are short-lived by design; expired tokens require a new step-up |
The SDK renews tokens automatically before expiry. If you are making raw HTTP requests you must handle re-authentication when you receive 401 Unauthorized.
Expiry and rotation
By default, keys expire 90 days after creation. This expiry is system-set and is not configurable at key creation time. You should rotate keys before they expire to avoid service interruption.
Recommended rotation process:
- Create the new key with the same scope and a versioned name (e.g., "My agent — v2")
- Update your agent's configuration to use the new key
- Verify the agent is working correctly with the new key
- Revoke the old key
Never rely on expiry as your only key management strategy. Rotate keys proactively whenever you change agent deployments, suspect a key has been exposed, or onboard a new team member who should not have access to old credentials.
Using keys in HTTP requests
All MCP and API requests authenticate with the Authorization header using the Bearer scheme:
Authorization: Bearer balc_YOUR_SECRET_KEYMCP tool call example
curl https://api.balchemy.ai/mcp/YOUR_PUBLIC_ID \
-H "Authorization: Bearer balc_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "trading_portfolio_summary",
"arguments": {}
}
}'Using the Balchemy SDK
import { BalchemyAgentSdk } from "@balchemy/agent-sdk";
const sdk = new BalchemyAgentSdk({ apiBaseUrl: "https://api.balchemy.ai/api" });
const mcp = sdk.connectMcp({
endpoint: "https://api.balchemy.ai/mcp/YOUR_PUBLIC_ID",
apiKey: "balc_YOUR_SECRET_KEY",
});
// The SDK attaches the Authorization header to every request automatically
const summary = await mcp.callTool("trading_portfolio_summary", {});Rate limits
API key requests are subject to the following rate limits:
| Scope | Requests per minute | Requests per hour |
|---|---|---|
read | 120 | 3,000 |
trade | 60 | 1,000 |
manage | 30 | 500 |
Rate limit headers are included in every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1710000060
If you exceed the limit, you receive a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.
Security rules
Follow these rules to keep your agent integrations secure.
Never do this:
- Never expose API keys in client-side JavaScript, browser code, or mobile apps
- Never commit keys to version control, even in private repositories
- Never log the full key value in application logs
- Never share keys between production and staging environments
Always do this:
- Store keys in a secrets manager (AWS Secrets Manager, HashiCorp Vault, environment variables injected at runtime)
- Use the minimum scope required for the agent's function
- Set a meaningful key name that identifies the agent and environment
- Rotate keys on a regular schedule (at least every 90 days, ideally every 30)
- Revoke keys immediately when a team member leaves or an agent is decommissioned
Configuration reference
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable key name |
scope | "read" | "trade" | "manage" | Yes | Access scope for the key |
stepUpToken | string | Manage only | Short-lived token from step-up verification |
expiresAt | string | System-set | ISO 8601 expiry date; system-set to 90 days from creation, not user-configurable |
Error handling
| Error | HTTP status | Cause | Resolution |
|---|---|---|---|
API key lacks required scope | 403 Forbidden | Key scope is lower than the tool requires | Use a key with the correct scope or create a new one |
Unauthorized | 401 Unauthorized | Key is invalid, revoked, or expired | Create a new key and update your agent configuration |
Verification failed | 400 Bad Request | Incorrect 6-digit TOTP code for manage scope | Check your authenticator app and retry |
Backend did not return a one-time secret | UI error | Backend issue during key creation | Retry creation; if the issue persists, check the logs |
Too Many Requests | 429 | Rate limit exceeded | Back off and retry after the Retry-After interval |