Agent Management
Bootstrap, manage, and govern AI agents — identity, lifecycle, delegation, and budget enforcement.
Agent Management
BrainstormRouter provides a complete agent identity and lifecycle system. Agents are first-class entities with profiles, budgets, delegation hierarchies, and lifecycle governance.
Bootstrap
POST /v1/agent/bootstrap
Create an agent profile, enforce budget limits, and mint a JWT — all in one call. Zero-human onboarding.
Auth: API key only (rejects SSO, agent-JWT, mTLS, SCIM).
Request body:
{
"agent_id": "my-agent-01",
"display_name": "Sales Assistant",
"cost_center": "sales-team",
"budget_daily_usd": 5.0,
"budget_monthly_usd": 100.0,
"metadata": { "can_delegate": true }
}
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | Yes | 3–64 chars, lowercase alphanumeric + hyphens |
display_name | string | No | Human-readable name |
cost_center | string | No | Business cost center tag |
budget_daily_usd | number | No | Daily budget cap |
budget_monthly_usd | number | No | Monthly budget cap |
metadata | object | No | Arbitrary key-value pairs |
Response (201 Created / 200 Idempotent):
{
"profile": {
"id": "uuid",
"tenantId": "uuid",
"agentId": "my-agent-01",
"displayName": "Sales Assistant",
"ownerId": null,
"costCenter": "sales-team",
"budgetDailyUsd": 5.0,
"budgetMonthlyUsd": 100.0,
"role": "agent",
"lifecycleState": "active",
"manifestId": null,
"parentAgentId": null,
"expiresAt": null,
"metadata": { "can_delegate": true },
"createdAt": "2026-03-10T00:00:00.000Z",
"updatedAt": "2026-03-10T00:00:00.000Z"
},
"jwt": "eyJ...",
"jwt_expires_at": "2026-03-10T01:00:00.000Z",
"budget": {
"profile_daily_usd": 5.0,
"profile_monthly_usd": 100.0,
"enforced_daily_usd": 5.0,
"enforced_rpm": 30
},
"next_steps": {
"completions": "POST /v1/chat/completions",
"self_status": "GET /v1/agent/status",
"memory": "POST /v1/memory/entries",
"delegate": "POST /v1/agent/delegate",
"cert_exchange": "POST /v1/agent/auth/cert",
"playbook": "https://brainstormrouter.com/llms-agent-playbook.txt"
}
}
Errors: 400 (invalid input), 401 (no API key), 403 (wrong auth method, suspended/terminated agent), 409 (concurrent conflict), 503 (limits write or JWT mint failed).
---
Self-Awareness
GET /v1/agent/status
Full self-awareness: profile, limits, anomaly events, and governance state.
Auth: Agent JWT or mTLS.
Response (200):
{
"profile": { "...AgentProfile" },
"limits": {
"profile_daily_usd": 5.0,
"profile_monthly_usd": 100.0,
"enforced_daily_usd": 5.0,
"enforced_daily_spent_usd": 1.23,
"enforced_daily_remaining_usd": 3.77,
"enforced_rpm": 30,
"requests_this_minute": 5
},
"anomaly": {
"recent_events": []
},
"governance": {
"lifecycle_state": "active",
"manifest_id": null,
"role": "agent"
}
}
GET /v1/agent/limits/me
Budget and rate limit subset only.
Auth: Agent JWT or mTLS.
Response (200):
{
"limits": {
"profile_daily_usd": 5.0,
"profile_monthly_usd": 100.0,
"enforced_daily_usd": 5.0,
"enforced_daily_spent_usd": 1.23,
"enforced_daily_remaining_usd": 3.77,
"enforced_rpm": 30,
"requests_this_minute": 5
}
}
GET /v1/agent/anomaly/me
Recent security and anomaly events for the calling agent.
Auth: Agent JWT or mTLS.
Response (200):
{
"events": []
}
---
Profiles
GET /v1/agent/profiles
List all agent profiles in the tenant.
Auth: Admin, operator, or auditor (requires agent.profile.read).
Response (200):
{
"profiles": [{ "...AgentProfile" }],
"total": 3
}
POST /v1/agent/profiles
Create an agent profile directly (without JWT minting — use bootstrap for full onboarding).
Auth: Admin or operator.
Request body:
{
"agentId": "my-agent-01",
"displayName": "Sales Assistant",
"ownerId": "user-123",
"costCenter": "sales-team",
"budgetDailyUsd": 5.0,
"budgetMonthlyUsd": 100.0,
"role": "agent",
"metadata": {}
}
Response (201): { "profile": { ...AgentProfile } }
Errors: 400 (missing agentId), 409 (already exists).
GET /v1/agent/profiles/me
Self-read for agent-authenticated callers.
Auth: Agent JWT or mTLS.
Response (200): { "profile": { ...AgentProfile } }
GET /v1/agent/profiles/:agentId
Read a single profile.
Auth: Admin, operator, or auditor (requires agent.profile.read).
Response (200): { "profile": { ...AgentProfile } }
PATCH /v1/agent/profiles/:agentId
Update profile fields (partial update).
Auth: Admin or operator.
Request body (all fields optional):
{
"displayName": "New Name",
"ownerId": "user-456",
"costCenter": "eng-team",
"budgetDailyUsd": 10.0,
"role": "operator",
"metadata": { "can_delegate": true }
}
Response (200): { "profile": { ...AgentProfile } }
DELETE /v1/agent/profiles/:agentId
Delete an agent profile (hard delete).
Auth: Admin.
Response (200): { "ok": true, "agentId": "my-agent-01" }
---
Lifecycle
PATCH /v1/agent/profiles/lifecycle/:agentId
Transition an agent's lifecycle state.
Auth: Requires agent.lifecycle.manage permission.
Request body:
{
"state": "quarantined"
}
Valid transitions:
active → quarantined, suspended
quarantined → active, suspended
suspended → active, terminated
terminated → (none — terminal state)
Response (200): { "profile": { ...AgentProfile } }
Errors: 400 (missing/invalid state), 403 (permission denied), 409 (invalid transition).
---
Delegation
POST /v1/agent/delegate
Parent agent creates a child agent with a sliced budget.
Auth: Agent JWT only. Parent must be active with metadata.can_delegate === true.
Request body:
{
"agent_id": "child-worker-01",
"budget_allocation_usd": 1.0,
"requested_role": "agent",
"requested_name": "Worker 1",
"ttl_seconds": 3600,
"metadata": {}
}
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | Yes | Child agent identifier |
budget_allocation_usd | number | Yes | Budget sliced from parent (parent retains ≥$0.01) |
requested_role | string | No | Must be ≤ parent role (no escalation) |
requested_name | string | No | Display name for child |
ttl_seconds | number | No | Time-to-live before auto-termination |
metadata | object | No | Merged with parentAgentId |
Response (201/200): Same shape as bootstrap response.
Errors: 400 (invalid input, no budget), 402 (insufficient budget), 403 (wrong auth, not active, no delegation, role escalation).
---
Sub-Agents
GET /v1/agent/sub-agents
List the caller's non-terminated child agents (all lifecycle states except terminated).
Auth: Agent JWT.
Response (200):
{
"sub_agents": [
{
"agent_id": "child-worker-01",
"display_name": "Worker 1",
"role": "agent",
"budget_daily_usd": 1.0,
"lifecycle_state": "active",
"expires_at": "2026-03-10T01:00:00.000Z",
"created_at": "2026-03-10T00:00:00.000Z"
}
],
"total": 1
}
DELETE /v1/agent/sub-agents/:child_agent_id
Terminate a child agent and reclaim unspent budget.
Auth: Agent JWT. Caller must be the parent.
Response (200):
{
"ok": true,
"terminated_agent_id": "child-worker-01",
"budget_refunded_usd": 0.43
}
If already terminated: { "ok": true, "terminated_agent_id": "...", "budget_refunded_usd": 0, "already_terminated": true }
---
Agent Limits (Tenant Administration)
These endpoints manage the tenant-wide agent enforcement limits map. They are tenant configuration endpoints, not individual agent operations. Keys must use the agent: prefix format for enforcement to apply at runtime (the route accepts any string key, but only prefixed keys match agent identity resolution). These endpoints are not wrapped by either SDK and must be called via direct HTTP or managed through tenant settings.
GET /v1/agent-limits
Read the tenant's agent enforcement limits map.
Auth: Admin or operator.
Response (200):
{
"agentLimits": {
"agent:my-agent-01": {
"maxBudgetUsd": 5.0,
"maxRequestsPerMinute": 30
}
}
}
PUT /v1/agent-limits
Replace the entire limits map.
Auth: Admin or operator. Requires database.
Request body: Object mapping agent: keys to limit objects:
{
"agent:my-agent-01": {
"maxBudgetUsd": 10.0,
"maxRequestsPerMinute": 60
}
}
Response (200): { "agentLimits": { ... }, "version": 7 }
PATCH /v1/agent-limits
Merge limits (set a key to null to delete an entry).
Auth: Admin or operator. Requires database.
Request body: Partial limit object using agent: keys:
{
"agent:my-agent-01": {
"maxBudgetUsd": 15.0
},
"agent:old-agent": null
}
Response (200): { "agentLimits": { ... }, "version": 8 }