Agents API
Manage agents within your tenant. Each agent gets encrypted EVM and Solana wallets on creation.
Create Agent
Creates an agent with encrypted wallet keypairs.
Auth: Tenant API key
Request Body:
{
id: string; // Unique agent ID (1-128 alphanumeric, _ - . :)
name: string; // Display name
platformId?: string; // Optional external platform ID
}
Response:
{
"ok": true,
"data": {
"id": "my-agent",
"name": "My Trading Agent",
"tenantId": "your-tenant",
"walletAddresses": {
"evm": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
"solana": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
},
"createdAt": "2026-03-26T12:00:00.000Z"
}
}
const agent = await steward.createWallet("my-agent", "My Trading Agent");
List Agents
Returns all agents for the authenticated tenant.
Auth: Tenant API key
Response:
{
"ok": true,
"data": [
{
"id": "my-agent",
"name": "My Trading Agent",
"tenantId": "your-tenant",
"walletAddresses": { "evm": "0x742d...", "solana": "7xKXtg..." },
"createdAt": "2026-03-26T12:00:00.000Z"
}
]
}
const agents = await steward.listAgents();
Get Agent
Returns a single agent by ID.
Auth: Tenant API key or agent JWT
const agent = await steward.getAgent("my-agent");
Delete Agent
Permanently deletes an agent and all associated data (wallets, policies, transactions).
Auth: Tenant API key (agent tokens cannot delete)
Response:
{
"ok": true,
"data": { "deleted": "my-agent" }
}
This cascades: encrypted keys, wallet entries, policies, transactions, and approval queue items are all deleted. This cannot be undone.
curl -X DELETE https://api.steward.fi/agents/my-agent \
-H "X-Steward-Key: your-key"
Generate Agent Token
Creates a scoped JWT for agent-level operations.
POST /agents/:agentId/token
Auth: Tenant API key (agents cannot generate their own tokens)
Request Body:
{
expiresIn?: string; // JWT expiry (e.g., "24h", "7d"). Default: "24h"
}
Response:
{
"ok": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"agentId": "my-agent",
"tenantId": "your-tenant",
"scope": "agent",
"expiresIn": "24h"
}
}
curl -X POST https://api.steward.fi/agents/my-agent/token \
-H "X-Steward-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"expiresIn": "24h"}'
Get Account
Returns the agent’s aggregated digital-asset account, including wallet rows,
native balance, token portfolio assets, USD totals when pricing is configured,
spend summary, signing capabilities, and gas sponsorship state.
GET /agents/:agentId/account?chainId=8453&tokens=0xUSDC,0xDAI
Auth: Agent JWT or tenant key
Response:
{
"ok": true,
"data": {
"id": "my-agent",
"type": "agent",
"agentId": "my-agent",
"walletAddress": "0x742d35Cc...",
"wallets": [{ "chainFamily": "evm", "address": "0x742d35Cc..." }],
"portfolio": {
"chainId": 8453,
"native": { "symbol": "ETH", "formatted": "1.0", "usdValueText": "3000" },
"tokens": [],
"totalUsdText": "3000"
},
"capabilities": ["sign_transaction", "sign_message", "transfer"],
"sponsorship": { "enabled": false }
}
}
const account = await steward.getAgentAccount("my-agent", {
chainId: 8453,
tokens: ["0xUSDC..."],
});
Get Balance
Returns the native token balance for an agent’s wallet.
GET /agents/:agentId/balance?chainId=8453
Auth: Agent JWT or tenant key
Response:
{
"ok": true,
"data": {
"agentId": "my-agent",
"walletAddress": "0x742d35Cc...",
"balances": {
"native": "1000000000000000000",
"nativeFormatted": "1.0",
"chainId": 8453,
"symbol": "ETH"
}
}
}
const balance = await steward.getBalance("my-agent", 8453);
Get Token Balances
Returns ERC-20 token balances for an agent’s wallet.
GET /agents/:agentId/tokens?chainId=8453&tokens=0xUSDC,0xDAI
Auth: Agent JWT or tenant key
Response:
{
"ok": true,
"data": {
"agentId": "my-agent",
"walletAddress": "0x742d35Cc...",
"chainId": 8453,
"native": {
"symbol": "ETH",
"balance": "1000000000000000000",
"formatted": "1.0"
},
"tokens": [
{ "address": "0xUSDC...", "symbol": "USDC", "balance": "1000000", "formatted": "1.0" }
]
}
}
Authorization Keys and Key Quorums
Agent signers model owners, delegated signers, service signers, and quorum
members for an agent wallet. A signer with keyType: "p256" and a registered
publicKey is Steward’s Privy-style asymmetric authorization key. A signer with
keyType: "hmac" can instead receive a one-time delegated credential secret when
created with issueCredential: true.
GET /agents/:agentId/signers?status=active
POST /agents/:agentId/signers
PATCH /agents/:agentId/signers/:signerId
DELETE /agents/:agentId/signers/:signerId
Auth: Owner/admin browser session. Create, revoke, and authority-changing
updates require recent MFA.
Signer request body:
{
signerType: "owner" | "delegated" | "service" | "quorum_member";
subjectType: "user" | "wallet" | "api_key" | "external";
subjectId: string;
keyType?: "hmac" | "p256"; // default: "hmac"
publicKey?: string | null; // required for keyType: "p256"
address?: string | null;
chainFamily?: "evm" | "solana" | null;
label?: string | null;
permissions?: string[];
policyIds?: string[]; // policy rule ids on this same agent
metadata?: Record<string, unknown>;
issueCredential?: boolean; // hmac only; returns credentialSecret once
}
const key = await steward.createAuthorizationKey("my-agent", {
signerType: "delegated",
subjectType: "external",
subjectId: "ops-key-1",
keyType: "p256",
publicKey: "BASE64_SPKI_P256_PUBLIC_KEY",
permissions: ["sign_message", "sign_transaction"],
policyIds: ["policy_daily_limit"],
});
policyIds must reference policy rules on the same agent. Updating a signer’s
policy scope is an authority-changing operation and requires recent MFA:
await steward.updateAuthorizationKey("my-agent", key.id, {
status: "paused",
policyIds: ["policy_daily_limit", "policy_manual_review"],
});
Signer responses include id, signerType, subjectType, subjectId,
keyType, publicKey, permissions, policyIds, status, metadata,
hasCredential, and timestamps. credentialSecret is returned only on the
create response when issueCredential: true; it is never returned by list or
update calls.
Key quorums group signer IDs and optional child quorum IDs behind a threshold.
Nested quorum verification is bounded and fails closed on cycles or excessive
depth.
GET /agents/:agentId/key-quorums?status=active
POST /agents/:agentId/key-quorums
PATCH /agents/:agentId/key-quorums/:quorumId
DELETE /agents/:agentId/key-quorums/:quorumId
const quorum = await steward.createAgentKeyQuorum("my-agent", {
name: "Treasury approval",
threshold: 2,
memberSignerIds: ["signer-a"],
memberQuorumIds: ["child-quorum-a"],
permissions: ["sign_transaction"],
});
Batch Create
Create multiple agents in one request with optional shared policies.
Auth: Tenant API key
Request Body:
{
agents: Array<{ id: string; name: string; platformId?: string }>;
applyPolicies?: PolicyRule[]; // Applied to all created agents
}
Response:
{
"ok": true,
"data": {
"created": [/* AgentIdentity[] */],
"errors": [/* { id: string, error: string }[] */]
}
}
const result = await steward.createWalletBatch(
[
{ id: "agent-1", name: "Agent One" },
{ id: "agent-2", name: "Agent Two" },
],
[{ id: "limit", type: "spending-limit", enabled: true, config: { maxPerDay: "1000000000000000000" } }]
);