---
title: "Approve an access request"
method: POST
path: "/api/v1/access_requests/{access_request_id}/approve"
tags: ["access_requests"]
---

# Approve an access request

`POST /api/v1/access_requests/{access_request_id}/approve`

## Request

- Base URL: `https://app.accessowl.io`
- URL: `https://app.accessowl.io/api/v1/access_requests/{access_request_id}/approve`
- Auth: HTTP bearer

Records one approver's approval at the request's current approval step. A request with further steps moves on to the next step; after the last step it is fully approved. The caller names the approver to approve on behalf of via `on_behalf_of_user_id`, and the acting user is then persisted as the deputy. Omit it only when the acting user is themselves an approver of the current step; an API token must always name one.

## Path parameters

- `access_request_id` string, uuid, required

## Headers

- `Idempotency-Key` string

## Request body

- ApproveAccessRequest: Request body for approving an access request
  - `on_behalf_of_user_id` string, uuid: The approver (user) to approve on behalf of, recording the acting user as deputy. Required when authenticating with an API token; otherwise omit it to approve as the acting user.

## Response `200`

Access request approved

- AccessRequest: An access request
  - `application_id` string, uuid, required: Application ID
  - `approval_steps` ApprovalStep[]: The ordered approval steps with their approvers and decisions. Empty for auto-approved requests.
    - `approvers` ApprovalStepApprover[], required: The approvers resolved for this step
      - `decided_at` string, date-time, nullable: When this approver approved or denied; null while pending or skipped
      - `decided_by_user_id` string, uuid, nullable: User ID of the person who recorded the decision — the approver themselves, or the user who approved or denied on their behalf; null while the approver hasn't decided
      - `status` 'pending' | 'approved' | 'denied' | 'skipped', required: Whether this approver approved, denied, is still pending, or was skipped (the step or request was decided without them)
      - `user_id` string, uuid, required: User ID of the approver
    - `decided_at` string, date-time, nullable: When the step was decided; null while pending or skipped
    - `status` 'pending' | 'approved' | 'denied' | 'skipped', required: State of the step: pending (current or upcoming), approved, denied, or skipped (a prior step's denial ended the request)
    - `step` integer, required: 1-based position of the step
    - `strategy` 'first_to_respond' | 'all', required: How many approvers must approve the step: any single one (first_to_respond) or every one (all)
  - `duration` string, nullable: Duration of time-based access as an ISO 8601 duration (e.g. "PT1H", "P7D"); null for permanent access
  - `expires_at` string, date-time, nullable: When the time-based access expires; null for permanent access or a time-based request that has not been granted yet
  - `grantee_user_id` string, uuid: User ID of the grantee
  - `id` string, uuid, required: Access request ID
  - `inserted_at` string, date-time: Creation timestamp
  - `permission_ids` string[], required: Requested permission IDs
  - `provisioning_type` 'application_admin' | 'automatic', nullable: Provisioning type
  - `request_reason` string, required: Request reason
  - `requestor_user_id` string, uuid: User ID of the requestor
  - `resource_id` string, uuid, required: Resource ID
  - `status` 'pending_approval' | 'pending_permissions_assignment' | 'access_granted' | 'denied' | 'rejected' | 'processing_access' | 'scheduled' | 'pending_dependency', required: Current status of the access request
  - `termination_reason` string, nullable: Reason the request was ended: the denial reason when denied, the provisioner's rejection reason when rejected; null otherwise. The status field says which kind it was.

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden: the caller lacks the approve permission; being an approver of the request is not enough
- `404`: Not found
- `409`: Conflict
- `422`: Validation error
- `429`: Too many requests

## Changes

- **2026-11-02** `ff38c63d8807`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/accessowl/apis/accessowl-api/changes/api/v1/access_requests/:access_request_id/approve/post.md)

---

[API](https://skmtc.dev/accessowl/apis/accessowl-api.md) - [All operations](https://skmtc.dev/accessowl/apis/accessowl-api/llms.txt) - [OpenAPI document](https://skmtc.dev/accessowl/apis/accessowl-api/revisions/ff38c63d8807?raw)
