Documentation Index
Fetch the complete documentation index at: https://docs.steward.fi/llms.txt
Use this file to discover all available pages before exploring further.
Tenant Config (Control Plane)
The tenant control plane config lets platform operators customize the Steward experience for each tenant — which policies are editable, what the UI looks like, which features are enabled, and how approvals work.
This is the layer between a raw multi-tenant Steward deployment and a white-labeled platform-specific experience.
Base path: GET/PUT /tenants/:id/config
Auth: Tenant-level (X-Steward-Key)
Get Tenant Config
curl https://api.steward.fi/tenants/my-platform/config \
-H "X-Steward-Key: your-tenant-key"
Response:
{
"ok": true,
"data": {
"tenantId": "my-platform",
"displayName": "My Platform",
"policyExposure": {
"spending-limit": "visible",
"rate-limit": "enforced",
"approved-addresses": "hidden"
},
"policyTemplates": [...],
"secretRoutePresets": [...],
"approvalConfig": {
"autoExpireSeconds": 86400,
"approvers": { "mode": "owner" },
"webhookCallbackEnabled": true
},
"featureFlags": {
"showFundingQR": true,
"showTransactionHistory": true,
"showSpendDashboard": true,
"showPolicyControls": true,
"showApprovalQueue": true,
"showSecretManager": false,
"enableSolana": true,
"showChainSelector": false,
"allowAddressExport": true
},
"theme": {
"primaryColor": "#8B5CF6",
"accentColor": "#A78BFA",
"backgroundColor": "#0F0F0F",
"surfaceColor": "#1A1A2E",
"textColor": "#FAFAFA",
"colorScheme": "dark"
}
}
}
If no config has been saved, returns a default empty config (all features enabled, no policy restrictions).
Built-in defaults are available for: milady-cloud, milady-desktop, eliza-cloud.
Update Tenant Config
Full replace — any fields omitted default to their zero values.
curl -X PUT https://api.steward.fi/tenants/my-platform/config \
-H "X-Steward-Key: your-tenant-key" \
-H "Content-Type: application/json" \
-d '{
"displayName": "My Platform",
"policyExposure": {
"spending-limit": "visible",
"rate-limit": "enforced",
"approved-addresses": "hidden",
"auto-approve-threshold": "visible",
"time-window": "hidden"
},
"approvalConfig": {
"autoExpireSeconds": 86400,
"approvers": { "mode": "owner" },
"webhookCallbackEnabled": true
},
"featureFlags": {
"showFundingQR": true,
"showTransactionHistory": true,
"showSpendDashboard": true,
"showPolicyControls": true,
"showApprovalQueue": true,
"showSecretManager": false,
"enableSolana": true,
"showChainSelector": false,
"allowAddressExport": true
},
"theme": {
"primaryColor": "#FF6B35",
"colorScheme": "dark"
}
}'
Policy Exposure
policyExposure controls which policy types end users can see and edit in the <PolicyControls> component:
| Value | Behavior |
|---|
"visible" | Policy is shown and editable |
"enforced" | Policy is applied but hidden from end users |
"hidden" | Policy is not shown and not automatically applied |
{
"policyExposure": {
"spending-limit": "visible",
"rate-limit": "enforced",
"approved-addresses": "hidden",
"auto-approve-threshold": "visible",
"time-window": "hidden"
}
}
Policy Templates
Policy templates appear in the <PolicyControls> component as one-click starting points. Define them with customizable fields so users can tune limits without editing raw policy configs:
{
"policyTemplates": [
{
"id": "trading-agent",
"name": "Trading Agent",
"description": "For agents that trade on DEXs. Spending limits + approved routers.",
"icon": "chart-line",
"policies": [
{
"id": "tpl-spend",
"type": "spending-limit",
"enabled": true,
"config": {
"maxPerTx": "100000000000000000",
"maxPerDay": "1000000000000000000",
"maxPerWeek": "5000000000000000000"
}
}
],
"customizableFields": [
{
"path": "spending-limit.maxPerDay",
"label": "Daily Spending Limit",
"type": "currency",
"default": "1.0",
"min": "0.01",
"max": "100"
}
]
}
]
}
Secret Route Presets
Pre-configured route templates shown in the secret manager UI. Saves users from manually entering host/inject details for common APIs:
{
"secretRoutePresets": [
{
"id": "openai",
"name": "OpenAI API",
"hostPattern": "api.openai.com",
"pathPattern": "/*",
"injectAs": "bearer",
"injectKey": "Authorization",
"injectFormat": "Bearer {value}",
"provisioning": "platform"
},
{
"id": "anthropic",
"name": "Anthropic API",
"hostPattern": "api.anthropic.com",
"pathPattern": "/*",
"injectAs": "header",
"injectKey": "x-api-key",
"injectFormat": "{value}",
"provisioning": "user"
}
]
}
provisioning: "platform" means the platform provides the credential. provisioning: "user" means the end user provides their own key.
Approval Config
Controls how the approval workflow behaves for this tenant:
{
"approvalConfig": {
"autoExpireSeconds": 86400,
"approvers": { "mode": "owner" },
"webhookCallbackEnabled": true
}
}
| Field | Description |
|---|
autoExpireSeconds | How long pending approvals last before auto-expiry (0 = never) |
approvers.mode | Who can approve: "owner" (tenant admins), "tenant-admin" |
webhookCallbackEnabled | Whether to fire tx.pending webhooks for this tenant |
Feature Flags
Toggle UI features in @stwd/react components:
| Flag | Default | Description |
|---|
showFundingQR | true | Show QR code in <WalletOverview> |
showTransactionHistory | true | Enable <TransactionHistory> component |
showSpendDashboard | true | Enable <SpendDashboard> component |
showPolicyControls | true | Enable <PolicyControls> component |
showApprovalQueue | true | Enable <ApprovalQueue> component |
showSecretManager | false | Show secret management UI |
enableSolana | true | Show Solana address alongside EVM |
showChainSelector | false | Show chain-switching UI |
allowAddressExport | true | Allow copying/exporting wallet addresses |
Theme Config
Full color and typography control:
{
"theme": {
"primaryColor": "#8B5CF6",
"accentColor": "#A78BFA",
"backgroundColor": "#0F0F0F",
"surfaceColor": "#1A1A2E",
"textColor": "#FAFAFA",
"mutedColor": "#6B7280",
"successColor": "#10B981",
"errorColor": "#EF4444",
"warningColor": "#F59E0B",
"borderRadius": 12,
"fontFamily": "Inter, system-ui, sans-serif",
"colorScheme": "dark"
}
}
These map directly to the CSS custom properties in @stwd/react. Any fields not provided fall back to the component library defaults.