Skip to content

Install an app (consent)

The app_installations.create operation: POST /api/v1/app_installations in the REST API and the app_installations_create tool in the MCP server.

POST/api/v1/app_installations

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.

At a glance

  • REST: POST /api/v1/app_installations
  • MCP tool: app_installations_create
  • Operation ID: app_installations.create
  • 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: M10

Request

Body

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

FieldTypeRequiredDescription
clientIdocl_… IDYes
grantIdogr_… IDYes
scopesarray of one of 84 values, e.g. org:read, org:write, org:admin (all in the OpenAPI document)Yes
limitToobjectNo
limitTo.entityIdsarray of ent_… IDNo
limitTo.brandIdsarray of brd_… IDNo

Response

201 Created with a JSON object:

FieldTypeDescription
idains_… ID
object"app_installation"
orgIdorg_… ID
appobject
app.idocl_… ID
app.namestring
app.publisherstring
app.logoUrlstring or null
app.verifiedboolean
app.statusone of active, disabled
app.suspensionobject or null
installedByusr_… ID
scopesarray of one of 84 values, e.g. org:read, org:write, org:admin (all in the OpenAPI document)
limitToobject
limitTo.entityIdsarray of ent_… ID
limitTo.brandIdsarray of brd_… ID
limitsobject
limits.rpsinteger or null
limits.mutationsPerDayinteger or null
limits.amountLimitsarray of object
limits.amountLimits[].operationIdstring
limits.amountLimits[].perCallmoney or null
limits.amountLimits[].perDaymoney or null
statusone of active, paused, revoked
pausedReasonone of manual, installer_lost_access, platform_suspended, app_disabled or null
pausedAtstring or null
revokedAtstring or null
createdAtstring
updatedAtstring

Examples

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

{
  "clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
  "grantId": "ogr_01m4ttwd3veh9apbewxheq5xhd",
  "scopes": [
    "filings:read",
    "filings:write",
    "tasks:read",
    "tasks:write"
  ],
  "limitTo": {
    "entityIds": [
      "ent_01m4ttwd3veh9apbewxheq5xh4"
    ]
  }
}

Response (201):

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

Errors

CodeHTTP statusWhenWhat to do
validation_failed400A scope isn't one the app registered, or a field is invalid.Fix the fields listed in details.issues and send the request again.
app_not_installable400The app is private to another organization, or listed but not (yet) approved in platform review.Ask the app's publisher to list it: private apps install only in the organization that registered them, and other organizations can install a listed app once platform review has approved it.
app_scopes_not_approved403Another organization's listed app: a scope its approved listing doesn't cover (it waits for re-review).Consent only to the scopes platform review approved (details.approved). The others wait for the publisher's re-review; they can be added after it is approved.
oauth_client_disabled409The app is disabled.Register a new app, or create a new agent.
app_suspended409Ownrecord suspended the app: nothing installs it while the suspension lasts.The app can't be installed, resumed or authorized while the suspension lasts. Its organization's owners and admins, and those of every organization that installed it, were emailed the reason. Once Ownrecord reinstates it, resume its installation under Organization → Agents & apps.
oauth_grant_mismatch400The grant isn't yours or isn't the app's.Start the authorization again from the application.
resource_not_found404The app, or an entity or brand in limitTo, doesn't exist.Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
permission_denied403You can't install apps, or this isn't a signed-in person.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_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.