
## Delete access entry

`DELETE /v1/infra/servers/:id/access/:accessId`

Deletes an access entry — a user or a department — from a BLACKHOLE server's access list. The endpoint handles both kinds of entry: an `accessId` can refer to either a user (`BlackHoleAccess`) or a department (`BlackHoleDepartment`) — the platform looks in the first table, then in the second. After deletion, the entry disappears from [`GET /access`](./access-list.md).

## Parameters

| Parameter | In | Type | Required | Description |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | yes | BLACKHOLE server ID |
| `accessId` | path | string (UUID) | yes | Access entry ID from [`GET /access`](./access-list.md) or [`POST /access`](./access-add.md) |
| `approvalId` | query | string (UUID) | no | Approved request ID from `error.details.proposalId` in a `409 AUDIENCE_APPROVAL_REQUIRED` response; [how to obtain approval](/docs/infra/access#approving-wider-access) |

## Examples

### curl — personal key

```bash
curl -X DELETE -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access/ACCESS_ID
```

### curl — OAuth application

```bash
curl -X DELETE -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access/ACCESS_ID
```

### JavaScript — personal key

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/access/${accessId}`,
  {
    method: 'DELETE',
    headers: { 'X-Api-Key': 'YOUR_API_KEY' },
  }
)
const { success } = await res.json()
if (success) console.log('Entry deleted')
```

### JavaScript — OAuth application

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/access/${accessId}`,
  {
    method: 'DELETE',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)
const { success } = await res.json()
if (success) console.log('Entry deleted')
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on successful deletion |

## Response example

```json
{ "success": true }
```

## Error response example

404 — entry not found (already deleted, wrong accessId, or an accessId that belongs to another server):

```json
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Access entry not found"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | The query parameter `approvalId` has an invalid format |
| 400 | `BLACKHOLE_ONLY` | The server is in OPEN mode |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not provided |
| 401 | `INVALID_API_KEY` | The key is not recognized — no such key exists on the platform |
| 403 | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | The call was made with a Cowork key — such a key works with data only and cannot perform write operations. To issue a key that can, see [Project key for deploy](/docs/cowork/deploy-key) |
| 403 | `SERVER_ROLE_FORBIDDEN` | You are on this server's development team with the Developer role, but this operation is open to the Administrator role. `error.hint` carries your role, the required threshold and the list of calls that are open to you. Role breakdown — [List servers](/docs/infra/servers/list) |
| 409 | `AUDIENCE_APPROVAL_REQUIRED` | The resulting access would widen; obtain human approval, then retry DELETE with `approvalId` in the query. Access is unchanged until approval |
| 404 | `NOT_FOUND` | The server does not exist, belongs to a different API key and you are not on its development team, or the entry was not found (wrong `accessId`, already deleted, or belongs to another server) |
| 409 | `AUDIENCE_APPROVAL_MISMATCH` | The approval belongs to another operation or requester; use the exact request and original credential |
| 409 | `AUDIENCE_APPROVAL_REPLAY` | The approval was already used or the request is not in the APPROVED state |
| 409 | `AUDIENCE_APPROVAL_STALE` | Access changed after review; obtain a new approval request |
| 410 | `AUDIENCE_APPROVAL_EXPIRED` | The request expired; obtain a new approval request |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |

The full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **Wider access requires approval.** If restoring other grants after deletion would widen the audience, the request returns `409 AUDIENCE_APPROVAL_REQUIRED` and leaves the entry in place. After human approval, retry the same DELETE for the same `id` and `accessId`, using the original credential and `?approvalId=APPROVAL_ID`. No approval is needed when the platform can prove that access only narrows. [Check or cancel your own request](/docs/infra/access#approving-wider-access).
- **Hard delete, not soft delete.** The entry is erased from the database. It cannot be restored — you will have to call [`POST /access`](./access-add.md) again.
- **Deletion also closes sessions that are already open.** If deleting the entry takes away the user's access, the application becomes unavailable to them within a minute, even in a tab opened earlier.
- **`share-url` links do not depend on the list.** They are revoked separately — [Revoke a token](/docs/infra/access-tokens/delete).
- **`accessId` is bound to the server.** An attempt to delete another server's access entry (correct `accessId` but wrong `:id` in the path) returns 404 `NOT_FOUND`. The platform deliberately does not reveal the existence of other servers' entries.
- **Deletion does not change the policy.** If you delete all users under `accessPolicy: "NAMED_USERS"`, the policy stays `NAMED_USERS` (and the application becomes inaccessible to everyone except the key owner). To "fully restore privacy", switch the policy back to `OWNER_ONLY` via [`PATCH /access-policy`](./access-policy.md).
- **The key owner cannot be deleted.** The owner always has access, even if they are not in the list. To revoke your own access, you need a different API key.

## See also

- [Access list](./access-list.md)
- [Add user/department](./access-add.md)
- [Access policy](./access-policy.md)
