Skip to content

App installations tools

MCP tools for App installations: app_installations_activity, app_installations_create, app_installations_create_agent, app_installations_get, app_installations_list, app_installations_pause, app_installations_reassign, app_installations_resume, app_installations_revoke, app_installations_update.

  • app_installations_activity: List an installed app's activity
  • app_installations_create: Install an app (consent)
  • app_installations_create_agent: Ask for an agent the app owns
  • app_installations_get: Get an installed app
  • app_installations_list: List installed apps
  • app_installations_pause: Pause an installed app
  • app_installations_reassign: Re-assign an installed app
  • app_installations_resume: Resume a paused app
  • app_installations_revoke: Uninstall an app
  • app_installations_update: Narrow an installed app's access

app_installations_activity

List an installed app's activity. Operation app_installations.activity · Organization level · permission audit:read · risk tier read · since M10

The installed app's activity feed in this organization, newest first, from the audit log: every change it made (outcome: "succeeded"), every call that asked for approval instead of running (approval_requested, with the approval's current status), and every run a person approved (ran_after_approval), each with the operation, its target, the mode, the entity or brand, the surface (via), the app's OAuth client and the installer the call was attributed to (onBehalfOfUserId). Reads aren't in the audit log, so they aren't listed. Both modes are listed; usage is today's use (UTC) of its daily limits in the request's mode. Paginate with limit (1–100, default 10) and starting_after.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
limitintegerno(1–100)
starting_afterID (aud_…)no–
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Example

A refund above the daily limit, approved and run

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc"
}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "object": "activity_entry",
      "livemode": false,
      "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
      "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
      "via": "mcp",
      "clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
      "onBehalfOfUserId": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "appInstallationId": null,
      "id": "aud_01m4ttwd3veh9apbewxheq5xhh",
      "at": "2026-10-26T15:02:11.000Z",
      "action": "refunds.create",
      "operationId": "refunds.create",
      "target": "re_01m4ttwd3veh9apbewxheq5xhj",
      "outcome": "ran_after_approval",
      "approval": {
        "id": "apr_01m4ttwd3veh9apbewxheq5xhk",
        "status": "executed",
        "approvedBy": ["usr_01m4ttwd3veh9apbewxheq5xh7"]
      }
    },
    {
      "object": "activity_entry",
      "livemode": false,
      "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
      "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
      "via": "mcp",
      "clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
      "onBehalfOfUserId": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "appInstallationId": null,
      "id": "aud_01m4ttwd3veh9apbewxheq5xhf",
      "at": "2026-10-26T14:30:00.000Z",
      "action": "approvals.request",
      "operationId": "refunds.create",
      "target": "apr_01m4ttwd3veh9apbewxheq5xhk",
      "outcome": "approval_requested",
      "approval": {
        "id": "apr_01m4ttwd3veh9apbewxheq5xhk",
        "status": "executed",
        "approvedBy": ["usr_01m4ttwd3veh9apbewxheq5xh7"]
      }
    },
    {
      "object": "activity_entry",
      "livemode": false,
      "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
      "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
      "via": "mcp",
      "clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
      "onBehalfOfUserId": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "appInstallationId": null,
      "id": "aud_01m4ttwd3veh9apbewxheq5xhg",
      "at": "2026-10-26T14:10:00.000Z",
      "action": "refunds.create",
      "operationId": "refunds.create",
      "target": "re_01m4ttwd3veh9apbewxheq5xhm",
      "outcome": "succeeded",
      "approval": null
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "usage": {
    "day": "2026-10-26",
    "livemode": false,
    "mutations": 2,
    "amounts": [
      {
        "operationId": "refunds.create",
        "amount": {
          "amount": "450000000",
          "currency": "EUR"
        }
      }
    ]
  }
}

app_installations_create

Install an app (consent). Operation app_installations.create · Organization level · permission agents:admin · risk tier security · since M10

Installs a partner app in the organization with the scopes you consent to, optionally limited to some legal entities or brands (limitTo; none = the whole organization). The consent screen calls it when an organization owner or admin approves an app's authorization request; grantId is that request's grant.

