Update a registered app
The apps.update operation: PATCH /api/v1/apps/{id} in the REST API and the apps_update tool in the MCP server.
/api/v1/apps/{id}Changes a registered app's name, publisher, links, redirect URIs, visibility, scopes or whether every token must
be DPoP-bound (dpopBoundAccessTokens). Send only what changes; null removes a link. Narrower scopes apply to
the app's tokens at once in every installation; wider scopes need the organizations' consent again.
For listed apps (see apps.listing.get): visibility: "listed" waits for an application
(apps.listing.submit); "private" ends the listing. On an approved app, scopes beyond the approved ones go to
review again (pending): the app stays listed for its approved scopes, other organizations can consent only to
those, and installations keep the scopes they consented to until the new ones are approved and consented. A new
name or publisher of an approved app is reviewed again before the app is listed again.
At a glance
- REST:
PATCH /api/v1/apps/{id} - MCP tool:
apps_update - Operation ID:
apps.update - Scope: Organization
- Permission:
agents:admin - Risk tier:
security - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyoptional - Modes: Test and live
- Authentication: API key with the
agents:adminscope - Since: M10
Request
Path parameters
| Field | Type | Description |
|---|---|---|
id | ocl_… ID |
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | |
publisher | string | No | |
logoUrl | string or null | No | |
websiteUrl | string or null | No | |
privacyPolicyUrl | string or null | No | |
redirectUris | array of string | No | |
visibility | one of private, listed | No | |
scopes | array of one of 84 values, e.g. org:read, org:write, org:admin (all in the OpenAPI document) | No | |
dpopBoundAccessTokens | boolean | No | Require DPoP for every token: a token request without a DPoP proof is refused (RFC 9449). |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
id | ocl_… ID | |
object | "app" | |
ownerOrgId | org_… ID | |
name | string | |
publisher | string | |
logoUrl | string or null | |
websiteUrl | string or null | |
privacyPolicyUrl | string or null | |
redirectUris | array of string | |
type | one of confidential, public | |
visibility | one of private, listed | |
review | object | |
review.status | one of not_submitted, pending, changes_requested, approved, rejected | |
review.at | string or null | |
verified | boolean | |
scopes | array of one of 84 values, e.g. org:read, org:write, org:admin (all in the OpenAPI document) | |
secretPrefix | string or null | |
dpopBoundAccessTokens | boolean | |
status | one of active, disabled | |
suspension | object or null | |
createdAt | string | |
updatedAt | string |
Examples
Add a redirect URI
PATCH /api/v1/apps/ocl_01m4ttwd3veh9apbewxheq5xha
Authorization: Bearer or_test_…
Content-Type: application/json
{
"redirectUris": [
"https://ledgerly.example/oauth/callback",
"https://eu.ledgerly.example/oauth/callback"
]
}
Response (200):
{
"id": "ocl_01m4ttwd3veh9apbewxheq5xha",
"object": "app",
"ownerOrgId": "org_01m4ttwd3veh9apbewxheq5xhb",
"name": "Ledgerly AI",
"publisher": "Ledgerly AI B.V.",
"logoUrl": null,
"websiteUrl": "https://ledgerly.example",
"privacyPolicyUrl": "https://ledgerly.example/privacy",
"redirectUris": ["https://ledgerly.example/oauth/callback", "https://eu.ledgerly.example/oauth/callback"],
"type": "confidential",
"visibility": "listed",
"review": {
"status": "approved",
"at": "2026-10-25T09:00:00.000Z"
},
"verified": true,
"scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write", "ledger:read"],
"secretPrefix": "or_cs_Exampl",
"dpopBoundAccessTokens": false,
"status": "active",
"suspension": null,
"createdAt": "2026-10-25T09:00:00.000Z",
"updatedAt": "2026-10-26T14:30:00.000Z"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A field is invalid. | Fix the fields listed in details.issues and send the request again. |
oauth_client_disabled | 409 | The app is disabled. | Register a new app, or create a new agent. |
resource_not_found | 404 | Your organization registered no app with this ID. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
version_conflict | 409 | The app changed at the same moment; retry. | Fetch the object again and retry the change. |
permission_denied | 403 | You can't manage the organization's apps. | 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_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.