---
title: "Approves a batch of pending timesheet entries by their TimeSheetEntryIDs. Caller must have the Timesheet Approver role and permission to approve each specific entry. Mixed-eligibility batches return per-entry results."
method: POST
path: "/api/Timesheets/Approve"
tags: ["TimesheetApproval"]
---

# Approves a batch of pending timesheet entries by their TimeSheetEntryIDs. Caller must have the Timesheet Approver role and permission to approve each specific entry. Mixed-eligibility batches return per-entry results.

`POST /api/Timesheets/Approve`

## Request body

- TimesheetApprovalRequest — Request body for approving a batch of timesheet entries by their IDs.
  - `TimeSheetEntryIDs` integer[] — (Required) List of TimeSheetEntryIDs to approve. 1-500 unique positive integers.
  - `ApprovalNote` string — (Optional) Free-text approval note. Max 1000 characters. Currently accepted but not persisted.

## Response `200`

Returns a summary and per-entry results.

- TimesheetApprovalBatchResponse — Response envelope for batch approve and reject endpoints.
  - `Summary` TimesheetApprovalSummary — Aggregated counts for a batch approve or reject request.
    - `Requested` integer — Number of TimeSheetEntryIDs supplied in the request.
    - `Processed` integer — Number of entries the server inspected (always equals Requested).
    - `Succeeded` integer — Number of entries that successfully transitioned to the target status.
    - `AlreadyInTargetState` integer — Number of entries that were already in the target status.
    - `Failed` integer — Number of entries that could not be processed (forbidden, not found, ineligible, invoiced/paid, etc).
  - `Results` TimesheetApprovalResultItem[] — One result entry per supplied TimeSheetEntryID, in the same order as the request.
    - `TimeSheetEntryID` integer — The TimeSheetEntryID supplied by the caller.
    - `Status` string — Result status: Approved, Rejected, AlreadyApproved, AlreadyRejected, or Failed.
    - `ActedByUserID` integer — UserID of the caller, populated only when the status changed as a result of this request.
    - `ActedAt` string, date-time — UTC timestamp of the state change, populated only when the status changed as a result of this request.
    - `ErrorCode` string — Machine-readable error code when Status=Failed.
    - `Message` string — Human-readable failure message when Status=Failed.

## Other responses

- `400` — Bad Request - missing/invalid TimeSheetEntryIDs or note too long.
- `401` — Unauthorized.
- `403` — Forbidden - caller lacks the Timesheet Approver role.

---

[API](https://skmtc.net/avaza/apis/avaza-api-documentation.md) · [All operations](https://skmtc.net/avaza/apis/avaza-api-documentation/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/avaza/avaza-api-documentation/versions/1eeadf750514/schema)