The app then acts in the organization as the installation, attributed to you, with at most your own access, re-checked on every call. By installing it, the organization instructs Ownrecord to disclose the data in these scopes to the app's publisher. Installing an app that is already installed updates its scopes and limitTo and makes you its installer. Private apps install only in the organization that registered them.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
clientIdID (ocl_…)yes–
grantIdID (ogr_…)yes–
scopesarray of one of 84 values, e.g. org:read, org:write, org:adminyes(1–200 items)
limitToobjectno–
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Install for one legal entity

Arguments:

JSON
{
  "clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
  "grantId": "ogr_01m4ttwd3veh9apbewxheq5xhd",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"]
  },
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "active",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-25T09:00:00.000Z"
}

app_installations_create_agent

Ask for an agent the app owns. Operation app_installations.create_agent · Organization level · permission agents:admin · risk tier security · since M13

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.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yesThe calling app's installation in this organization.
namestringyes(1–100 characters)
descriptionstringno(1–500 characters)
contactstringnoWho to contact about the agent (default: none). (1–500 characters)
vendorstringnoModel or vendor description (default: the app's publisher). (1–500 characters)
roleone of org_admin, billing_admin, finance, tax_manager, support, developer, vieweryes–
scopeobject or object or objectno(default {"type":"org"})
livemodeAccessbooleanno(default false)
scopesarray of one of 84 values, e.g. org:read, org:write, org:adminno(1–200 items)
jwksobjectyesThe agent's public keys for private_key_jwt client authentication.
limitsobjectno–
toolSetsarray of stringno(at most 20 items)
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

A filing agent for the whole organization (after approval)

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "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"
      }
    ]
  },
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

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"
  }
}

app_installations_get

Get an installed app. Operation app_installations.get · Organization level · permission agents:read · risk tier read · since M10

Returns one app installation of the organization: the app, the installer, scopes, limitTo and status.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Example

An installation

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "active",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-25T09:00:00.000Z"
}

app_installations_list

List installed apps. Operation app_installations.list · Organization level · permission agents:read · risk tier read · since M10

Lists the apps installed in the organization, newest first: the app and its publisher (verified or not), who installed it, the scopes granted, limitTo and the status. Filter by status; paginate with limit and starting_after.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
limitintegerno(1–100)
starting_afterID (ains_…)no–
statusone of active, paused, revokedno–
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Examples

Installed apps

Arguments:

JSON
{}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
      "object": "app_installation",
      "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
      "app": {
        "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
        "name": "Ledgerly AI",
        "publisher": "Ledgerly AI B.V.",
        "logoUrl": null,
        "verified": true,
        "status": "active",
        "suspension": null
      },
      "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
      "limitTo": {
        "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
        "brandIds": []
      },
      "limits": {
        "rps": null,
        "mutationsPerDay": null,
        "amountLimits": []
      },
      "status": "active",
      "pausedReason": null,
      "pausedAt": null,
      "revokedAt": null,
      "createdAt": "2026-10-25T09:00:00.000Z",
      "updatedAt": "2026-10-25T09:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Paused installations, one per page

Arguments:

JSON
{
  "status": "paused",
  "limit": 1
}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
      "object": "app_installation",
      "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
      "app": {
        "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
        "name": "Ledgerly AI",
        "publisher": "Ledgerly AI B.V.",
        "logoUrl": null,
        "verified": true,
        "status": "active",
        "suspension": null
      },
      "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
      "limitTo": {
        "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
        "brandIds": []
      },
      "limits": {
        "rps": null,
        "mutationsPerDay": null,
        "amountLimits": []
      },
      "status": "paused",
      "pausedReason": "installer_lost_access",
      "pausedAt": "2026-10-26T14:30:00.000Z",
      "revokedAt": null,
      "createdAt": "2026-10-25T09:00:00.000Z",
      "updatedAt": "2026-10-26T14:30:00.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "ains_01m4ttwd3veh9apbewxheq5xhc"
}

app_installations_pause

Pause an installed app. Operation app_installations.pause · Organization level · permission agents:admin · risk tier security · since M10

Pauses an installed app: its access tokens and refresh tokens stop working in the organization at once, and it can't act there until resumed (app_installations.resume), after which it must ask for authorization again. Pausing a paused app changes nothing (one paused because its installer left stays so, keeping its tokens for after the re-assignment).

Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Pause an app

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "paused",
  "pausedReason": "manual",
  "pausedAt": "2026-10-26T14:30:00.000Z",
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-26T14:30:00.000Z"
}

app_installations_reassign

