---
title: "Delete Time Entry"
method: DELETE
path: "/v1/time-entries/{time_entry_id}"
tags: ["time-entries"]
---

# Delete Time Entry

`DELETE /v1/time-entries/{time_entry_id}`

## Request

- Base URL: `https://app.tokumalabs.com/api`
- URL: `https://app.tokumalabs.com/api/v1/time-entries/{time_entry_id}`
- Auth: OAuth 2
  - Password
  - Token URL: `v1/auth/token`

Soft-delete a time entry and detach its associated time blocks.

Returns the soft-deleted entry (``deleted_at`` populated) plus every
detached child block — blocks stay live with ``time_entry_id``
cleared, so they return to the unattached/pending pool instead of
being discarded. Both carry the trigger-advanced ``version``. The
desktop client applies the response directly to its local SQLite
mirror; the next ``GET /api/v1/sync`` round re-delivers the same rows
and the version-check predicate makes the second apply a no-op.
Released time entries cannot be deleted.

## Path parameters

- `time_entry_id` integer, required: ID of the time entry to delete

## Response `200`

Successful Response

- DeleteTimeEntryResponse: Response model for deleting a time entry. Returns the soft-deleted entry (``deleted_at`` set) plus every **detached** child time block — blocks stay live (``deleted_at`` is ``None``) with their ``time_entry_id`` cleared, so they return to the unattached/pending pool rather than vanishing. Both carry the trigger-bumped ``version``. The desktop client applies the response directly to its local SQLite mirror via the same idempotent upsert path used by ``GET /api/v1/sync``: the entry's row is evicted and the detached blocks reappear as pending.
  - `time_entry` TimeEntrySyncDto, required: A time entry as seen by the cursor sync feed. ``matter_segment`` is a denormalized snapshot — see ``TimeBlockSyncDto`` for rename-staleness semantics. ``version`` is the trigger-bumped cursor counter; ``updated_at`` is informational.
    - `id` integer, required
    - `organization_id` string, required
    - `user_id` string, required
    - `date` string, date, required
    - `legal_time_minutes` integer, required
    - `legal_time_is_computed` boolean, required
    - `tracked_duration_minutes` integer, required
    - `narrative` string, nullable, required
    - `narrative_suggestions` string[], nullable
    - `activity_code` string, nullable
    - `segment_id` string, nullable
    - `matter_segment` MatterSegmentSummaryDto: Summary of matter and segment for time blocks.
      - `matter_id` string, required: Matter ID
      - `matter_name` string, required: Matter name
      - `segment_id` string, required: Segment ID
      - `segment_name` string, required: Segment name
      - `segment_order` integer, required: Display order of the segment within the matter
      - `is_root` boolean, required: Whether this is the root segment
      - `root_segment_id` string, nullable: Root segment ID of the matter
    - `is_billable` boolean, required
    - `legal_time_pinned` boolean, required
    - `legal_time_resnapped_from` integer, nullable
    - `is_user_created` boolean, required
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `deleted_at` string, date-time, nullable
    - `version` integer, required
  - `cascaded_blocks` TimeBlockSyncDto[]: Child time blocks detached from the deleted entry — live (deleted_at null) with time_entry_id cleared, returned to the pending pool
    - `id` integer, required
    - `organization_id` string, required
    - `user_id` string, required
    - `start_time` string, date-time, required
    - `end_time` string, date-time, required
    - `headline` string, required
    - `is_live` boolean, required
    - `app_id` string, nullable
    - `app_name` string, nullable
    - `segment_id` string, nullable
    - `matter_segment` MatterSegmentSummaryDto: Summary of matter and segment for time blocks.
      - `matter_id` string, required: Matter ID
      - `matter_name` string, required: Matter name
      - `segment_id` string, required: Segment ID
      - `segment_name` string, required: Segment name
      - `segment_order` integer, required: Display order of the segment within the matter
      - `is_root` boolean, required: Whether this is the root segment
      - `root_segment_id` string, nullable: Root segment ID of the matter
    - `activity_code` string, nullable
    - `time_entry_id` integer, nullable
    - `source_type` 'APP' | 'MS365_CALL' | 'MS365_EMAIL' | 'MS365_CALENDAR_EVENT', required: Source of a time block.
    - `headline_attempt_status` 'not_attempted' | 'succeeded' | 'skipped_no_signal' | 'failed_terminal': Vocabulary for `time_blocks.headline_attempt_status`. Stored as a `(str, Enum)` so the cursor-sync wire DTO can type the field as the enum and Pydantic v2 serializes to the bare value ('not_attempted' etc.) — the qualified-name footgun of plain `str(EnumMember)` is avoided.
    - `artifacts` BlockArtifactsDto: Artifacts for one block: a capped list plus the honest total. ``total`` is the pre-cap count of displayed (doc+email) artifacts — the same population as ``items`` — so a client showing the first N can render an honest "+more" without the wire ever implying the capped list is complete.
      - `items` ArtifactDto[]
        - `kind` 'doc' | 'email', required
        - `title` string, required
        - `location` string, nullable
      - `total` integer
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `deleted_at` string, date-time, nullable
    - `version` integer, required

## Other responses

- `400`: Validation error or domain rule violation.
- `401`: Missing, expired, or invalid authentication.
- `403`: Authenticated but not permitted.
- `404`: Resource not found.
- `409`: Resource state conflict (duplicate, illegal transition).
- `422`: Request body failed schema validation.
- `500`: Server-side failure.

---

[API](https://skmtc.dev/tokumalabs/apis/tokuma-user-api.md) - [All operations](https://skmtc.dev/tokumalabs/apis/tokuma-user-api/llms.txt) - [OpenAPI document](https://skmtc.dev/tokumalabs/apis/tokuma-user-api/revisions/1f8201af459b?raw)
