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 }
}
FieldTypeRequiredDescription
agent_idstringYes3–64 chars, lowercase alphanumeric + hyphens
display_namestringNoHuman-readable name
cost_centerstringNoBusiness cost center tag
budget_daily_usdnumberNoDaily budget cap
budget_monthly_usdnumberNoMonthly budget cap
metadataobjectNoArbitrary 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": {}
}
FieldTypeRequiredDescription
agent_idstringYesChild agent identifier
budget_allocation_usdnumberYesBudget sliced from parent (parent retains ≥$0.01)
requested_rolestringNoMust be ≤ parent role (no escalation)
requested_namestringNoDisplay name for child
ttl_secondsnumberNoTime-to-live before auto-termination
metadataobjectNoMerged 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 }