Skip to content

Suspend an app everywhere

The platform.apps.suspend operation: POST /api/v1/platform/apps/{id}/suspend in the REST API and the platform_apps_suspend tool in the MCP server.

POST/api/v1/platform/apps/{id}/suspend

Platform admins: suspends a registered app in every organization at once, for abuse or a compromise, with a reason. In one transaction:

  • every access and refresh token, authorization code and grant the app holds is deleted, in every organization, and so are the tokens of the agents it owns;
  • every installation that isn't uninstalled is paused (pausedReason: platform_suspended); its organization can't resume it while the suspension lasts (app_suspended);
  • from then on the OAuth server issues the app nothing (authorization code, refresh, client credentials, with or without DPoP), introspection reports its tokens inactive, the agents it owns are refused, and nothing installs it.

The organization that registered the app and every organization with it installed get an app.suspended event, and their owners and admins an email with the reason (they all read it; the admin isn't named). The platform audit chain records the app, the reason and every organization concerned; each organization's own audit log records its installation's pause. Suspending a suspended app changes nothing. platform.apps.reinstate lifts it.

Security tier; needs a sign-in within the last 15 minutes.

At a glance

  • REST: POST /api/v1/platform/apps/{id}/suspend
  • MCP tool: platform_apps_suspend
  • Operation ID: platform.apps.suspend
  • Scope: Platform
  • Permission: platform: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 platform:admin scope
  • Fresh sign-in: In the console, a sign-in within the last 15 minutes
  • Since: M13

Request

Path parameters

FieldTypeDescription
idocl_… ID

Body

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

FieldTypeRequiredDescription
reasonstringYesWhy, in plain words. The app's organization and every organization that installed it read it.

Response

200 OK with a JSON object:

FieldTypeDescription
idocl_… ID
object"platform_app"
namestring
publisherstring
orgobject
org.idorg_… ID
org.slugstring
org.namestring
visibilityone of private, listed
listedboolean
reviewStatusone of not_submitted, pending, changes_requested, approved, rejected
statusone of active, disabled
suspensionobject or null
createdAtdate-time
updatedAtdate-time
logoUrlstring or null
websiteUrlstring or null
installationsobject
installations.organizationsinteger
installations.activeinteger
installations.pausedinteger
installations.pausedBySuspensioninteger
installations.revokedinteger
historyarray of object
history[].actionone of suspended, reinstated
history[].atdate-time
history[].byusr_… ID
history[].reasonstring
history[].organizationsinteger
history[].installationsPausedinteger or null
versioninteger

Examples

Suspend an app whose secret leaked

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

{
  "reason": "Its client secret was published in a public repository; tokens were used from unknown networks."
}

Response (200):

JSON
{
  "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
  "object": "platform_app",
  "name": "Ledgerly AI",
  "publisher": "Ledgerly AI B.V.",
  "org": {
    "id": "org_01m4ttwd3veh9apbewxheq5xhb",
    "slug": "ledgerly",
    "name": "Ledgerly"
  },
  "visibility": "listed",
  "listed": true,
  "reviewStatus": "approved",
  "status": "active",
  "suspension": {
    "status": "suspended",
    "reason": "Its client secret was published in a public repository; tokens were used from unknown networks.",
    "suspendedAt": "2026-11-01T08:30:00.000Z",
    "reinstatedAt": null,
    "reinstateReason": null,
    "suspendedBy": "usr_01m4ttwd3veh9apbewxheq5xhg",
    "reinstatedBy": null
  },
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-11-01T08:30:00.000Z",
  "logoUrl": null,
  "websiteUrl": "https://ledgerly.example",
  "installations": {
    "organizations": 12,
    "active": 0,
    "paused": 12,
    "pausedBySuspension": 12,
    "revoked": 2
  },
  "history": [
    {
      "action": "suspended",
      "at": "2026-11-01T08:30:00.000Z",
      "by": "usr_01m4ttwd3veh9apbewxheq5xhg",
      "reason": "Its client secret was published in a public repository; tokens were used from unknown networks.",
      "organizations": 12,
      "installationsPaused": 12
    }
  ],
  "version": 5
}

Errors

CodeHTTP statusWhenWhat to do
fresh_auth_required403Your last sign-in is older than 15 minutes: sign in again first.Sign in again, then repeat the action within 15 minutes.
validation_failed400No reason, or one longer than 2,000 characters.Fix the fields listed in details.issues and send the request again.
resource_not_found404No registered app has this ID (agents' and MCP clients aren't apps).Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
version_conflict409The app or one of its installations changed at the same moment; retry.Fetch the object again and retry the change.
permission_denied403You aren't a platform 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, rate_limited, internal_error.