Skip to content

Ask for an agent the app owns

The app_installations.create_agent operation: POST /api/v1/app_installations/{id}/agents in the REST API and the app_installations_create_agent tool in the MCP server.

POST/api/v1/app_installations/{id}/agents

Called by an installed app with its own access token: asks for an agent the app owns in the organization, for work that runs without the app's user session (for example a filing agent). It is a security operation, so the call always answers 202 with an approval request: an owner or admin of the organization (not the person who installed the app) approves it in the console, and the approved run creates the agent exactly as asked. Poll the approval (approvals.get) or watch approval.resolved; its resultRef is the new agent's ID, and agents.get returns its clientId.

The agent holds one role at a scope like a member, works in test mode unless livemodeAccess is asked for and the installer may use live mode, and its token scopes stay within the scopes the app was granted (default: everything the role can use among them). It authenticates with private_key_jwt only: give its public keys in jwks. Its calls are attributed to the agent, the app's installation and the person who installed the app; it stops when the app is paused or uninstalled, or the installer leaves the organization. id is your own installation (ains_…); an installation limited to some entities or brands can't ask for agents.

At a glance

  • REST: POST /api/v1/app_installations/{id}/agents
  • MCP tool: app_installations_create_agent
  • Operation ID: app_installations.create_agent
  • Scope: Organization
  • Permission: agents:admin
  • Risk tier: security
  • Dry run: Supported (send Ownrecord-Dry-Run: true)
  • Idempotency: Idempotency-Key required
  • Modes: Test and live
  • Authentication: API key with the agents:admin scope
  • Since: M13

Request

Path parameters

FieldTypeDescription
idains_… IDThe calling app's installation in this organization.

Body

A JSON object (Content-Type: application/json):

