---
title: "Create Agent"
method: POST
path: "/agents"
tags: ["agents"]
---

# Create Agent

`POST /agents`

## Request

- Base URL: `https://api.instruxi.dev/api/v1/enforcer`
- URL: `https://api.instruxi.dev/api/v1/enforcer/agents`
- Auth: one of:
  - API key in header `Authorization`
  - API key in header `X-API-Key`

Creates the service account and the agent in one transaction. Mint fences (AGENTS_CONTRACT §5.3): the role may not exceed the caller's grants (403 role_exceeds_caller), must be in the tenant's allowed_role_ids unless the caller holds tenant_manage (403 role_not_allowed), must be covered by the steward's role (409 steward_role_too_low); requested scopes must be known (400 invalid_scope) and covered by a scoped caller (403 insufficient_scope); members may be barred by policy (403 agents_disabled_for_members); a steward holds at most max_agents_per_steward (409 agent_limit_reached); an agent or portal credential cannot mint (403 agent_cannot_mint); the steward must be a live human in the tenant (422 invalid_steward). The steward is the caller unless the caller holds tenant_manage (403 transfer_consent_required).

## Request body

- InternalDeliveryHttpHandlerCreateAgentRequest
  - `card` object
  - `description` string
  - `expires_at` string
  - `name` string
  - `owner` InternalDeliveryHttpHandlerAgentOwnerRef
    - `id` string: ID is the owner. For kind=account it may be omitted (the steward).
    - `kind` 'account' | 'group'
  - `rate_limit_per_min` integer
  - `role_id` string
  - `scopes` string[]
  - `slug` string
  - `steward_account_id` string: StewardAccountID is required for a group-owned agent; for an account-owned one it defaults to the caller. It must be the caller, or the caller must hold tenant_manage.

## Response `201`

Created

- InternalDeliveryHttpHandlerAgentResponse
  - `data` EnforcerV3InternalUsecaseAgentsView
    - `card` object
    - `created_at` string
    - `created_by` string
    - `credentials` EnforcerV3InternalUsecaseAgentsCredentialRollup
      - `active` integer
      - `expiring_within_7d` integer
      - `last_used_at` string
    - `description` string
    - `effective_permissions` EnforcerV3InternalAuthzPermissions
      - `admin_managed` boolean: read/write/manage admin-managed types in tenant
      - `cross_tenant` boolean: every row, every tenant (admin)
      - `mpp_ops` boolean: MPPOps is a NARROW operator grant: read the MPP deposit-intent queue and its settle plans across tenants (GET /admin/mpp-deposit-intents...). It moves no money (the settle/refund levers stay PlatformOnly) and the policy never reads it: no row anywhere else becomes visible through it.
      - `tenant_manage` boolean: manage any non-admin-managed row in tenant
      - `tenant_read` boolean: read any non-admin-managed row in tenant
      - `tenant_write` boolean: write any non-admin-managed row in tenant
    - `expires_at` string
    - `groups` EnforcerV3InternalUsecaseAgentsGroupRef[]
      - `id` string
      - `name` string
      - `slug` string
    - `id` string
    - `name` string
    - `owner` EnforcerV3InternalUsecaseAgentsOwnerView
      - `id` string
      - `kind` 'account' | 'group'
      - `name` string
    - `rate_limit_per_min` integer
    - `role` EnforcerV3InternalUsecaseAgentsRoleView
      - `id` string
      - `permissions` EnforcerV3InternalAuthzPermissions
        - `admin_managed` boolean: read/write/manage admin-managed types in tenant
        - `cross_tenant` boolean: every row, every tenant (admin)
        - `mpp_ops` boolean: MPPOps is a NARROW operator grant: read the MPP deposit-intent queue and its settle plans across tenants (GET /admin/mpp-deposit-intents...). It moves no money (the settle/refund levers stay PlatformOnly) and the policy never reads it: no row anywhere else becomes visible through it.
        - `tenant_manage` boolean: manage any non-admin-managed row in tenant
        - `tenant_read` boolean: read any non-admin-managed row in tenant
        - `tenant_write` boolean: write any non-admin-managed row in tenant
      - `slug` string
    - `scopes` string[]
    - `service_account` EnforcerV3InternalUsecaseAgentsServiceAccountView
      - `active` boolean
      - `agent_id` string
      - `created_at` string
      - `created_by` string
      - `description` string
      - `email` string
      - `groups` EnforcerV3InternalUsecaseAgentsGroupRef[]
        - `id` string
        - `name` string
        - `slug` string
      - `id` string
      - `key_count` integer
      - `kind` string
      - `last_used_at` string
      - `name` string
      - `role` EnforcerV3InternalUsecaseAgentsRoleView
        - `id` string
        - `permissions` EnforcerV3InternalAuthzPermissions
          - `admin_managed` boolean: read/write/manage admin-managed types in tenant
          - `cross_tenant` boolean: every row, every tenant (admin)
          - `mpp_ops` boolean: MPPOps is a NARROW operator grant: read the MPP deposit-intent queue and its settle plans across tenants (GET /admin/mpp-deposit-intents...). It moves no money (the settle/refund levers stay PlatformOnly) and the policy never reads it: no row anywhere else becomes visible through it.
          - `tenant_manage` boolean: manage any non-admin-managed row in tenant
          - `tenant_read` boolean: read any non-admin-managed row in tenant
          - `tenant_write` boolean: write any non-admin-managed row in tenant
        - `slug` string
      - `slug` string
      - `tenant_id` string
      - `updated_at` string
    - `slug` string
    - `state` 'active' | 'disabled' | 'suspended'
    - `state_reason` string
    - `steward` EnforcerV3InternalUsecaseAgentsStewardView
      - `account_id` string
      - `email` string
      - `name` string
    - `tenant_id` string
    - `updated_at` string
  - `success` boolean

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `409`: Conflict
- `422`: Unprocessable Entity

---

[API](https://skmtc.dev/instruxi/apis/enforcer-api.md) · [All operations](https://skmtc.dev/instruxi/apis/enforcer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/instruxi/apis/enforcer-api/revisions/fa82bc1becc0?raw)
