> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tiro.ooo/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Create a workspace Voice File Job, upload audio, track processing, retrieve transcript segments, and delete stored results through the Tiro API.

This page outlines the end-to-end flow for creating a Voice File Job, uploading audio, and retrieving results. The current implementation uses a client-triggered upload-complete call (no S3 event).

## What you need

* A user or system API key bound to a workspace: `Authorization: Bearer {id}.{secret}`
* Voice File Jobs enabled for that workspace by a Tiro administrator
* transcriptLocaleHints: up to 1 (optional)
  * **If not provided, language will be automatically detected**
* translationLocales: up to 5 (optional)

## End-to-end checklist

1. Create job → receive `{ id, uploadUri }`
2. Upload audio to `uploadUri`
3. Call `PUT /v1/external/voice-file/jobs/{jobId}/upload-complete`
4. Poll job status until completion
5. Fetch transcript and (optionally) translations
6. Get paragraph summaries for better content understanding

## How do you receive updates and delete a job?

Subscribe to `voice_file_job.created`, `voice_file_job.completed`, `voice_file_job.failed`, or `voice_file_job.deleted` to receive lifecycle updates without polling. Webhook payloads contain job metadata, not transcript text. Fetch transcript content through the transcript endpoint.

Call `DELETE /v1/external/voice-file/jobs/{jobId}` to remove a job in any status. Tiro removes the audio and generated results, and ignores processing callbacks that arrive after deletion.

## How does Tiro store and protect voice file data?

Tiro stores uploaded audio in Tiro-managed object storage and stores transcripts and translations in the Tiro service database. The API does not provide a configurable automatic retention period. Call `DELETE /v1/external/voice-file/jobs/{jobId}` when your application no longer needs the data.

A workspace user key can access jobs created by that user in the same workspace. A workspace system key can access jobs in its workspace. Deleting a job removes its uploaded audio, transcript, and translations. The deleted job is no longer available through the API.

## Polling strategy (recommended)

* Poll `GET /v1/external/voice-file/jobs/{jobId}` with exponential backoff
  * Start at 1–2s interval, then 4s, 8s, up to 30s cap
  * Stop conditions:
    * Success: `status` = `COMPLETED`
    * Failure: `status` = `FAILED`
  * After success:
    * Always fetch transcript: `GET /v1/external/voice-file/jobs/{jobId}/transcript`
    * If you requested translations: `GET /v1/external/voice-file/jobs/{jobId}/translations` or per-locale endpoint
    * Get paragraph summaries:
      * For transcript: `GET /v1/external/voice-file/jobs/{jobId}/transcript/paragraph-summary`
      * For translations: `GET /v1/external/voice-file/jobs/{jobId}/translations/{locale}/paragraph-summary`

<Note>
  The final status for successful processing is `COMPLETED`. This means all processing is complete including transcript, translation (if requested), and paragraph summaries for both.
</Note>

## File Limits & Requirements

### Supported Audio Formats

Based on industry-standard STT capabilities, Tiro supports the following formats:

**Audio Formats:**

| Format  | MIME Type  | Extension |
| ------- | ---------- | --------- |
| **MP3** | audio/mpeg | .mp3      |
| **WAV** | audio/wav  | .wav      |
| **M4A** | audio/mp4  | .m4a      |

**Video Formats (audio extraction):**

| Format  | MIME Type | Extension |
| ------- | --------- | --------- |
| **MP4** | video/mp4 | .mp4      |

### File Size & Duration Limits

| Limit Type                  | Value          | Notes                               |
| --------------------------- | -------------- | ----------------------------------- |
| **Max File Size**           | 500 MB         | Practical limit for most use cases  |
| **Max Duration**            | 4 hours        | Covers most meetings and interviews |
| **Min Sample Rate**         | 8 kHz          | Minimum for speech recognition      |
| **Recommended Sample Rate** | 16 kHz+        | Optimal for accuracy                |
| **Max Sample Rate**         | 48 kHz         | Studio quality support              |
| **Channels**                | Mono or Stereo | Multi-speaker support               |

### Processing Time Estimates

Processing times are optimized with parallel processing for longer files:

| File Duration | Typical Processing Time |
| ------------- | ----------------------- |
| \< 5 minutes  | 45-75 seconds           |
| 5-20 minutes  | 1-3 minutes             |
| 20-60 minutes | 3-6 minutes             |
| 1-4 hours     | 6-18 minutes            |

## Paragraph Summary Feature

The Paragraph Summary feature provides intelligent summarization of audio content, breaking down the transcript or translation into digestible paragraph-level summaries.

### How it works

1. **Transcript Processing**: After transcription is complete, the text is automatically split into logical paragraphs using the CompositeTextSplitter
2. **Summary Generation**: Each paragraph is processed through the ParagraphSummarizer to create concise summaries
3. **Translation Integration**: When translations are requested, summaries are regenerated based on the translated content for each locale
4. **Asynchronous Processing**: Summary generation happens asynchronously after transcript/translation completion

## Sequence

```mermaid theme={"system"}
sequenceDiagram
    participant Client
    participant API as Tiro API
    participant Storage as File Storage
    participant Worker as Tiro Worker
    participant STT as STT Engine
    participant TR as Translation Engine
    participant WH as Webhook Service

    %% Job creation
    Client->>API: POST /v1/external/voice-file/jobs (transcriptLocaleHints, translationLocales)
    API->>Storage: Generate upload URL
    API-->>Client: 201 Created {id, uploadUri}

    %% File upload
    Client->>Storage: PUT audio file
    Client->>API: PUT /v1/external/voice-file/jobs/{jobId}/upload-complete

    %% Pipeline
    API->>Worker: Enqueue job (start processing)
    Worker->>STT: Speech-to-text
    STT-->>Worker: transcript
    alt translations requested
        Worker->>TR: Translate to requested locales
        TR-->>Worker: translations
    end
    Worker->>API: mark job = COMPLETED or FAILED
    opt Webhook configured
        API-->>WH: POST {jobId, status=COMPLETED}
    end

    %% Results
    Client->>API: GET /v1/external/voice-file/jobs/{jobId}
    API-->>Client: status, timestamps
    Client->>API: GET /v1/external/voice-file/jobs/{jobId}/transcript
    API-->>Client: transcript
    Client->>API: GET /v1/external/voice-file/jobs/{jobId}/translations
    API-->>Client: translations[]
```

Ready to try it? Walk through the full flow in the [Step-by-Step Tutorial](/en/developers/voice-file/tutorial) — upload, poll, and fetch your first transcript end to end.
