> ## Documentation Index
> Fetch the complete documentation index at: https://assembly-preview.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Speech Recognition

> The Speech Recognition model enables you to transcribe spoken words into written text and is the foundation of all AssemblyAI products.

On top of the core transcription, you can enable other features and models, such as [Speaker Diarization](/docs/speech-to-text/speaker-diarization), by adding additional parameters to the same transcription request.

<Tip>
  Choose between [*Best* and *Nano*](#select-the-speech-model-with-best-and-nano) based on the cost and performance tradeoffs best suited for your application.
</Tip>

## Quickstart

The following example transcribes an audio file from a URL.

<CodeGroup>
  ```python Python theme={"system"}
  import assemblyai as aai

  aai.settings.api_key = "YOUR_API_KEY"

  # You can use a local filepath:
  # audio_file = "./example.mp3"

  # Or use a publicly-accessible URL:
  audio_file = (
      "https://assembly.ai/wildfires.mp3"
  )

  transcriber = aai.Transcriber()

  transcript = transcriber.transcribe(audio_file)

  if transcript.status == aai.TranscriptStatus.error:
      print(f"Transcription failed: {transcript.error}")
      exit(1)

  print(transcript.text)
  ```

  ```typescript Typescript theme={"system"}
  import { AssemblyAI } from 'assemblyai'

  const client = new AssemblyAI({
    apiKey: 'YOUR_API_KEY'
  })

  // You can use a local filepath:
  // const audioFile = "./example.mp3"

  // Or use a publicly-accessible URL:
  const audioFile = 'https://assembly.ai/wildfires.mp3'

  const params = {
    audio: audioFile
  }

  const run = async () => {
    const transcript = await client.transcripts.transcribe(params)

    if (transcript.status === 'error') {
      console.error(`Transcription failed: ${transcript.error}`)
      process.exit(1)
    }

    console.log(transcript.text)
  }

  run()
  ```

  ```go Go theme={"system"}
  package main

  import (
      "context"
      "log"

      aai "github.com/AssemblyAI/assemblyai-go-sdk"
  )

  func main() {
      ctx := context.Background()

      client := aai.NewClient("YOUR_API_KEY")

      // You can use a local file:
      /*
      f, err := os.Open("./example.mp3")
      [error handling here]
      transcript, err := client.Transcripts.TranscribeFromReader(ctx, f, nil)
      */

      // Or use a publicly-accessible URL:
      audioURL := "https://assembly.ai/wildfires.mp3"

      transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, nil)
      if err != nil {
        fmt.Println("Something bad happened:", err)
        os.Exit(1)
      }

      log.Println(aai.ToString(transcript.Text))
  }
  ```

  ```java Java theme={"system"}
  import com.assemblyai.api.AssemblyAI;
  import com.assemblyai.api.resources.transcripts.types.*;

  public final class App {
    public static void main(String[] args) {

        AssemblyAI client = AssemblyAI.builder()
                .apiKey("YOUR_API_KEY")
                .build();

        // You can use a local file:
        /*
        Transcript transcript = aai.transcripts().transcribe(
                 new File("./example.mp3"));
        */

        // Or use a publicly-accessible URL:
        String audioUrl = "https://assembly.ai/wildfires.mp3";

        Transcript transcript = client.transcripts().transcribe(audioUrl);

        if (transcript.getStatus().equals(TranscriptStatus.ERROR)) {
          System.err.println(transcript.getError().get());
          System.exit(1);
        }

        System.out.println(transcript.getText().get());
    }
  }
  ```

  ```csharp C# theme={"system"}
  using AssemblyAI;
  using AssemblyAI.Transcripts;

  var client = new AssemblyAIClient("YOUR_API_KEY");

  // You can use a local file:
  /*
  var transcript = await client.Transcripts.TranscribeAsync(
      new FileInfo("./example.mp3")
  );
  */

  // Or use a publicly-accessible URL:
  const string audioUrl = "https://assembly.ai/wildfires.mp3";

  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl
  });

  if (transcript.Status == TranscriptStatus.Error)
  {
      Console.WriteLine(transcript.Error);
      Environment.Exit(1);
  }

  // Alternatively, you can use the EnsureStatusCompleted() method
  // to throw an exception if the transcription status is not "completed".
  // transcript.EnsureStatusCompleted();

  Console.WriteLine(transcript.Text);
  ```

  ```ruby Ruby theme={"system"}
  require 'assemblyai'

  client = AssemblyAI::Client.new(api_key: 'YOUR_API_KEY')

  # You can upload and transcribe a local file:
  # uploaded_file = client.files.upload(file: '/path/to/your/file')
  # transcript = client.transcripts.transcribe(audio_url: uploaded_file.upload_url)

  # Or use a publicly-accessible URL:
  audio_url = 'https://assembly.ai/wildfires.mp3'

  transcript = client.transcripts.transcribe(audio_url: audio_url)

  abort transcript.error if transcript.status == AssemblyAI::Transcripts::TranscriptStatus::ERROR

  puts transcript.text
  ```
</CodeGroup>

### Example output

```
Smoke from hundreds of wildfires in Canada is triggering air quality alertsthroughout the US. Skylines from Maine to Maryland to Minnesota are gray andsmoggy. And...
```

## Word-level timestamps

The response also includes an array with information about each word:

<CodeGroup>
  ```python Python theme={"system"}
  print(transcript.words)
  ```

  ```typescript Typescript theme={"system"}
  console.log(transcript.words)
  ```

  ```go Go theme={"system"}
  for _, word := range transcript.Words {
      fmt.Printf(
          "Word: %s, Start: %d, End: %d, Confidence: %f\n",
          aai.ToString(word.Text),
          aai.ToInt64(word.Start),
          aai.ToInt64(word.End),
          aai.ToFloat64(word.Confidence),
      )
  }
  ```

  ```java Java theme={"system"}
  System.out.println(transcript.getWords());
  ```

  ```csharp C# theme={"system"}
  foreach (var word in transcript.Words!)
  {
      Console.WriteLine(
          "Word: {0}, Start: {1}, End: {2}, Confidence: {3}",
          word.Text, word.Start, word.End, word.Confidence
      );
  }
  ```

  ```ruby Ruby theme={"system"}
  puts transcript.words
  ```
</CodeGroup>

```
[
  #<AssemblyAI::Transcripts::TranscriptWord:0x000000011f65f2f0 @confidence=0.72731, @start=250, @end_=650, @text="Smoke", @speaker=nil, @additional_properties=#<OpenStruct text="Smoke", start=250, end=650, confidence=0.72731, speaker=nil>>,
  #<AssemblyAI::Transcripts::TranscriptWord:0x000000011f65f2a0 @confidence=0.99996, @start=730, @end_=1022, @text="from", @speaker=nil, @additional_properties=#<OpenStruct text="from", start=730, end=1022, confidence=0.99996, speaker=nil>>,
  ...
]
```

## Transcript status

After you've submitted a file for transcription, your transcript has one of the following statuses:

| Status       | Description                                        |
| ------------ | -------------------------------------------------- |
| `processing` | The audio file is being processed.                 |
| `queued`     | The audio file is waiting to be processed.         |
| `completed`  | The transcription has completed successfully.      |
| `error`      | An error occurred while processing the audio file. |

### Handling errors

If the transcription fails, the status of the transcript is `error`, and the transcript includes an `error` property explaining what went wrong.

<CodeGroup>
  ```python Python theme={"system"}
  if transcript.status == aai.TranscriptStatus.error:
      print(f"Transcription failed: {transcript.error}")
      exit(1)
  ```

  ```typescript Typescript theme={"system"}
  if (transcript.status === 'error') {
    console.error(`Transcription failed: ${transcript.error}`)
    process.exit(1)
  }
  ```

  ```go Go theme={"system"}
  if transcript.Status == "error" {
      log.Println("Transcription failed:", transcript.Error)
  }
  ```

  ```java Java theme={"system"}
  if (transcript.getStatus().equals(TranscriptStatus.ERROR)) {
    System.err.println(transcript.getError().get());
    System.exit(1);
  }
  ```

  ```csharp C# theme={"system"}
  if (transcript.Status == TranscriptStatus.Error)
  {
      Console.WriteLine(transcript.Error);
      Environment.Exit(1);
  }

  // Alternatively, you can use the EnsureStatusCompleted() method
  // to throw an exception if the transcription status is not "completed".
  // transcript.EnsureStatusCompleted();
  ```

  ```ruby Ruby theme={"system"}
  puts transcript.error if transcript.status == AssemblyAI::Transcripts::TranscriptStatus::ERROR
  ```
</CodeGroup>

<Note>
  A transcription may fail for various reasons:

  * Unsupported file format
  * Missing audio in file
  * Unreachable audio URL

  If a transcription fails due to a server error, we recommend that you resubmit the file for transcription to allow another server to process the audio.
</Note>

## Select the speech model with Best and Nano

We use a combination of models to produce your results. You can select the class of models to use in order to make cost-performance tradeoffs best suited for your application. You can visit our for more information on our model tiers.

| Name               | SDK Parameter          | Description                                                                                     |
| ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------- |
| **Best** (default) | `aai.SpeechModel.best` | Use our most accurate and capable models with the best results, recommended for most use cases. |
| **Nano**           | `aai.SpeechModel.nano` | Use our less accurate, but much lower cost models to produce your results.                      |

You can change the model by setting the `speech_model` in the transcription config:

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(speech_model=aai.SpeechModel.nano)

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    speech_model: 'nano'
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      SpeechModel: "nano"
  })
  ```

  ```java Java theme={"system"}
  import com.assemblyai.api.resources.transcripts.types.SpeechModel;

  var params = TranscriptOptionalParams.builder()
          .speechModel(SpeechModel.NANO)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      SpeechModel = SpeechModel.Nano
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    speech_model: AssemblyAI::Transcripts::SpeechModel::NANO
  )
  ```
</CodeGroup>

For a list of the supported languages for each model, see [Supported languages](/docs/getting-started/supported-languages).

## Automatic punctuation and casing

By default, the API automatically punctuates the transcription text and formats proper nouns, as well as converts numbers to their numerical form.

To disable punctuation and text formatting, set `punctuate` and `format_text` to `False` in the transcription config.

<CodeGroup>
  ```python Python theme={"system"}
  # create a new TranscriptionConfig
  config = aai.TranscriptionConfig(punctuate=False, format_text=False)

  # set the configuration
  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    punctuate: false,
    format_text: false
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      Punctuate:  aai.Bool(false),
      FormatText: aai.Bool(false),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .punctuate(false)
          .formatText(false)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      Punctuate = false,
      FormatText = false
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    punctuate: false,
    format_text: false
  )
  ```
</CodeGroup>

## Automatic language detection

Identify the dominant language spoken in an audio file and use it during the transcription. Enable it to detect any of the [supported languages](/docs/getting-started/supported-languages).

To reliably identify the dominant language, the file must contain **at least 50 seconds** of spoken audio.

To enable it, set `language_detection` to `True` in the transcription config.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(language_detection=True)

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    language_detection: true
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      LanguageDetection: aai.Bool(true),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .languageDetection(true)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      LanguageDetection = true
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    language_detection: true
  )
  ```
