For AI agents: markdown of this page — /docs-content-en/apps/unpublish.md documentation index — /llms.txt

Unpublish

POST /v1/apps/:id/unpublish

Moves a published app to UNPUBLISHED and starts unbinding placements from the Bitrix24 account. A failure to unbind does not cancel unpublishing.

Parameters

Parameter Type Required Description
Parameterid (path) Typestring Requiredyes DescriptionIdentifier of an app in PUBLISHED status. List: GET /v1/apps

No request body is required — an empty body is allowed.

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/apps/YOUR_APP_ID/unpublish" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/apps/YOUR_APP_ID/unpublish" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — personal key

javascript
const res = await fetch(
  'https://vibecode.bitrix24.com/v1/apps/YOUR_APP_ID/unpublish',
  {
    method: 'POST',
    headers: { 'X-Api-Key': 'YOUR_API_KEY' },
  }
)
const body = await res.json()
if (!body.success) throw new Error(body.error.code)
console.log(body.data.placements)

JavaScript — OAuth application

javascript
const res = await fetch(
  'https://vibecode.bitrix24.com/v1/apps/YOUR_APP_ID/unpublish',
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)
const body = await res.json()
if (!body.success) throw new Error(body.error.code)
console.log(body.data.placements)

Response fields

Field Type Description
Fieldsuccess Typeboolean Descriptiontrue on a successful unpublish
Fielddata Typeobject DescriptionThe app after unpublish — the same set of fields returned by Application data
Fielddata.placements Typestring[] DescriptionPlacements whose removal was not confirmed. What an empty array means depends on the rollout — see the breakdown in the note below
Fielddata.catalogStatus Typestring DescriptionAfter unpublish — UNPUBLISHED
Fielddata.publishedAt Typestring | null DescriptionThe last publication date is kept — unpublishing does not reset it
Fieldwarnings Typestring[] DescriptionEntries explaining how the removal went. The field sits next to data, not inside it. The set of entries is open-ended — see the breakdown under the note below

The account-side removal check is currently rolling out per account, so there are two cases:

  • While the capability is not enabled on the account — unbinding runs without waiting for the result for each placement code, placements always arrives as an empty array, and warnings does not arrive at all. An empty list here means neither "the account confirmed the removal" nor "the unbind was sent": the list is cleared regardless of the outcome. There may be no removal transport available at all — for example, when the account was reconnected, when the app's token was revoked, or when refreshing it failed — in which case no unbind is sent and the binding survives the unpublish.
  • Once enabled — the platform waits for the account's response. Codes that could not be removed stay in placements, and the explanations arrive in warnings. After the access and application status checks pass, the operation returns 200 even if placements could not be removed. Determine the unbinding result by whether placements is empty, not by the 200 status or the presence of warnings.

A non-empty warnings array does not by itself mean that the operation failed. The entries come in four kinds, and two of them describe success: the removal was confirmed by the only available transport, the removal went through while one of the two transports refused the request, the code could not be removed, and there was no way to remove it. On an account with a single available transport — a cloud account without a developer key, for example — an entry arrives for EVERY placement removed normally. You do not need to parse these entries in code — they are meant for humans.

Response example

The data field mirrors the app object with an empty placements array — what an empty array means is covered in the note above:

JSON
{
  "success": true,
  "data": {
    "id": "33c4d5e6-f7a8-49b0-1234-5c6d7e8f9012",
    "title": "Sales dashboard",
    "description": null,
    "scopes": ["crm", "user", "placement"],
    "handlerUrl": "https://vibecode.bitrix24.com/v1/bitrix-handler",
    "appUrl": "https://app-abc12345.vibecode.bitrix24.com",
    "redirectUris": [
      "https://vibecode.bitrix24.com/oauth/complete",
      "http://localhost"
    ],
    "bitrixClientId": "local.7c3d4e5f6a7b80.55556666",
    "prefix": "vibe_app_local_7c3",
    "suffix": "6666",
    "authorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "authorBitrixUserId": 42,
    "authorBitrixUserIdSource": "member",
    "portalId": "8b1f0e2a-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
    "createdAt": "2026-06-24T09:12:45.781Z",
    "updatedAt": "2026-06-24T12:47:05.930Z",
    "placements": [],
    "catalogStatus": "UNPUBLISHED",
    "publishedAt": "2026-06-24T10:03:18.204Z"
  }
}

Removal was confirmed by the only available method. No placements remain, but warnings is present. The main fields are shown; for the full structure of data, see Application data:

JSON
{
  "success": true,
  "data": {
    "id": "f928148c-ad20-496c-a144-8420c5322353",
    "title": "Sales dashboard",
    "placements": [],
    "catalogStatus": "UNPUBLISHED",
    "publishedAt": "2026-10-06T11:11:35.325Z"
  },
  "warnings": [
    "LEFT_MENU: verified via devkey transport only"
  ]
}

Error response example

404 — the app is not published:

JSON
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Published app not found"
  }
}

Errors

HTTP Code Description
HTTP403 CodeINFRA_FORBIDDEN_FOR_COWORK_KEY DescriptionThe call was made with a Cowork/Code key — such a key works with data only and cannot perform write operations. To issue a key that can, see Project key for deploy
HTTP404 CodeNOT_FOUND DescriptionApp does not exist, belongs to another portal, or is not in PUBLISHED status
HTTP403 CodeFORBIDDEN DescriptionThe call was made with an authorization key vibe_app_… issued for a different application. Such a key unpublishes only its own application, even when both applications were created by the same author
HTTP403 CodeFORBIDDEN DescriptionRequest is not from the app author and not from a Bitrix24 account administrator
HTTP403 CodeWRITE_BLOCKED_READONLY_KEY DescriptionThe key does not change Bitrix24 data, and the app is not its own. An app counts as the key's own if it was created by that key; for Cowork seat keys, creation by any key of the same seat qualifies. For an authorization key, only its own app qualifies. An app created in the dashboard does not qualify as the key's own
HTTP403 CodeWRITE_BLOCKED_READONLY_KEY DescriptionThe key does not change Bitrix24 data, and the app's bound placements include one in an employee work screen, or the placements are bound to a handler other than the platform handler. Unpublishing removes all bound placements. An app with only a left menu item on the platform handler can be unpublished without triggering this error

Full list of common API errors — Errors.

Known specifics

  • Returns to UNPUBLISHED, not PRIVATE. Catalog metadata — title, description, icon — is preserved, so publishing the app again with an empty body restores it without re-entering the metadata.

See also