FieldTypeRequiredDescription
namestringYes
descriptionstringNo
contactstringNoWho to contact about the agent (default: none).
vendorstringNoModel or vendor description (default: the app's publisher).
roleone of org_admin, billing_admin, finance, tax_manager, support, developer, viewerYes
scopeobjectNo
livemodeAccessbooleanNo
scopesarray of one of 84 values, e.g. org:read, org:write, org:admin (all in the OpenAPI document)No
jwksobjectYesThe agent's public keys for private_key_jwt client authentication.
jwks.keysarray of objectYes
jwks.keys[].ktyone of RSA, EC, OKPYes
jwks.keys[].kidstringNo
jwks.keys[].use"sig"No
jwks.keys[].algstringNo
limitsobjectNo
limits.rpsinteger (1 to 10000) or nullNo
limits.mutationsPerDayinteger (0 to 10000000) or nullNo
limits.amountLimitsarray of objectNo
limits.amountLimits[].operationIdstringYes
limits.amountLimits[].perCallmoney or nullNo
limits.amountLimits[].perDaymoney or nullNo
toolSetsarray of stringNo

Response

201 Created with a JSON object:

FieldTypeDescription
agentobject
agent.idagt_… ID
agent.object"agent"
agent.orgIdorg_… ID
agent.namestring
agent.descriptionstring or null
agent.contactstring or null
agent.vendorstring or null
agent.ownerTypeone of org, app
agent.appInstallationIdains_… ID or null
agent.roleone of org_admin, billing_admin, finance, tax_manager, support, developer, viewer
agent.scopeobject
agent.livemodeAccessboolean
agent.limitsobject
agent.limits.rpsinteger or null
agent.limits.mutationsPerDayinteger or null
agent.limits.amountLimitsarray of object
agent.limits.amountLimits[].operationIdstring
agent.limits.amountLimits[].perCallmoney or null
agent.limits.amountLimits[].perDaymoney or null
agent.toolSetsarray of string
agent.statusone of active, paused, revoked
agent.clientIdocl_… ID
agent.authMethodone of client_secret_basic, client_secret_post, private_key_jwt
agent.secretPrefixstring or null
agent.dpopBoundAccessTokensboolean
agent.scopesarray of one of 84 values, e.g. org:read, org:write, org:admin (all in the OpenAPI document)
agent.createdBystring
agent.createdAtstring
agent.updatedAtstring
agent.pausedAtstring or null
agent.revokedAtstring or null
credentialsobject
credentials.clientIdocl_… ID
credentials.clientSecretstring or null
credentials.tokenEndpointstring
credentials.authMethodone of none, client_secret_basic, client_secret_post, private_key_jwt

Examples

A filing agent for the whole organization (after approval)

HTTP
POST /api/v1/app_installations/ains_01m4ttwd3veh9apbewxheq5xhc/agents
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json

{
  "name": "Ledgerly Filing Agent",
  "description": "Prepares and files the quarterly returns",
  "contact": "filings@ledgerly.example",
  "role": "finance",
  "scopes": [
    "filings:read",
    "filings:write",
    "tasks:read",
    "tasks:write"
  ],
  "jwks": {
    "keys": [
      {
        "kty": "EC",
        "crv": "P-256",
        "kid": "ledgerly-filing-1",
        "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
        "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
      }
    ]
  }
}

Response (201):

JSON
{
  "agent": {
    "id": "agt_01m4ttwd3veh9apbewxheq5xh8",
    "object": "agent",
    "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
    "name": "Ledgerly Filing Agent",
    "description": "Prepares and files the quarterly returns",
    "contact": "filings@ledgerly.example",
    "vendor": "Ledgerly AI B.V.",
    "ownerType": "app",
    "appInstallationId": "ains_01m4ttwd3veh9apbewxheq5xhc",
    "role": "finance",
    "scope": {
      "type": "org"
    },
    "livemodeAccess": false,
    "limits": {
      "rps": null,
      "mutationsPerDay": null,
      "amountLimits": []
    },
    "toolSets": [],
    "status": "active",
    "clientId": "ocl_01m4ttwd3veh9apbewxheq5xh9",
    "authMethod": "private_key_jwt",
    "secretPrefix": null,
    "dpopBoundAccessTokens": false,
    "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
    "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
    "createdAt": "2026-10-25T09:00:00.000Z",
    "updatedAt": "2026-10-25T09:00:00.000Z",
    "pausedAt": null,
    "revokedAt": null
  },
  "credentials": {
    "clientId": "ocl_01m4ttwd3veh9apbewxheq5xh9",
    "clientSecret": null,
    "tokenEndpoint": "https://ownrecord.io/oauth/token",
    "authMethod": "private_key_jwt"
  }
}

Errors

CodeHTTP statusWhenWhat to do
approval_required202Always for the app's own call: an owner or admin approves it in the console.Nothing ran yet. An approver reviews approval.summary and the dry-run result in the console (approval.approveUrl). Poll GET /approvals/{id} or watch for the approval.resolved event; sending the same request again with the same Idempotency-Key returns the same approval.
validation_failed400A field is invalid, e.g. a scope the app wasn't granted or the role can't use.Fix the fields listed in details.issues and send the request again.
agent_role_invalid400The role is org_owner, or isn't allowed at the scope's type.Choose a role other than org_owner, at a scope the role allows (org, entity or brand; see the role table in the docs).
agent_delegation_not_allowed403The agent would get a permission (or live access) the app doesn't have at its scope.Choose a narrower role, scope or token scopes, turn off live mode for the agent, or ask an organization owner to do it.
resource_not_found404The installation isn't the calling app's, or the scope's entity or brand doesn't exist.Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
app_installation_paused403The installation was paused before the approved run.An organization owner or admin can resume it under Organization → Agents & apps. If the member who installed it left, an owner must re-assign it first; calls then resume with the same tokens.
oauth_client_disabled409The app was disabled before the approved run.Register a new app, or create a new agent.
permission_denied403The caller isn't an installed app (people create agents with agents.create), or lacks agents:admin.Ask an organization owner or admin for a role or scope that allows this action.

It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.