## Cancel an access request

`POST /v1/infra/servers/:id/audience-proposals/:proposalId/cancel`

Cancels your own access change request. Cancellation does not change application access.

Use the original API key that created the request. Another key belonging to the same owner cannot access it.

## Parameters

| Parameter | In | Type | Required | Description |
|-----------|----|------|:--------:|-------------|
| `id` | path | string (UUID) | yes | Server ID from the original operation. See [List servers](/docs/infra/servers/list) |
| `proposalId` | path | string (UUID) | yes | Request ID from `error.details.proposalId` in a `409 AUDIENCE_APPROVAL_REQUIRED` response to [changing the policy](./access-policy.md) or [minting a token](/docs/infra/access-tokens/create) |

## Request fields (body)

The body is optional. If supplied, it must be an empty object `{}`.

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/audience-proposals/PROPOSAL_ID/cancel" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/audience-proposals/PROPOSAL_ID/cancel" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — personal key

```javascript
const response = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/audience-proposals/${proposalId}/cancel`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
    },
  },
)
const { proposal } = await response.json()
console.log(proposal.state)
```

### JavaScript — OAuth application

```javascript
const response = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/audience-proposals/${proposalId}/cancel`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  },
)
const { proposal } = await response.json()
console.log(proposal.state)
```

## Response fields

A successful response is `{ "proposal": ... }`, without a `success` or `data` envelope. The table lists the main fields. The response also includes the operation under review, the original, proposed and current access snapshots, participant labels and the differences between them.

| Field | Type | Description |
|-------|------|-------------|
| `proposal.id` | string (UUID) | Request ID |
| `proposal.state` | string | `PENDING`, `APPROVED`, `APPLIED`, `REJECTED`, `CANCELLED`, `EXPIRED` or `STALE` |
| `proposal.baseRevision` | string | Access revision when the request was created; a decimal string |
| `proposal.currentRevision` | string | Current access revision; a decimal string |
| `proposal.expiresAt` | string | Request expiry in ISO 8601 |
| `proposal.canDecide` | boolean | Always `false` for an API key |
| `proposal.canCancel` | boolean | Whether the request can be cancelled now |
| `proposal.resultEntityId` | string (UUID), optional | ID of the record created when applied; not a token or secret URL |

## Response example

The ID, state and revisions are shown. Other fields are described above.

```json
{
  "proposal": {
    "id": "00000000-0000-4000-8000-000000000001",
    "state": "CANCELLED",
    "baseRevision": "0",
    "currentRevision": "0"
  }
}
```

## Error response example

404 — server not found:

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

## Errors

| HTTP | Code | Description |
|------|------|-------------|
| 400 | `VALIDATION_ERROR` | Invalid UUID or a non-empty body |
| 401 | `MISSING_API_KEY` | No key was supplied |
| 401 | `INVALID_API_KEY` | The key was not recognized |
| 403 | `PORTAL_COLLABORATOR_NOT_A_MEMBER` | The collaborator key was revoked or expired, or their portal membership ended |
| 403 | `AUDIENCE_APPROVAL_FORBIDDEN` | The current key, its owner or portal binding no longer permits the operation |
| 404 | `NOT_FOUND` | The server is missing, deleted or not bound to the portal. Message: `Server not found` |
| 404 | `NOT_FOUND` | The request is missing for this server and portal, or was created by another caller. Message: `Proposal not found` |
| 409 | `AUDIENCE_APPROVAL_REPLAY` | The request was already applied, cancelled or completed by another decision |
| 409 | `AUDIENCE_APPROVAL_STALE` | The access revision changed |
| 410 | `AUDIENCE_APPROVAL_EXPIRED` | The request expired |

For common API errors, see [Errors](/docs/errors).

## Known limitations

- **Check `canCancel` before cancelling.** Only a current request in the `PENDING` or `APPROVED` state can be cancelled.
- **Cancellation does not revoke granted access.** After `APPLIED`, use the original access management methods.

## See also

- [Approving wider access](/docs/infra/access#approving-wider-access)
- [Check an access change request](./audience-proposals-get.md)
- [Access policy](./access-policy.md)
- [Mint an access token](/docs/infra/access-tokens/create)