Re-assign an installed app. Operation app_installations.reassign · Organization level · permission agents:admin · risk tier security · since M10

Makes another organization owner or admin the installer of an app: its calls are attributed to them and limited to their access from now on. An installation paused because its installer left resumes, with the same tokens. The new installer must be an org_owner or org_admin of the organization.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
userIdID (usr_…)yes–
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Re-assign after the installer left

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "userId": "usr_01m4ttwd3veh9apbewxheq5xh7",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh7",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "active",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-26T14:30:00.000Z"
}

app_installations_resume

Resume a paused app. Operation app_installations.resume · Organization level · permission agents:admin · risk tier security · since M10

Resumes a paused installation. After a manual pause the app must ask for authorization again (its tokens were revoked). An installation paused because its installer left can only resume once its installer has access again: re-assign it instead (app_installations.reassign), which also resumes it. Resuming an active installation changes nothing; a revoked one can't be resumed.

While Ownrecord suspends the app (pausedReason: platform_suspended), it can't be resumed (app_suspended). After a reinstatement, resuming it is your decision; the app then asks for authorization again.

An app disabled by the organization that registered it (pausedReason: app_disabled) never resumes (oauth_client_disabled): uninstall it.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Resume an app

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "active",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-26T14:30:00.000Z"
}

app_installations_revoke

Uninstall an app. Operation app_installations.revoke · Organization level · permission agents:admin · risk tier security · since M10

Uninstalls an app from the organization: its tokens stop working there at once and the installation is kept as revoked with its audit trail. The app can be installed again later through the consent screen. Uninstalling an uninstalled app changes nothing.

Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Uninstall an app

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "revoked",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": "2026-10-26T14:30:00.000Z",
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-26T14:30:00.000Z"
}

app_installations_update

Narrow an installed app's access. Operation app_installations.update · Organization level · permission agents:admin · risk tier security · since M10

Changes what an installed app may do in the organization: fewer scopes (only scopes it already has; more need the app to ask for consent again), a different limitTo (entities or brands; empty lists = the whole organization), or its limits. Changes apply to the app's next call. A revoked installation can't be changed.

limits work as an agent's (spec §41.4): rps operation calls per second (agent_rate_limited), mutationsPerDay changes per UTC day and mode (agent_daily_limit_reached), and amountLimits per financial operation and currency (perCall, perDay; money as integer micros in a string): a call above them, or without an amount, creates an approval request instead of running. Send only what changes; null clears a value.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (ains_…)yes–
scopesarray of one of 84 values, e.g. org:read, org:write, org:adminno(1–200 items)
limitToobjectno–
limitsobjectno–
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

  • validation_failed: A scope isn't one the installation already has, or a limit can't work (e.g. an amount limit on an operation that moves no amount).
  • resource_not_found: No such installation, or an entity or brand in limitTo doesn't exist.
  • version_conflict: The installation changed at the same moment; retry.
  • permission_denied: You can't manage the organization's apps.

Examples

Read-only filings

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "scopes": ["filings:read", "tasks:read"],
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "tasks:read"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": null,
    "amountLimits": []
  },
  "status": "active",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-26T14:30:00.000Z"
}

Ten changes a day, refunds up to €100 a day

Arguments:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "limits": {
    "mutationsPerDay": 10,
    "amountLimits": [
      {
        "operationId": "refunds.create",
        "perDay": {
          "amount": "100000000",
          "currency": "EUR"
        }
      }
    ]
  },
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "ains_01m4ttwd3veh9apbewxheq5xhc",
  "object": "app_installation",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "app": {
    "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
    "name": "Ledgerly AI",
    "publisher": "Ledgerly AI B.V.",
    "logoUrl": null,
    "verified": true,
    "status": "active",
    "suspension": null
  },
  "installedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write"],
  "limitTo": {
    "entityIds": ["ent_01m4ttwd3veh9apbewxheq5xh4"],
    "brandIds": []
  },
  "limits": {
    "rps": null,
    "mutationsPerDay": 10,
    "amountLimits": [
      {
        "operationId": "refunds.create",
        "perCall": null,
        "perDay": {
          "amount": "100000000",
          "currency": "EUR"
        }
      }
    ]
  },
  "status": "active",
  "pausedReason": null,
  "pausedAt": null,
  "revokedAt": null,
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-10-26T14:30:00.000Z"
}