---
title: "Cancel a transcription"
method: DELETE
path: "/v1/transcriptions/{id}"
tags: ["Transcriptions"]
---

# Cancel a transcription

`DELETE /v1/transcriptions/{id}`

## Request

- Base URL: `https://api.quillhub.ai`
- URL: `https://api.quillhub.ai/v1/transcriptions/{id}`
- Auth: HTTP bearer

Cancels a transcription that hasn't completed yet. The job transitions to `cancelled` and no further points are charged. Calling this on an already-terminal transcription returns the current state unchanged.

## Path parameters

- `id` string, required: Transcription id: `trs_…` (canonical), numeric `request.id` from web/desktop URLs, or `trs_legacy_<n>`.

## Response `200`

Updated transcription — now `cancelled`.

- Transcription
  - `id` string, required: Stable identifier with `trs_` prefix.
  - `internal_id` integer, required: Numeric `request.id` used by first-party web/desktop URLs (e.g. https://quillhub.ai/{locale}/transcript/{internal_id}). Public API consumers should keep using `id`; this field exists so first-party clients can deep-link to the existing web transcript page without an extra round-trip.
  - `kind` 'meeting' | 'dictation', nullable: Categorisation of the request: 'dictation' for short voice notes captured via the desktop widget, 'meeting' for recorded calls/uploads. Null on legacy rows; clients should treat null as 'meeting'.
  - `title` string, nullable: Human-readable title. Generated by the structurer once the transcript is ready (e.g. "Митинг с командой о Q3"); falls back to the original filename for sources that don't go through structuring.
  - `status` 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled', required: Lifecycle stage. `queued` → `processing` → one of `completed` / `failed` / `cancelled` (terminal).
  - `stage` 'queued' | 'downloading' | 'transcribing' | 'structuring' | 'completed' | 'failed' | 'insufficient_funds' | 'cancelled', required: Precise processing stage. `status` keeps its existing, back-compatible meaning; `stage` refines it — notably separating `insufficient_funds` from a generic failure, and the download / transcribe / structure phases from a generic `processing`.
  - `progress` number, nullable: Fraction between 0 and 1 while `processing`. `null` otherwise.
  - `source` object, required: What was submitted.
    - `type` 'youtube' | 'instagram' | 'direct' | 'upload', required: Detected source category. `youtube` / `instagram` for those platforms, `direct` for any other reachable URL, `upload` when the client sent an inline base64 file.
    - `url` string, nullable: Normalized source URL. `null` for inline uploads unless `include_source_url: true`.
    - `channel` string, nullable: Which surface created the recording: `web`, `api`, `desktop`, `bot`, `tg_webapp`. `null` for rows created before the column existed (those are web uploads). Deliberately a free-form string, not an enum: the column carries no CHECK constraint, and a new surface must not break response validation for existing clients.
  - `options` object, required: Echoes the create-request options so clients can branch on effective config.
    - `language` string, nullable: Language forced by the caller. `null` if auto-detect was used.
    - `speaker_recognition` boolean, required
    - `structure` boolean, required
  - `duration_seconds` number, nullable: Source duration, detected after download/probe.
  - `language` string, nullable: Detected or forced ISO-639-1 language code. `null` until probed.
  - `share_enabled` boolean, required: Whether the public share link is active.
  - `share_enabled_at` string, date-time, nullable, required: ISO 8601 timestamp when sharing was enabled. `null` if never enabled.
  - `share_url` string, uri, nullable, required: Public share URL. `null` when `share_enabled` is false.
  - `points_spent` number, nullable: Points charged on completion. `null` until the job is terminal.
  - `result` TranscriptionResult, nullable: Populated when `status` is `completed`. `null` for `queued` / `processing` / `failed` / `cancelled`.
    - `text` string, nullable: Full transcript as a single plain-text string.
    - `segments` Segment[]: Phrase-level chunks with timestamps and optional speaker labels.
      - `start` number, required: Seconds from the beginning of the source audio.
      - `end` number, required: Seconds from the beginning of the source audio.
      - `text` string, required
      - `speaker` string, nullable: Generic speaker label (`Speaker 1`, `Speaker 2`, …). Present only when the request set `speaker_recognition: true`.
    - `structured` object, nullable: Title, summary, TOC, paragraphs, highlights, and terms. Populated when `structure: true`.
      - `title` string, nullable: Suggested title inferred by the structurer.
      - `summary` string, nullable: Short summary of the content.
      - `language` string, nullable: Detected language code, echoed from the structurer.
      - `toc` object[]: Table of contents — array of entries with a `title` and a `start_paragraph_number` anchor (plus any auxiliary fields the structurer emits).
      - `chapters` object[]: Chapter-level segmentation with `title`, `start_time`, `end_time`, and the paragraphs that belong to each chapter.
      - `paragraphs` object[]: Paragraph-level readable view with `start_time`, `paragraph_text`, and the index matching back to `result.segments`.
      - `highlights` string[]: Key quotes pulled from the transcript.
      - `key_theses` string[]: Main thesis statements — slightly longer than highlights.
      - `terms` string[]: Glossary of proper nouns, product names, and domain terms the model extracted.
      - `action_items` union[]: Tasks found in the recording, exactly as the structurer emitted them: either a bare string, or an object with `text` plus an optional assignee and deadline. Use `format=summary` for the normalized `ActionItem` shape.
        - union
          - string
          - object
            - `text` string, required
            - `who` string, nullable
            - `due` string, nullable
      - `decisions` string[]: Decisions reached during the recording.
      - `topics` string[]: Topics covered in the recording.
    - `subtitles` object: Ready-to-use VTT and SRT caption strings.
      - `vtt` string, nullable: Presigned URL to the WebVTT file. Suitable to pass directly into a `<track>` element or a player. Expires after the storage TTL.
      - `srt` string, nullable: Presigned URL to the SRT file. Expires after the storage TTL.
  - `source_url` string, nullable: Short-lived presigned URL to the stored source file. Only present for inline uploads when `include_source_url: true` was set on create.
  - `webhook_url` string, nullable: Callback URL recorded on create. We POST the finished Transcription object here.
  - `error` string, nullable: Human-readable failure reason. Present only when `status` is `failed`. Machine-readable classification lives in `error_code`, never inside this text.
  - `error_code` string, nullable: Stable machine-readable failure code (e.g. `GOT_ARCHIVE`, `CONTENT_PRIVATE`, `NO_SPEECH`). `null` when the failure wasn't classified. Branch on this instead of matching `error` text.
  - `metadata` object, nullable: Arbitrary string→string map passed on create, echoed back unchanged.
  - `workspace_id` integer, nullable: Workspace the transcription belongs to. `null` on legacy rows created before workspaces.
  - `project_id` integer, nullable: Project inside the workspace. `null` means the transcription sits in the workspace Inbox (no project).
  - `created_at` string, required: ISO 8601 timestamp.
  - `completed_at` string, nullable: ISO 8601 timestamp of the terminal transition. `null` otherwise.

## Other responses

- `401`: Missing or invalid Bearer token.
- `404`: No transcription with this id exists under the authenticated account.

---

[API](https://skmtc.dev/quillhub/apis/quillhub-public-api.md) · [All operations](https://skmtc.dev/quillhub/apis/quillhub-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/quillhub/apis/quillhub-public-api/revisions/5bd42ee9d967?raw)
