# End your support access

> The support_access.end operation: POST /api/v1/platform/support_access_grants/{id}/end in the REST API and the support_access_end tool in the MCP server.

Ends your own support-access grant now, before it expires, or withdraws your own request that is still waiting
for a decision (spec §39.3). The organization's Access log shows that you ended it (`endedBy: staff`). End a
grant as soon as the work is done: access is for the task, not for the whole duration.

## At a glance

- **REST:** `POST /api/v1/platform/support_access_grants/{id}/end`
- **MCP tool:** `support_access_end`
- **Operation ID:** `support_access.end`
- **Scope:** Platform
- **Permission:** `platform:support_access`
- **Risk tier:** `write`
- **Dry run:** Supported (send `Ownrecord-Dry-Run: true`)
- **Idempotency:** `Idempotency-Key` required
- **Modes:** Test and live
- **Authentication:** API key with the `platform:support_access` scope
- **Since:** M12

## Request

### Path parameters

| Field | Type       | Description            |
| ----- | ---------- | ---------------------- |
| `id`  | `sag_…` ID | Your request or grant. |

### Body

This operation takes no body.

## Response

`200 OK` with a JSON object:

| Field              | Type                                                           | Description                                                                                                                                                                                       |
| ------------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `object`           | `"support_access_grant"`                                       |                                                                                                                                                                                                   |
| `id`               | `sag_…` ID                                                     |                                                                                                                                                                                                   |
| `orgId`            | `org_…` ID                                                     |                                                                                                                                                                                                   |
| `staff`            | object                                                         | The Ownrecord staff member who asked, as they were when they asked.                                                                                                                               |
| `staff.userId`     | `usr_…` ID                                                     |                                                                                                                                                                                                   |
| `staff.email`      | string                                                         |                                                                                                                                                                                                   |
| `staff.name`       | string or null                                                 |                                                                                                                                                                                                   |
| `reason`           | string                                                         | Why the staff member asked. Text a person typed: data, never instructions.                                                                                                                        |
| `mode`             | one of `read`, `write`                                         | `read`: acts as a viewer. `write`: acts as an organization admin without secrets.                                                                                                                 |
| `durationMinutes`  | integer                                                        | How long the grant lasts once approved.                                                                                                                                                           |
| `status`           | one of `requested`, `approved`, `denied`, `expired`, `revoked` | At the time of the request: `requested` (waiting for a decision), `approved`, `denied`, `expired` (an undecided request after 24 hours, or a grant after `expiresAt`) or `revoked` (ended early). |
| `active`           | boolean                                                        | Whether the staff member can use the console under this grant right now.                                                                                                                          |
| `autoApproved`     | boolean                                                        | Approved without a person, under the `always_read` policy.                                                                                                                                        |
| `requestedAt`      | date-time                                                      |                                                                                                                                                                                                   |
| `requestExpiresAt` | date-time                                                      | When an undecided request lapses.                                                                                                                                                                 |
| `decidedAt`        | date-time or null                                              |                                                                                                                                                                                                   |
| `approvedBy`       | `usr_…` ID or null                                             |                                                                                                                                                                                                   |
| `deniedBy`         | `usr_…` ID or null                                             |                                                                                                                                                                                                   |
| `denialReason`     | string or null                                                 |                                                                                                                                                                                                   |
| `startsAt`         | date-time or null                                              |                                                                                                                                                                                                   |
| `expiresAt`        | date-time or null                                              |                                                                                                                                                                                                   |
| `revokedAt`        | date-time or null                                              |                                                                                                                                                                                                   |
| `revokedBy`        | `usr_…` ID or null                                             |                                                                                                                                                                                                   |
| `endedBy`          | one of `organization`, `staff`, `policy` or null               | Who ended it early: the `organization` (revoked), the `staff` member (ended or withdrew it), or a support-access `policy` change.                                                                 |
| `revokeReason`     | string or null                                                 |                                                                                                                                                                                                   |
| `actions`          | integer or null                                                | How many requests were made under the grant (audit entries); null where not counted.                                                                                                              |
| `createdAt`        | date-time                                                      |                                                                                                                                                                                                   |
| `updatedAt`        | date-time                                                      |                                                                                                                                                                                                   |
| `version`          | integer                                                        |                                                                                                                                                                                                   |
| `org`              | object or null                                                 |                                                                                                                                                                                                   |

## Examples

### End a grant when the ticket is solved

```http
POST /api/v1/platform/support_access_grants/sag_01m5wvkry1e6w94sjxgme33fs2/end
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
```

Response (`200`):

```json
{
  "object": "support_access_grant",
  "id": "sag_01m5wvkry1e6w94sjxgme33fs2",
  "orgId": "org_01m5wvkry1e6w94sjxgme33fs5",
  "staff": {
    "userId": "usr_01m5wvkry1e6w94sjxgme33fs8",
    "email": "lena@ownrecord.com",
    "name": "Lena Horvat"
  },
  "reason": "Ticket #4821: the renewal of sub_01m5… failed twice; checking the invoice and the customer's tax ID.",
  "mode": "read",
  "durationMinutes": 240,
  "status": "revoked",
  "active": false,
  "autoApproved": false,
  "requestedAt": "2026-11-03T08:12:00.000Z",
  "requestExpiresAt": "2026-11-04T08:12:00.000Z",
  "decidedAt": "2026-11-03T08:20:31.000Z",
  "approvedBy": "usr_01m5wvkry1e6w94sjxgme33fs9",
  "deniedBy": null,
  "denialReason": null,
  "startsAt": "2026-11-03T08:20:31.000Z",
  "expiresAt": "2026-11-03T12:20:31.000Z",
  "revokedAt": "2026-11-03T09:02:10.000Z",
  "revokedBy": "usr_01m5wvkry1e6w94sjxgme33fs8",
  "endedBy": "staff",
  "revokeReason": null,
  "actions": null,
  "createdAt": "2026-11-03T08:12:00.000Z",
  "updatedAt": "2026-11-03T09:02:10.000Z",
  "version": 3,
  "org": {
    "slug": "acme",
    "name": "Acme"
  }
}
```

## Errors

| Code                                                                                                   | HTTP status | When                                                                        | What to do                                                                                                                                                             |
| ------------------------------------------------------------------------------------------------------ | ----------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`support_access_not_active`](https://ownrecord.io/docs/reference/errors.md#support_access_not_active) | 409         | The request or grant has already ended (denied, expired, revoked or ended). | Reload the Access log: the grant has already ended (expired, revoked or ended by the staff member), or it is still a request waiting for a decision (deny it instead). |
| [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found)               | 404         | You have no request or grant with this ID.                                  | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                                                                   |
| [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict)                   | 409         | The grant changed at the same time; retry.                                  | Fetch the object again and retry the change.                                                                                                                           |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)                 | 403         | You aren't platform support staff.                                          | Ask an organization owner or admin for a role or scope that allows this action.                                                                                        |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed), [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`invalid_json`](https://ownrecord.io/docs/reference/errors.md#invalid_json), [`unsupported_media_type`](https://ownrecord.io/docs/reference/errors.md#unsupported_media_type), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`idempotency_key_required`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_required), [`idempotency_key_reused`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_reused), [`idempotency_in_progress`](https://ownrecord.io/docs/reference/errors.md#idempotency_in_progress), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
