# GET /api/v2/worklogs/{worklog}

Read a worklog

- MCP id: worklogs.show
- Scope: api:read:times
- Permission: hours::read
- Rate cost: 1 unit, read bucket.
- Cache-Control: private, no-store

Returns one worklog.

`reason` and `billable_change_reason` are detail-view fields, so `?view=detail` is what fetches the justifications a list row omits. An entry belonging to another employee is `404` unless the caller holds `times::update_others` or `times::delete_others`: the row is invisible, so its existence stays invisible. `project` and `work_item` are always expanded; `budget`, `task` and `user` expand under `?include=`, and each additionally requires the read permission and token scope of its own prefix.

## Parameters
- worklog (integer, path): The Time's numeric id.
- view (string, optional): Which field set to render.
- X-Request-Id (header, optional): A correlation id of your own. It is recorded in our logs next to the server's request id but never returned: the response header always carries the server's id. A value that does not match the pattern is discarded silently, never rejected.
- If-None-Match (header, optional): The ETag a read is conditional on. A match is answered 304 with no body.

## Response 200
- id (integer, required): Unique identifier.
- date (date (YYYY-MM-DD), required): The calendar day the work happened.
- minutes (integer, required): Duration in minutes, between 1 and 1440.
- description (string ≤ 255, required): What the employee worked on.
- project_id (integer or null, required): Project the hours are booked against; `null` once that project is deleted.
- project (Ref or ProjectSummary or null, required): The project the hours are booked against, always expanded. Its `customer_id` is the customer to fetch with `GET /api/v2/customers/{customer}`; the customer itself is not nested.
- budget_id (integer or null, required, server-assigned): Budget the hours are invoiced against. Derived from the task, never accepted on a write; `null` when no task is set or the budget is deleted.
- budget (Ref or BudgetSummary or null, required): The budget the hours are invoiced against. Expanding it with `?include=budget` additionally requires the `budgets::read` permission and a token scope covering the budgets prefix.
- task_id (integer or null, required): Task the hours are booked on; `null` when the entry is not attached to one, or once that task is deleted.
- task (Ref or TaskSummary or null, required): The task the hours are booked on. Expanding it with `?include=task` additionally requires the `kanban::manage_self` permission and a token scope covering the kanban prefix, and is limited to the tasks you can see on the tasks collection.
- work_item_id (integer or null, required): Work item the hours are attached to; `null` when the entry is not attached to one, or once that work item is deleted.
- work_item (Ref or WorkItemSummary or null, required): The work item the hours are attached to, always expanded.
- user_id (integer or null, required, server-assigned): Employee the hours belong to. Assigned on create (from the authenticated user, or from `on_behalf_of_user_id`) and never writable afterwards; reassigning a worklog is a DELETE plus a POST.
- user (Ref or UserSummary or null, required): The employee the hours belong to. Expanding it with `?include=user` additionally requires the `users::read` permission and a token scope covering the users prefix.
- is_not_billable (boolean, required): Whether these hours are excluded from invoicing. Inferred from the task's `is_billable` flag (`false` without a task) on create and again whenever `task_id` is sent. Sending a value that differs from the inferred or current one requires `billable_change_reason` and puts the entry in a reviewer's queue; without it the write is a `422` on `/billable_change_reason`.
- is_overtime (boolean, required): Whether the hours count as overtime. Sending it without the `times::write_overtime` permission leaves it `false` and adds an `input_ignored` warning rather than failing the write.
- exceeded_budget (boolean, required): Whether the entry was booked knowing it exceeds its budget. Set on create only, and `true` whenever a `reason` is sent; setting it puts the entry in a reviewer's queue.
- reason (string or null, required, detail only, multiline): Why the budget overrun was accepted. Sending it on create marks the entry as exceeding its budget. Once a reviewer has settled the entry it can no longer be changed: a PATCH that does answers `409` `reason_reviewed`.
- billable_change_reason (string or null, required, detail only, multiline): Why the inferred billability was overridden. Required whenever `is_not_billable` is sent with a value that differs from the inferred or current one, on create and on PATCH alike; the override puts the entry in a reviewer's queue, reopening one a reviewer had already settled.
- reviewed_by (integer or null, required, server-assigned): The reviewer who settled the entry, once one has. Set by the review queue in plnnrly; this API exposes no way to write it.
- invoice_id (integer or null, required, server-assigned): The invoice these hours were billed on, once they have been. While it is set, the entry is locked: a write answers `409` with `conflict.reason` `locked_by_invoice`.
- sales_invoice_row_id (integer or null, required, server-assigned): The sales-invoice line these hours were billed on, once they have been. Set by the invoicing flow.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Creation timestamp.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync.
- links (TimeLinks, required)
  - self (url, required): The canonical URI of this record.

## Errors
- 403 forbidden-by-policy | insufficient-permission | insufficient-token-scope: Forbidden.
- 304 : Not modified.
- 400 idempotency-key-required | invalid-cursor | invalid-query-parameter | malformed-request | unsupported-parameter: Bad request.
- 401 token-expired | unauthenticated: Unauthenticated.
- 404 endpoint-not-found | resource-not-found: Not found.
- 406 not-acceptable: Not acceptable.
- 429 rate-limit-exceeded: Too many requests.
- 500 internal-error: Server error.
- 503 tenant-unavailable: Service unavailable.

## Example
```bash
curl -G \
  'https://<your-url>/api/v2/worklogs/1' \
  --data-urlencode 'view=detail' \
  --data-urlencode 'include=budget,task,user' \
  -H 'Authorization: Bearer <token>' \
  -H 'Accept: application/json'
```
