Skip to content

Reinstate a suspended app

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

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

Platform admins: lifts the platform's suspension of an app (platform.apps.suspend), with a reason. The app can get tokens, be authorized and be installed again.

It doesn't resume any installation: each one stays paused until its organization resumes it (app_installations.resume, their decision), after which the app asks for authorization again. The organization that registered the app and every organization with it installed get an app.reinstated event, and their owners and admins an email saying so, with the reason. Reinstating an app that isn't suspended changes nothing.

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

At a glance

  • REST: POST /api/v1/platform/apps/{id}/reinstate
  • MCP tool: platform_apps_reinstate
  • Operation ID: platform.apps.reinstate
  • 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 the suspension ends. 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

Reinstate once the partner fixed it

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

{
  "reason": "The partner rotated its secret and confirmed the leak is closed."
}

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": "reinstated",
    "reason": "Its client secret was published in a public repository; tokens were used from unknown networks.",
    "suspendedAt": "2026-11-01T08:30:00.000Z",
    "reinstatedAt": "2026-11-03T16:00:00.000Z",
    "reinstateReason": "The partner rotated its secret and confirmed the leak is closed.",
    "suspendedBy": "usr_01m4ttwd3veh9apbewxheq5xhg",
    "reinstatedBy": "usr_01m4ttwd3veh9apbewxheq5xhg"
  },
  "createdAt": "2026-10-25T09:00:00.000Z",
  "updatedAt": "2026-11-03T16:00: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
    },
    {
      "action": "reinstated",
      "at": "2026-11-03T16:00:00.000Z",
      "by": "usr_01m4ttwd3veh9apbewxheq5xhg",
      "reason": "The partner rotated its secret and confirmed the leak is closed.",
      "organizations": 12,
      "installationsPaused": null
    }
  ],
  "version": 6
}

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.Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
version_conflict409The app 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.