Transcriptions

Create a transcription

Submit a source to transcribe. Exactly one of url or file must be provided:

  • url — a YouTube/Instagram link, a direct audio/video URL, or an s3:// reference.
  • file — inline upload. Pass the binary as base64 in file.data (the server uploads it to storage for you).

The response is returned immediately with status: "queued". Poll GET /v1/transcriptions/{id} until the status is terminal, or pass webhook_url to receive a POST when it finishes.

post/v1/transcriptions

Request

  • Base URL: https://api.quillhub.ai
  • URL: https://api.quillhub.ai/v1/transcriptions
  • Auth: HTTP bearer

Request body

urlstring

YouTube / Instagram link, direct audio or video URL, or an s3:// reference. Mutually exclusive with file.

languagestring nullable

ISO-639-1 code (e.g. en, ru, es) to force recognition in that language — same effect as language_code, which wins when both are set. Omit (or pass "auto") to auto-detect from the audio — recommended in ~99% of cases.

language_codestring nullable

Force AssemblyAI recognition to a specific ISO-639-1 language (e.g. ru, en, kk, uz). When set, language auto-detection is disabled. Omit, pass null, or pass "auto" to keep auto-detection (the default).

speaker_recognitionboolean

Label each segment with a speaker identifier. Adds ~10–15% processing time.

structureboolean

Generate a structured summary (title, summary, paragraphs, highlights, terms) alongside the raw transcript.

include_source_urlboolean

If true, GET /v1/transcriptions/{id} returns a short-lived presigned source_url for inline uploads.

webhook_urlstring uri nullable

HTTPS URL that will receive a POST with the finished transcription. Deliveries are unsigned — pick an unguessable path.

metadataobject nullable

Arbitrary string→string map of up to 16 pairs, echoed back on the transcription. Useful for correlating jobs with your own records.

Example request

{
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "file": {
    "filename": "meeting.mp3",
    "mime_type": "audio/mpeg",
    "data": "SUQzAwAAAAA..."
  },
  "language_code": "ru",
  "structure": true,
  "webhook_url": "https://your-app.example.com/hooks/quillhub"
}

Response

Accepted — a queued transcription object

idstring required

Stable identifier with trs_ prefix.

internal_idinteger 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'.

titlestring 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.

progressnumber nullable

Fraction between 0 and 1 while processing. null otherwise.

duration_secondsnumber nullable

Source duration, detected after download/probe.

languagestring nullable

Detected or forced ISO-639-1 language code. null until probed.

share_enabledboolean required

Whether the public share link is active.

share_enabled_atstring date-time nullable required

ISO 8601 timestamp when sharing was enabled. null if never enabled.

share_urlstring uri nullable required

Public share URL. null when share_enabled is false.

points_spentnumber nullable

Points charged on completion. null until the job is terminal.

source_urlstring 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_urlstring nullable

Callback URL recorded on create. We POST the finished Transcription object here.

errorstring nullable

Human-readable failure reason. Present only when status is failed. Machine-readable classification lives in error_code, never inside this text.

error_codestring 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.

metadataobject nullable

Arbitrary string→string map passed on create, echoed back unchanged.

workspace_idinteger nullable

Workspace the transcription belongs to. null on legacy rows created before workspaces.

project_idinteger nullable

Project inside the workspace. null means the transcription sits in the workspace Inbox (no project).

created_atstring required

ISO 8601 timestamp.

completed_atstring nullable

ISO 8601 timestamp of the terminal transition. null otherwise.

Example response

{
  "id": "trs_01HZXK9P2Q7R8S4T5V6W7X8Y9Z",
  "internal_id": 212241,
  "kind": "dictation",
  "title": "Q3 planning sync",
  "status": "queued",
  "stage": "transcribing",
  "progress": 0.42,
  "source": {
    "type": "youtube",
    "channel": "desktop"
  },
  "duration_seconds": 1843,
  "language": "en",
  "points_spent": 28,
  "result": {
    "segments": [
      {
        "start": 3.84,
        "end": 7.12,
        "text": "Welcome back to the channel.",
        "speaker": "Speaker 1"
      }
    ]
  },
  "error_code": "GOT_ARCHIVE",
  "workspace_id": 42,
  "project_id": 7,
  "created_at": "2026-04-23T10:14:22Z"
}

Changes

No recorded changes to this operation across all 1 revision of this API.