</CodeGroup>

<Tip>
  By performing automatic language detection on a small chunk of audio first, you can then select between the Best or Nano model depending on the detected language. To learn more, see [Separating automatic language detection from transcription](/docs/guides/automatic-language-detection-workflow).
</Tip>

### Confidence score

If language detection is enabled, the API returns a confidence score for the detected language. The score ranges from 0.0 (low confidence) to 1.0 (high confidence).

<CodeGroup>
  ```python Python theme={"system"}
  print(transcript.json_response["language_confidence"])
  ```

  ```typescript Typescript theme={"system"}
  console.log(transcript.language_confidence)
  ```

  ```go Go theme={"system"}
  fmt.Printf(aai.ToFloat64(transcript.LanguageConfidence))
  ```

  ```java Java theme={"system"}
  System.out.println(transcript.getLanguageConfidence().get());
  ```

  ```ruby Ruby theme={"system"}
  puts transcript.language_confidence
  ```
</CodeGroup>

### Set a language confidence threshold

You can set the confidence threshold that must be reached if language detection is enabled. An error will be returned if the language confidence is below this threshold. Valid values are in the range \[0,1] inclusive.

<Tip>
  For a workflow that resubmits a transcription request using a default language if the threshold is not reached, see [this cookbook](https://github.com/AssemblyAI/cookbook/blob/master/core-transcription/automatic-language-detection-route-default-language-python.ipynb).
</Tip>

## Set language manually

If you already know the dominant language, you can use the `language_code` key to specify the language of the speech in your audio file.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(language_code="es")
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    language_code: 'es'
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      LanguageCode: "es",
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .languageCode(TranscriptLanguageCode.ES)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      LanguageCode = TranscriptLanguageCode.Es
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    language_code: AssemblyAI::Transcripts::TranscriptLanguageCode::ES
  )
  ```
</CodeGroup>

To see all supported languages and their codes, see [Supported languages](/docs/getting-started/supported-languages).

## Custom spelling

Custom Spelling lets you customize how words are spelled or formatted in the transcript.

To use Custom Spelling, pass a dictionary to `set_custom_spelling()` on the transcription config. Each key-value pair specifies a mapping from a word or phrase to a new spelling or format. The key specifies the new spelling or format, and the corresponding value is the word or phrase you want to replace.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig()
  config.set_custom_spelling(
    {
      "Gettleman": ["gettleman"],
      "SQL": ["Sequel"],
    }
  )
  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    custom_spelling: [
      {
        from: ['gettleman'],
        to: 'Gettleman'
      },
      {
        from: ['Sequel'],
        to: 'SQL'
      }
    ]
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      CustomSpelling: []aai.TranscriptCustomSpelling{
          {
              From: []string{"gettleman"},
              To:   aai.String("Gettleman"),
          },
          {
              From: []string{"Sequel"},
              To:   aai.String("SQL"),
          },
      },
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .customSpelling(List.of(TranscriptCustomSpelling.builder().to("Gettleman").addFrom("gettleman").build(),
                  TranscriptCustomSpelling.builder().to("SQL").addFrom("Sequel").build()))
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      CustomSpelling =
      [
          new TranscriptCustomSpelling
          {
              From = ["gettleman"],
              To = "Gettleman"
          },
          new TranscriptCustomSpelling
          {
              From = ["Sequel"],
              To = "SQL"
          }
      ]
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    custom_spelling: [
      {
        from: ['gettleman'],
        to: 'Gettleman'
      },
      {
        from: ['Sequel'],
        to: 'SQL'
      }
    ]
  )
  ```
