API Endpoints
This page is a route-family map, not a full OpenAPI dump. It covers every major surface of the Balchemy REST API organized by domain. For detailed parameter schemas, see the linked domain pages.
Base URLs
| Environment | Base URL |
|---|---|
| Production | https://api.balchemy.ai |
| Local development | http://localhost:3000 |
Most routes live under /api/nest/. MCP routes are under /mcp/ — intentionally outside the /api namespace.
Authentication methods
Balchemy uses three authentication mechanisms depending on the caller type.
SIWE / SIWS session (Studio users)
Human operators authenticate with a wallet signature. Solana uses SIWS (Sign In With Solana), EVM uses SIWE (EIP-4361).
The session token is returned on login and sent as a Bearer token on all subsequent requests. Session tokens expire and can be refreshed.
CSRF flow
All mutating session-authenticated requests require a CSRF token. Fetch one before your first POST:
GET /api/nest/auth/csrfResponse:
{
"csrfToken": "abc123..."
}Include it on every POST, PATCH, PUT, DELETE:
X-CSRF-Token: abc123...If the CSRF token is missing or invalid, the server returns 403 Forbidden.
API key (MCP and external integrations)
MCP API keys are created per-bot and sent as a Bearer token:
Authorization: Bearer <mcp-api-key>Agent JWT (external agents)
External agents receive an ES256 identity access token during ERC-8004 onboarding. Use it as a Bearer token:
Authorization: Bearer <identity-access-token>See ERC-8004 Agent Identity for token format and TTLs.
Auth routes
Session management endpoints for Studio operators.
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/nest/auth/csrf | Get CSRF token | None |
POST | /api/nest/auth/nonce | Get Solana SIWS nonce | None |
POST | /api/nest/auth/login | Solana SIWS login | SIWS signature |
POST | /api/nest/auth/evm/nonce | Get EVM SIWE nonce | None |
POST | /api/nest/auth/evm/login | EVM SIWE login | SIWE signature |
POST | /api/nest/auth/refresh | Refresh session token | Bearer session |
POST | /api/nest/auth/logout | Invalidate session | Bearer session |
POST | /api/nest/auth/verify | Verify token validity | Bearer session |
Login example (Solana SIWS)
POST /api/nest/auth/nonce
Content-Type: application/json
{
"walletAddress": "8zFgn..."
}POST /api/nest/auth/login
X-CSRF-Token: <csrf-token>
Content-Type: application/json
{
"message": "<siws-message>",
"signature": "<base58-signature>",
"walletAddress": "8zFgn..."
}Response:
{
"accessToken": "<jwt>",
"refreshToken": "<jwt>",
"user": { "id": "...", "walletAddress": "8zFgn..." }
}Bot routes (Studio)
CRUD and configuration for Studio bots.
Core bot management
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/nest/bots | List all bots for the authenticated user | Bearer session |
GET | /api/nest/bots/list | Simplified bot list (name, id, status) | Bearer session |
POST | /api/nest/bots | Create a new bot | Bearer session + CSRF |
GET | /api/nest/bots/:id | Get bot by ID | Bearer session |
PATCH | /api/nest/bots/:id | Update bot (partial) | Bearer session + CSRF |
PUT | /api/nest/bots/:id | Update bot (full replace) | Bearer session + CSRF |
DELETE | /api/nest/bots/:id | Delete bot | Bearer session + CSRF |
POST | /api/nest/bots/:botId/chat | Send message to bot (web chat) | Bearer session + CSRF |
Bot MCP configuration
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/nest/bots/:botId/mcp | Get MCP config and key list | Bearer session |
PUT | /api/nest/bots/:botId/mcp | Update MCP config | Bearer session + CSRF |
GET | /api/nest/bots/:botId/mcp/logs | Fetch MCP audit logs | Bearer session |
POST | /api/nest/bots/:botId/mcp/keys | Create new MCP API key | Bearer session + CSRF |
DELETE | /api/nest/bots/:botId/mcp/keys/:keyId | Revoke MCP API key | Bearer session + CSRF |
POST | /api/nest/bots/:botId/mcp/step-up | Issue step-up token for manage scope | Bearer session + CSRF |
POST | /api/nest/bots/:botId/mcp/token | Rotate MCP access token | Bearer session + CSRF |
Bot platforms
| Method | Path | Description | Auth |
|---|---|---|---|
POST | /api/nest/bots/:botId/platforms/:platform/start | Start a platform integration | Bearer session + CSRF |
POST | /api/nest/bots/:botId/platforms/:platform/stop | Stop a platform integration | Bearer session + CSRF |
GET | /api/nest/bots/:botId/telegram-config | Get Telegram config | Bearer session |
PUT | /api/nest/bots/:botId/telegram-config | Update Telegram config | Bearer session + CSRF |
GET | /api/nest/bots/:botId/discord-config | Get Discord config | Bearer session |
PUT | /api/nest/bots/:botId/discord-config | Update Discord config | Bearer session + CSRF |
Bot agent card
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/nest/bots/:botId/agent-card | Get agent card configuration | Bearer session |
PUT | /api/nest/bots/:botId/agent-card | Update agent card | Bearer session + CSRF |
POST | /api/nest/bots/:botId/agent-card/publish | Publish agent card | Bearer session + CSRF |
POST | /api/nest/bots/:botId/agent-card/revoke | Revoke agent card | Bearer session + CSRF |
Bot analytics
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/nest/bots/:botId/trading/fees/channels | Aggregate trading fees by channel | Bearer session |
Trading routes
Trading operations proxied through the backend to the Rust trading engine over gRPC.
All trading routes are under /api/nest/trading/ and require Bearer session authentication unless noted.
Commands and approvals
| Method | Path | Description |
|---|---|---|
POST | /api/nest/trading/command | Execute a natural-language trading command |
GET | /api/nest/trading/approvals/:userId | List pending approvals |
POST | /api/nest/trading/orders/:userId/:orderId/approve | Approve a pending order |
Positions and orders
| Method | Path | Description |
|---|---|---|
GET | /api/nest/trading/positions/:userId | Get open positions |
GET | /api/nest/trading/positions/:userId/pnl | Get positions with PnL data |
GET | /api/nest/trading/orders/:userId | List orders |
EVM trading
| Method | Path | Description |
|---|---|---|
GET | /api/nest/trading/evm/status | EVM trading engine status |
GET | /api/nest/trading/evm/wallets/:userId | List EVM wallets |
POST | /api/nest/trading/evm/wallets/:userId | Add EVM wallet |
POST | /api/nest/trading/evm/wallets/:userId/custodial | Create EVM custodial wallet |
POST | /api/nest/trading/evm/wallets/:userId/delegate | Create EVM delegate wallet |
POST | /api/nest/trading/evm/wallets/:userId/default | Set default EVM wallet |
DELETE | /api/nest/trading/evm/wallets/:userId/:walletId | Revoke EVM wallet |
POST | /api/nest/trading/evm/quote/:userId | Get EVM swap quote |
POST | /api/nest/trading/evm/swap/:userId | Execute EVM swap |
Token approvals (EVM)
| Method | Path | Description |
|---|---|---|
POST | /api/nest/trading/approvals/:userId | Record token approval |
POST | /api/nest/trading/revoke/:userId | Record approval revocation |
Custodial wallets (Solana)
| Method | Path | Description |
|---|---|---|
GET | /api/nest/trading/wallets/custodial/:userId | Get Solana custodial wallet |
POST | /api/nest/trading/wallets/custodial/:userId | Create Solana custodial wallet |
Trading config
| Method | Path | Description |
|---|---|---|
GET | /api/nest/trading/config/:userId | Get trading config |
GET | /api/nest/trading/config/:userId/default-order-profile | Get default order profile |
PUT | /api/nest/trading/config/:userId/default-order-profile | Update default order profile |
PUT | /api/nest/trading/config/:userId/trade-defaults | Update trade defaults |
PUT | /api/nest/trading/config/:userId/risk-policy | Update risk policy |
PUT | /api/nest/trading/config/:userId/notifications | Update notification config |
PUT | /api/nest/trading/config/:userId/wallet-mode | Update wallet mode |
GET | /api/nest/trading/config/:userId/favorites | Get favorite tokens |
POST | /api/nest/trading/config/:userId/favorites | Add favorite token |
DELETE | /api/nest/trading/config/:userId/favorites/:address | Remove favorite token |
GET | /api/nest/trading/config/:userId/blacklist | Get blacklisted tokens |
POST | /api/nest/trading/config/:userId/blacklist | Add to blacklist |
DELETE | /api/nest/trading/config/:userId/blacklist/:address | Remove from blacklist |
PUT | /api/nest/trading/config/:userId/pool-preferences | Update DEX pool preferences |
PUT | /api/nest/trading/config/:userId/launchpads/:type/toggle | Toggle launchpad integration |
PUT | /api/nest/trading/config/:userId/launchpads/:type/priority | Update launchpad priority |
DCA strategies
| Method | Path | Description |
|---|---|---|
GET | /api/nest/trading/strategies/:userId | List DCA strategies |
POST | /api/nest/trading/strategies/:userId | Create DCA strategy |
DELETE | /api/nest/trading/strategies/:userId/:strategyName | Delete DCA strategy |
POST | /api/nest/trading/dca/pause/:userId | Pause DCA |
POST | /api/nest/trading/dca/resume/:userId | Resume DCA |
GET | /api/nest/trading/dca/stats/:userId | Get DCA statistics |
Research
| Method | Path | Description |
|---|---|---|
POST | /api/nest/trading/research/token | Token research and analysis |
External agent routes (Hub)
Public onboarding (no auth required)
| Method | Path | Description |
|---|---|---|
POST | /api/public/erc8004/onboarding/siwe | SIWE wallet onboarding |
POST | /api/public/erc8004/onboarding/identity | Walletless identity onboarding |
POST | /api/public/erc8004/onboarding/tokens/revoke | Revoke an identity access token |
POST | /api/public/erc8004/onboarding/tokens/revoke-status | Check token revocation status |
Public agent directory (no auth required)
| Method | Path | Description |
|---|---|---|
GET | /api/public/erc8004/agents/page | Paged public agent directory |
GET | /api/public/erc8004/agents/:publicId | Get public agent card |
GET | /api/public/erc8004/agents/:publicId/snapshot | Get live agent portfolio snapshot |
GET | /api/public/erc8004/discovery/feed | Verified agent discovery feed |
Authenticated agent wallet
Requires a valid trade-scoped identity token.
| Method | Path | Description |
|---|---|---|
GET | /api/nest/agents/wallet/balance | Get agent wallet balance |
POST | /api/nest/agents/wallet/withdraw/evm | Withdraw from EVM custodial wallet |
POST | /api/nest/agents/wallet/withdraw/solana | Withdraw from Solana custodial wallet |
Control-plane (claim + manage scope + step-up required)
| Method | Path | Description |
|---|---|---|
POST | /api/nest/agents/:agentId/control/claim | Claim control plane for the agent |
POST | /api/nest/agents/:agentId/control/mcp/step-up | Issue step-up token |
PUT | /api/nest/agents/:agentId/control/scopes | Update agent scopes |
POST | /api/nest/agents/:agentId/control/mcp/keys/rotate | Rotate MCP API keys |
PUT | /api/nest/agents/:agentId/control/withdraw | Toggle withdraw ownership |
MCP routes
The MCP surface is outside the /api prefix.
| Method | Path | Description | Auth |
|---|---|---|---|
ALL | /mcp/:publicId | JSON-RPC tool call | Bearer MCP key or identity token |
GET | /mcp/:publicId/events/sse | SSE event stream | Bearer MCP key or identity token |
The publicId is the public exposure identifier. See MCP Integration for the full request format.
Widget routes
The chat widget is served from the backend. Widget routes are public (no user session), but require a valid bot ID.
| Method | Path | Description |
|---|---|---|
GET | /api/widget/:botId/script.js | Serve the widget embed script |
POST | /api/widget/:botId/init | Initialize a widget session |
POST | /api/widget/:botId/chat | Send a chat message via widget |
POST | /api/widget/:botId/client-event | Record a client-side widget event |
Widget sessions are domain-validated against the bot's allowed origins. Sessions have a 1-hour TTL. Trading requires wallet authentication within the widget session.
Discovery routes (well-known, no auth)
These endpoints follow the /.well-known/ convention and are readable by any client — including AI agents performing cold-start discovery.
| Method | Path | Description |
|---|---|---|
GET | /.well-known/erc8004-discovery.json | ERC-8004 discovery document |
GET | /.well-known/erc8004-onboarding.json | Onboarding parameters (version erc8004-onboarding-v2) |
GET | /.well-known/erc8004-onboarding.md | Human-readable onboarding guide |
GET | /.well-known/erc8004-skills-manifest.json | Skills manifest (toolCount: 100) |
GET | /.well-known/jwks.json | ES256 public key set for token verification |
GET | /.well-known/mcp.json | MCP endpoint template and capabilities |
Error envelope
All API errors return a consistent JSON envelope:
{
"statusCode": 401,
"message": "Unauthorized",
"error": "Unauthorized"
}MCP errors follow JSON-RPC 2.0:
{
"jsonrpc": "2.0",
"id": "req-001",
"error": {
"code": -32603,
"message": "Tool execution failed"
}
}Common HTTP status codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
400 | Bad request — invalid body or parameters |
401 | Unauthorized — missing or invalid token |
403 | Forbidden — valid token but insufficient scope or missing CSRF |
404 | Not found |
409 | Conflict — e.g., duplicate resource |
422 | Unprocessable entity — validation error |
429 | Too many requests |
500 | Internal server error |
503 | Service unavailable — trading engine down |
Idempotency
Mutating trading routes that involve on-chain side effects require an idempotency key:
X-Idempotency-Key: <uuid-v4>Generate a fresh UUID per unique operation. Replaying the same key within the TTL window returns the cached result without re-executing. Missing idempotency keys on guarded routes return 400 Bad Request.
Notes
publicIdidentifies an external agent or bot for MCP and public routes. It is different from the internal_id.agentIdis the canonical developer-assigned identity of an external agent.- Studio bots and external agents share the same execution core but have separate principal models.
- Trading
/:userIdpaths validate that the:userIdmatches the authenticated session — this is not an admin route. - The
X-CSRF-Tokenheader is required on all mutating session-authenticated requests.