</CodeGroup>

<Note>
  The value in the `to` key is case-sensitive, but the value in the `from` key isn't. Additionally, the `to` key must only contain one word, while the `from` key can contain multiple words.
</Note>

## Custom vocabulary

To improve the transcription accuracy, you can boost certain words or phrases that appear frequently in your audio file.

To boost words or phrases, include the `word_boost` parameter in the transcription config.

You can also control how much weight to apply to each keyword or phrase. Include `boost_param` in the transcription config with a value of `low`, `default`, or `high`.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(
    word_boost=["aws", "azure", "google cloud"],
    boost_param="high"
  )

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    word_boost: ['aws', 'azure', 'google cloud'],
    boost_param: 'high'
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      WordBoost:  []string{"aws", "azure", "google cloud"},
      BoostParam: "high",
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .wordBoost(List.of("aws", "azure", "google cloud"))
          .boostParam(TranscriptBoostParam.HIGH)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      WordBoost = ["aws", "azure", "google cloud"],
      BoostParam = TranscriptBoostParam.High
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    word_boost: ['aws', 'azure', 'google cloud'],
    boost_param: AssemblyAI::Transcripts::TranscriptBoostParam::HIGH
  )
  ```
</CodeGroup>

<Note>
  Follow formatting guidelines for custom vocabulary to ensure the best results:

  * Remove all punctuation except apostrophes.
  * Make sure each word is in its spoken form. For example, `iphone seven` instead of `iphone 7`.
  * Remove spaces between letters in acronyms.

  Additionally, the model still accepts words with unique characters such as é, but converts them to their ASCII equivalent.

  You can boost a maximum of 1,000 unique keywords and phrases, where each of them can contain up to 6 words.
</Note>

## Multichannel transcription

If you have a multichannel audio file with multiple speakers, you can transcribe each of them separately.

To enable it, set `multichannel` to `true` in your transcription config.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(multichannel=True)

  transcriber = aai.Transcriber(config=config)
  transcript = transcriber.transcribe(audio_url)

  print(transcript.json_response["audio_channels"])

  print(transcript.utterances)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    multichannel: true
  }

  const transcript = await client.transcripts.transcribe(params)
  console.log(transcript.utterances)
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      Multichannel: aai.Bool(true),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
                  .multichannel(true)
                  .build();

  Transcript transcript = client.transcripts().transcribe(audioUrl, params);

  System.out.println(transcript.getUtterances());
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      Multichannel = true
  });

  foreach (var utterance in transcript.Utterances!)
  {
      Console.WriteLine($"Speaker: {utterance.Speaker}, Word: {utterance.Text}");
  }
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    multichannel: true
  )

  p transcript.utterances
  ```
</CodeGroup>

<Note>
  Multichannel audio increases the transcription time by approximately 25%.

  The response includes an `audio_channels` property with the number of different channels, and an additional `utterances` property, containing a list of turn-by-turn utterances.

  Each utterance contains channel information, starting at 1.

  Additionally, each word in the `words` array contains the channel identifier.
</Note>

## Dual-channel transcription

<Info>
  Dual-channel is a legacy feature. Use [Multichannel](#multichannel-transcription) instead.
</Info>

## Export SRT or VTT caption files

You can export completed transcripts in SRT or VTT format, which can be used for subtitles and closed captions in videos.

You can also customize the maximum number of characters per caption by specifying the `chars_per_caption` parameter.

<CodeGroup>
  ```python Python theme={"system"}
  srt = transcript.export_subtitles_srt()
  srt = transcript.export_subtitles_srt(chars_per_caption=32)

  vtt = transcript.export_subtitles_vtt()
  vtt = transcript.export_subtitles_vtt(chars_per_caption=32)
  ```

  ```typescript Typescript theme={"system"}
  const transcript = await client.transcripts.transcribe(params)

  let srt = await client.transcripts.subtitles(transcript.id, 'srt')
  srt = await client.transcripts.subtitles(transcript.id, 'srt', 32)

  let vtt = await client.transcripts.subtitles(transcript.id, 'vtt')
  vtt = await client.transcripts.subtitles(transcript.id, 'vtt', 32)
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      DualChannel: aai.Bool(true),
  })

  params := &aai.TranscriptGetSubtitlesOptions{
      CharsPerCaption: 32,
  }

  srt, _ := client.Transcripts.GetSubtitles(ctx, aai.ToString(transcript.ID), "srt", params)

  vtt, _ := client.Transcripts.GetSubtitles(ctx, aai.ToString(transcript.ID), "vtt", params)
  ```

  ```java Java theme={"system"}
  Transcript transcript = client.transcripts().transcribe(audioUrl, params);

  var srt = client.transcripts().getSubtitles(transcript.getId(), SubtitleFormat.SRT);
  srt = client.transcripts().getSubtitles(transcript.getId(), SubtitleFormat.SRT, GetSubtitlesParams.builder().charsPerCaption(32).build());

  var vtt = client.transcripts().getSubtitles(transcript.getId(), SubtitleFormat.VTT);
  vtt = client.transcripts().getSubtitles(transcript.getId(), SubtitleFormat.VTT, GetSubtitlesParams.builder().charsPerCaption(32).build());
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl
  });

  var stt = await client.Transcripts.GetSubtitlesAsync(transcript.Id, SubtitleFormat.Srt);
  stt = await client.Transcripts.GetSubtitlesAsync(transcript.Id, SubtitleFormat.Srt, charsPerCaption: 32);

  var vtt = await client.Transcripts.GetSubtitlesAsync(transcript.Id, SubtitleFormat.Vtt);
  vtt = await client.Transcripts.GetSubtitlesAsync(transcript.Id, SubtitleFormat.Vtt, charsPerCaption: 32);
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(audio_url: audio_url)

  srt = client.transcripts.get_subtitles(
    transcript_id: transcript.id,
    subtitle_format: AssemblyAI::Transcripts::SubtitleFormat::SRT
  )
  srt = client.transcripts.get_subtitles(
    transcript_id: transcript.id,
    subtitle_format: AssemblyAI::Transcripts::SubtitleFormat::SRT,
    chars_per_caption: 32
  )

  vtt = client.transcripts.get_subtitles(
    transcript_id: transcript.id,
    subtitle_format: AssemblyAI::Transcripts::SubtitleFormat::VTT
  )
  vtt = client.transcripts.get_subtitles(
    transcript_id: transcript.id,
    subtitle_format: AssemblyAI::Transcripts::SubtitleFormat::VTT,
    chars_per_caption: 32
  )
  ```
</CodeGroup>

## Export paragraphs and sentences

You can retrieve transcripts that are automatically segmented into paragraphs or sentences, for a more reader-friendly experience.

The text of the transcript is broken down by either paragraphs or sentences, along with additional metadata.

<CodeGroup>
  ```python Python theme={"system"}
  sentences = transcript.get_sentences()
  for sentence in sentences:
    print(sentence.text)

  paragraphs = transcript.get_paragraphs()
  for paragraph in paragraphs:
    print(paragraph.text)
  ```

  ```typescript Typescript theme={"system"}
  const transcript = await client.transcripts.transcribe(params)

  const { sentences } = await client.transcripts.sentences(transcript.id)
  for (const sentence of sentences) {
    console.log(sentence.text)
  }

  const { paragraphs } = await client.transcripts.paragraphs(transcript.id)
  for (const paragraph of paragraphs) {
    console.log(paragraph.text)
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      DualChannel: aai.Bool(true),
  })

  sentences, _ := client.Transcripts.GetSentences(ctx, aai.ToString(transcript.ID))

  for _, sentence := range sentences.Sentences {
      fmt.Println(aai.ToString(sentence.Text))
  }

  paragraphs, _ := client.Transcripts.GetParagraphs(ctx, aai.ToString(transcript.ID))

  for _, paragraph := range paragraphs.Paragraphs {
      fmt.Println(aai.ToString(paragraph.Text))
  }
  ```

  ```java Java theme={"system"}
  Transcript transcript = client.transcripts().transcribe(audioUrl, params);

  var sentences = client.transcripts().getSentences(transcript.getId());
  System.out.println(sentences);

  var paragraphs = client.transcripts().getParagraphs(transcript.getId());
  System.out.println(paragraphs);
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl
  });

  var sentencesResponse = await client.Transcripts.GetSentencesAsync(transcript.Id);
  foreach (var sentence in sentencesResponse.Sentences) {
      Console.WriteLine(sentence.Text);
  }

  var paragraphsResponse = await client.Transcripts.GetParagraphsAsync(transcript.Id);
  foreach (var paragraph in paragraphsResponse.Paragraphs) {
      Console.WriteLine(paragraph.Text);
  }
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(audio_url: audio_url)

  sentences = client.transcripts.get_sentences(transcript_id: transcript.id)
  p sentences

  paragraphs = client.transcripts.get_paragraphs(transcript_id: transcript.id)
  p paragraphs
  ```
</CodeGroup>

The response is an array of objects, each representing a sentence or a paragraph in the transcript. See the [API reference](#sentences-and-paragraphs) for more info.

## Filler words

The following filler words are removed by default:

* "um"
* "uh"
* "hmm"
* "mhm"
* "uh-huh"
* "ah"
* "huh"
* "hm"
* "m"

If you want to keep filler words in the transcript, you can set the `disfluencies` to `true` in the transcription config.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(disfluencies=True)

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    disfluencies: true
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      Disfluencies: aai.Bool(true),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .disfluencies(true)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      Disfluencies = true
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    disfluencies: true
  )
  ```
</CodeGroup>

## Profanity filtering

You can automatically filter out profanity from the transcripts by setting `filter_profanity` to `true` in your transcription config.

Any profanity in the returned `text` will be replaced with asterisks.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(filter_profanity=True)

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    filter_profanity: true
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      FilterProfanity: aai.Bool(true),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .filterProfanity(true)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      FilterProfanity = true
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    filter_profanity: true
  )
  ```
</CodeGroup>

<Note>
  Profanity filter isn't perfect. Certain words may still be missed or improperly filtered.
</Note>

## Set the start and end of the transcript

If you only want to transcribe a portion of your file, you can set the `audio_start_from` and the `audio_end_at` parameters in your transcription config.

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(
    audio_start_from=5000,  # The start time of the transcription in milliseconds
    audio_end_at=15000  # The end time of the transcription in milliseconds
  )

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    audio_start_from: 5000, // The start time of the transcription in milliseconds
    audio_end_at: 15000 // The end time of the transcription in milliseconds
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      AudioStartFrom: aai.Int64(5000),
      AudioEndAt:     aai.Int64(15000),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .audioStartFrom(5000)
          .audioEndAt(15000)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      AudioStartFrom = 5000,
      AudioEndAt = 15000
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    audio_start_from: 5_000,
    audio_end_at: 15_000
  )
  ```
</CodeGroup>

## Speech threshold

To only transcribe files that contain at least a specified percentage of spoken audio, you can set the `speech_threshold` parameter. You can pass any value between 0 and 1.

If the percentage of speech in the audio file is below the provided threshold, the value of `text` is `None` and the response contains an `error` message:

```
Audio speech threshold 0.9461 is below the requested speech threshold value 1.0
```

<CodeGroup>
  ```python Python theme={"system"}
  config = aai.TranscriptionConfig(speech_threshold=0.1)

  transcriber = aai.Transcriber(config=config)
  ```

  ```typescript Typescript theme={"system"}
  const params = {
    audio: audioUrl,
    speech_threshold: 0.1
  }
  ```

  ```go Go theme={"system"}
  transcript, _ := client.Transcripts.TranscribeFromURL(ctx, audioURL, &aai.TranscriptOptionalParams{
      SpeechThreshold: aai.Float64(0.1),
  })
  ```

  ```java Java theme={"system"}
  var params = TranscriptOptionalParams.builder()
          .speechThreshold(0.1)
          .build();
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      SpeechThreshold = 0.1f
  });
  ```

  ```ruby Ruby theme={"system"}
  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    speech_threshold: 0.1
  )
  ```
</CodeGroup>

## Word search

You can search through a completed transcript for a specific set of keywords, which is useful for quickly finding relevant information.

The parameter can be a list of words, numbers, or phrases up to five words.

<CodeGroup>
  ```python Python theme={"system"}
  # Set the words you want to search for
  words = ["foo", "bar", "foo bar", "42"]

  matches = transcript.word_search(words)

  for match in matches:
      print(f"Found '{match.text}' {match.count} times in the transcript")
  ```

  ```typescript Typescript theme={"system"}
  // Set the words you want to search for.
  const words = ['foo', 'bar', 'foo bar', '42']

  const transcript = await client.transcripts.transcribe(params)

  const { matches } = await client.transcripts.wordSearch(transcript.id, words)

  for (const match of matches) {
    console.log(`Found '${match.text}' ${match.count} times in the transcript`)
  }
  ```

  ```go Go theme={"system"}
  // Set the words you want to search for.
  words := []string{"foo", "bar", "foo bar", "42"}

  resp, _ := client.Transcripts.WordSearch(ctx, aai.ToString(transcript.ID), words)

  for _, match := range resp.Matches {
      fmt.Println("Found %q %d times in the transcript.",
          aai.ToString(match.Text),
          aai.ToInt64(match.Count),
      )
  }
  ```

  ```java Java theme={"system"}
  Transcript transcript = client.transcripts().transcribe(audioUrl, params);

  var words = List.of("foo", "bar", "foo bar", "42");
  var matchesResponse = client.transcripts().wordSearch(transcript.getId(), words);

  for (var match: matchesResponse.getMatches()){
      System.out.printf("Found '%s' %d times in the transcript%n", match.getText(), match.getCount());
  }
  ```

  ```csharp C# theme={"system"}
  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
  });

  var matchesResponse = await client.Transcripts.WordSearchAsync(
      transcript.Id,
      ["foo", "bar", "foo bar", "42"]
  );

  foreach (var match in matchesResponse.Matches)
  {
      Console.WriteLine($"Found '{match.Text}' {match.Count} times in the transcript");
  }
  ```

  ```ruby Ruby theme={"system"}
  word = 'foo'

  transcript = client.transcripts.transcribe(audio_url: audio_url)

  response = client.transcripts.word_search(
    transcript_id: transcript.id,
    words: [word]
  )

  response.matches.each do |match|
    printf(
      "Found '%<word>s' %<count>d times in the transcript",
      word: match.text,
      count: match.count
    )
  end
  ```
</CodeGroup>

## Delete transcripts

You can remove the data from the transcript and mark it as deleted.

<CodeGroup>
  ```python Python theme={"system"}
  aai.Transcript.delete_by_id("1234")
  ```

  ```typescript Typescript theme={"system"}
  const res = await client.transcripts.delete('1234')
  ```

  ```go Go theme={"system"}
  transcript, err := client.Transcripts.Delete(ctx, "1234")
  ```

  ```java Java theme={"system"}
  aai.transcript().delete("1234");
  ```

  ```csharp C# theme={"system"}
  await client.Transcripts.DeleteAsync("1234");
  ```

  ```ruby Ruby theme={"system"}
  api.transcripts.delete(transcript_id: "1234")
  ```
</CodeGroup>

<Note>
  Starting on 11-26-2024, the platform will assign an account-level Time to Live (TTL) for customers who have executed a Business Associate Agreement (BAA) with AssemblyAI. For those customers, all transcripts generated via the async transcription endpoint will be deleted after the TTL period.

  As of the feature launch date:

  * The TTL is set to 3 days (subject to change).
  * Customers can still manually delete transcripts before the TTL period by using the deletion endpoint. However, they cannot keep transcripts on the platform after the TTL period has expired.

  BAAs are limited to customers who process PHI, subject to HIPAA. If you are processing PHI and require a BAA, please reach out to [sales@assemblyai.com](mailto:sales@assemblyai.com).
</Note>

## API reference

You can find the API reference [here](/docs/api-reference/).

## Troubleshooting

<Accordion title="How can I make certain words more likely to be transcribed?">
  You can include words, phrases, or both in the `word_boost` parameter. Any term included has its likelihood of being transcribed boosted.
</Accordion>

<Accordion title="Can I customize how words are spelled by the model?">
  Yes. The Custom Spelling feature gives you the ability to specify how words are spelled or formatted in the transcript text. For example, Custom Spelling could be used to change the spelling of all instances of the word "Ariana" to "Arianna". It could also be used to change the formatting of "CS 50" to "CS50".
</Accordion>

<Accordion title="Why am I receiving a 400 Bad Request error when making an API request?">
  A "400 Bad Request" error typically indicates that there's a problem with the formatting or content of the API request. Double-check the syntax of your request and ensure that all required parameters are included as described in the [API reference](https://assemblyai.com/docs/api-reference/transcripts). If the issue persists, contact our support team for assistance.
</Accordion>
