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

# Audio Recap

> Audio summaries of study materials for on-the-go learning

## Overview

The Audio Recap component converts your study materials into audio summaries, perfect for reviewing content during commutes, workouts, or when visual reading isn't practical. Supports multiple voices and languages.

When **`topic`** is set and **`folders`** are included, generation can narrow folder-derived materials toward that topic (best-effort). Use **`excludedMaterialIds`** to omit specific materials that would otherwise be included from selected folders; IDs listed here are ignored if the same material is also listed in **`materials`** (explicit selections win).

<Tip>
  **How much source material fits per length.** When you generate a recap from materials *without* a **`topic`**, the selected materials are split evenly across the recap up to an approximate source-content budget for the chosen length — anything beyond it is truncated. Set a **`topic`** to prioritize the most relevant content instead of having it split evenly. The longer the recap (`duration`), the more source material it can include:

  | Length   | `duration` (min) | Approx. source material |
  | -------- | ---------------- | ----------------------- |
  | Short    | 3                | \~100 KB                |
  | Medium   | 6                | \~250 KB                |
  | Long     | 12               | \~250 KB                |
  | Extended | 24               | \~400 KB                |
  | Complete | 30               | \~400 KB                |
  | Ultra    | 45               | \~500 KB                |

  If your materials exceed the budget for the length you picked, either use a longer `duration` or set a `topic` so the most relevant content is kept.
</Tip>

## Creating an Audio Recap Component

<CodeGroup>
  ```javascript JavaScript theme={null}
  import StudyfetchSDK from '@studyfetch/sdk';

  const client = new StudyfetchSDK({
    apiKey: 'your-api-key',
    baseURL: 'https://studyfetchapi.com',
  });

  const audioComponent = await client.v1.components.create({
    name: 'Biology Chapter Audio Summary',
    type: 'audio_recap',
    config: {
      materials: ['mat-123', 'mat-456'],
      folders: ['folder-789'],
      excludedMaterialIds: ['mat-skip-from-folder'],
      recapType: 'SUMMARY',
      duration: 10,
      numParts: 3,
      isMultiVoice: true,
      voice1: 'Puck',
      voice2: 'Aoede',
      model: 'gpt-4.1-2025-04-14',
      topic: 'Cell Biology',
      theme: 'Educational podcast style'
    }
  });

  console.log('Audio recap component created:', audioComponent._id);
  ```

  ```python Python theme={null}
  from studyfetch_sdk import StudyfetchSDK

  client = StudyfetchSDK(
      api_key="your-api-key",
      base_url="https://studyfetchapi.com",
  )

  audio_component = client.v1.components.create(
      name="Biology Chapter Audio Summary",
      type="audio_recap",
      config={
          "materials": ["mat-123", "mat-456"],
          "folders": ["folder-789"],
          "excludedMaterialIds": ["mat-skip-from-folder"],
          "recapType": "SUMMARY",
          "duration": 10,
          "numParts": 3,
          "isMultiVoice": True,
          "voice1": "Puck",
          "voice2": "Aoede",
          "model": "gpt-4.1-2025-04-14",
          "topic": "Cell Biology",
          "theme": "Educational podcast style"
      }
  )

  print(f"Audio recap component created: {audio_component._id}")
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.components.ComponentResponse;
  import com.studyfetch.javasdk.models.v1.components.ComponentCreateParams;

  import java.util.List;

  public class CreateAudioRecapComponent {
      public static void main(String[] args) {
          StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
              .fromEnv()
              .baseUrl("https://studyfetchapi.com")
              .build();

          ComponentCreateParams params = ComponentCreateParams.builder()
              .name("Biology Chapter Audio Summary")
              .type(ComponentCreateParams.Type.AUDIO_RECAP)
              .config(ComponentCreateParams.Config.AudioRecapConfigDto.builder()
                  .materials(List.of("mat-123", "mat-456"))
                  .folders(List.of("folder-789"))
                  .excludedMaterialIds(List.of("mat-skip-from-folder"))
                  .recapType(ComponentCreateParams.Config.AudioRecapConfigDto.RecapType.SUMMARY)
                  .duration(10)
                  .numParts(3)
                  .isMultiVoice(true)
                  .voice1("Puck")
                  .voice2("Aoede")
                  .model("gpt-4.1-2025-04-14")
                  .topic("Cell Biology")
                  .theme("Educational podcast style")
                  .build())
              .build();

          ComponentResponse component = client.v1().components().create(params);
          System.out.println("Audio recap component created: " + component._id());
      }
  }
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Components;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;
  using RecapType = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.AudioRecapConfigDtoProperties.RecapType;

  public class CreateAudioRecapComponent
  {
      public static async Task CreateAudioRecap()
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          var audioComponent = await client.V1.Components.Create(new()
          {
              Name = "Biology Chapter Audio Summary",
              Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.AudioRecap,
              Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.AudioRecapConfigDto()
              {
                  Materials = new List<string> { "mat-123", "mat-456" },
                  Folders = new List<string> { "folder-789" },
                  ExcludedMaterialIds = new List<string> { "mat-skip-from-folder" },
                  RecapType = RecapType.Summary,
                  Duration = 10,
                  NumParts = 3,
                  IsMultiVoice = true,
                  Voice1 = "Puck",
                  Voice2 = "Aoede",
                  Model = "gpt-4.1-2025-04-14",
                  Topic = "Cell Biology",
                  Theme = "Educational podcast style",
              }
          });

          Console.WriteLine($"Audio recap component created: {audioComponent._ID}");
      }
  }
  ```
</CodeGroup>

## Configuration Parameters

<ParamField body="name" type="string" required>
  Name of the audio recap component
</ParamField>

<ParamField body="type" type="string" required>
  Must be `"audio_recap"`
</ParamField>

<ParamField body="config" type="object" required>
  Audio recap configuration object

  <Expandable title="Configuration Properties">
    <ParamField body="materials" type="array" required>
      Array of material IDs to generate audio from
    </ParamField>

    <ParamField body="folders" type="array">
      Array of folder IDs containing materials
    </ParamField>

    <ParamField body="excludedMaterialIds" type="array">
      Material IDs to exclude when expanding selected **folders**. Has no effect on materials you list directly in **`materials`**—if an ID appears in both **`materials`** and **`excludedMaterialIds`**, the explicit **`materials`** entry wins.
    </ParamField>

    <ParamField body="recapType" type="string" default="SUMMARY">
      Type of audio recap to generate:

      * `SUMMARY` - Concise summary highlighting important points
      * `LECTURE` - Formal academic lecture style
      * `PODCAST` - Conversational podcast-style discussion
      * `AUDIO_BOOK` - Detailed audio book narration
    </ParamField>

    <ParamField body="duration" type="number" default="10">
      Target duration in minutes for the audio recap (affects content depth). Longer durations also raise the amount of source material included before truncation — see the source-material budget table in the [Overview](#overview).
    </ParamField>

    <ParamField body="numParts" type="number" default="3">
      Number of sections to divide the content into
    </ParamField>

    <ParamField body="isMultiVoice" type="boolean" default="false">
      Whether to use multiple voices for a conversational format
    </ParamField>

    <ParamField body="voice1" type="string" default="Puck">
      Primary voice for narration. Available voices:

      * `Puck` - Default voice
      * `Riley` - Friendly and warm
      * `Morgan` - British accent
      * `Fenrir` - Energetic and engaging
      * `Aoede` - Secondary voice for conversations
    </ParamField>

    <ParamField body="voice2" type="string" default="Aoede">
      Secondary voice for multi-voice conversations (used when `isMultiVoice` is true)
    </ParamField>

    <ParamField body="model" type="string" default="gpt-4.1-2025-04-14">
      AI model to use for content generation
    </ParamField>

    <ParamField body="topic" type="string">
      Specific topic to focus on within the materials. Together with **`folders`**, this can steer which folder-derived materials are used (best-effort relevance filtering).
    </ParamField>

    <ParamField body="theme" type="string">
      Style or theme for the audio content (e.g., "casual educational", "formal academic")
    </ParamField>
  </Expandable>
</ParamField>

## Response

```json theme={null}
{
  "_id": "comp_202mno",
  "name": "Biology Chapter Audio Summary",
  "type": "audio_recap",
  "status": "processing",
  "config": {
    "materials": ["mat-123", "mat-456"],
    "folders": ["folder-789"],
    "excludedMaterialIds": ["mat-skip-from-folder"],
    "recapType": "SUMMARY",
    "duration": 10,
    "numParts": 3,
    "isMultiVoice": true,
    "voice1": "Puck",
    "voice2": "Aoede",
    "model": "gpt-4.1-2025-04-14",
    "topic": "Cell Biology",
    "theme": "Educational podcast style"
  },
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-15T10:00:00Z",
  "organizationId": "org_456def",
  "audioFile": {
    "url": null,
    "duration": null,
    "size": null
  }
}
```

## Embedding This Component

Once you've created an Audio Recap component, you can embed it on your website using the embedding API.

### Generate Embed URL

<CodeGroup>
  ```javascript JavaScript theme={null}
  const embedResponse = await client.v1.components.generateEmbed(audioComponent._id, {
    // User tracking
    userId: 'user-456',
    studentName: 'Jane Smith',  // Student name for display
    groupIds: ['class-101', 'class-102'],
    sessionId: 'session-789',
    
    // Audio-specific features
    features: {
      enableTranscript: true,
      enableOutline: true,
      enableHistory: true
    },
    
    // Dimensions
    width: '100%',
    height: '400px',
    
    // Token expiry
    expiryHours: 24
  });
  ```

  ```python Python theme={null}
  embed_response = client.v1.components.generateEmbed(
      component_id=audio_component._id,
      userId="user-456",
      student_name="Jane Smith",  # Student name for display
      groupIds=["class-101", "class-102"],
      sessionId="session-789",
      features={
          "enableTranscript": True,
          "enableOutline": True,
          "enableHistory": True
      },
      width="100%",
      height="400px",
      expiryHours=24
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
  import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .fromEnv()
      .baseUrl("https://studyfetchapi.com")
      .build();

  ComponentGenerateEmbedParams params = ComponentGenerateEmbedParams.builder()
      .id(audioComponent._id())
      // User tracking
      .userId("user-456")
      .studentName("Jane Smith")  // Student name for display
      .groupIds(List.of("class-101", "class-102"))
      .sessionId("session-789")
      
      // Audio-specific features
      .features(ComponentGenerateEmbedParams.Features.builder()
          .enableTranscript(true)
          .enableOutline(true)
          .enableHistory(true)
          .build())
      
      // Dimensions
      .width("100%")
      .height("400px")
      
      // Token expiry
      .expiryHours(24)
      .build();

  ComponentGenerateEmbedResponse embedResponse = client.v1().components()
      .generateEmbed(params);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Components;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;

  public class GenerateAudioRecapEmbed
  {
      public static async Task GenerateEmbed()
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          var embedResponse = await client.V1.Components.GenerateEmbed(new()
          {
              ID = "component_123abc", // Replace with your component ID
              UserID = "user-456",
              StudentName = "Jane Smith",  // Student name for display
              GroupIDs = new List<string> { "class-101", "class-102" },
              Width = "100%",
              Height = "600px"
          });

          Console.WriteLine($"Embed URL: {embedResponse.EmbedURL}");
          Console.WriteLine($"Token: {embedResponse.Token}");
      }
  }
  ```
</CodeGroup>

### Audio Recap-Specific Embedding Features

<ParamField body="features.enableTranscript" type="boolean" default="true">
  Show synchronized transcript alongside the audio player
</ParamField>

<ParamField body="features.enableOutline" type="boolean" default="true">
  Display chapter markers and content outline for easy navigation
</ParamField>

<ParamField body="features.enableHistory" type="boolean" default="true">
  Remember playback position and show listening history
</ParamField>

## User Progress & Status Tracking

Audio Recap embeds can track how far each learner has listened through a recap. Progress is tracked per **user**, per **section**, and can be grouped by class or cohort using `groupIds`.

Progress is recorded only when the embed token includes a `userId`. Anonymous embeds do not create progress records.

<Info>
  StudyFetch does not generate user IDs for you. Use the stable learner identifier from your platform, such as an LMS user ID, student ID, UUID, or email address.
</Info>

### How Tracking Works

When you generate an embed URL, include one `userId` for the learner viewing that iframe:

```json theme={null}
{
  "userId": "student-001",
  "groupIds": ["class-101"]
}
```

One embed session should represent one learner. To track a full class, generate one embed token per learner with a unique `userId` and shared `groupIds`.

The Audio Recap player reports:

* `lastPosition` — the learner's last known playback position for a section, in seconds
* `completed` — whether the learner completed a section
* `groupIds` — group or class IDs supplied when generating the embed

### List Progress for a Recap

Use the audio recap **`componentId`** (for example, `audio_recap_abc123`) to list all users with recorded progress.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const progress = await client.v1.audioRecaps.listProgress('audio_recap_abc123', {
    groupId: 'class-101',
  });

  console.log(progress.users);
  ```

  ```python Python theme={null}
  progress = client.v1.audio_recaps.list_progress(
      "audio_recap_abc123",
      group_id="class-101",
  )

  print(progress.users)
  ```

  ```java Java theme={null}
  var progress = client.v1().audioRecaps().listProgress(
      "audio_recap_abc123",
      AudioRecapListProgressParams.builder()
          .groupId("class-101")
          .build()
  );

  System.out.println(progress.users());
  ```

  ```csharp C# theme={null}
  var progress = await client.V1.AudioRecaps.ListProgress(new()
  {
      ComponentID = "audio_recap_abc123",
      GroupID = "class-101",
  });

  Console.WriteLine(progress.TotalUsers);
  ```

  ```curl cURL theme={null}
  curl "https://studyfetchapi.com/api/v1/audio-recaps/progress/audio_recap_abc123?groupId=class-101" \
    -H "x-api-key: your-api-key"
  ```
</CodeGroup>

#### Response

```json theme={null}
{
  "totalSections": 21,
  "totalUsers": 2,
  "users": [
    {
      "userId": "student-001",
      "groupIds": ["class-101"],
      "sectionsCompleted": 2,
      "completionPct": 10,
      "lastActivityAt": "2026-06-18T15:20:45.577Z",
      "currentSection": {
        "order": 2,
        "lastPosition": 9
      }
    }
  ]
}
```

### Get One User's Section Progress

Use this endpoint to see section-by-section playback status for a learner.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const detail = await client.v1.audioRecaps.retrieveUserProgress(
    'audio_recap_abc123',
    'student-001'
  );

  console.log(detail.sections);
  ```

  ```python Python theme={null}
  detail = client.v1.audio_recaps.retrieve_user_progress(
      "audio_recap_abc123",
      "student-001",
  )

  print(detail.sections)
  ```

  ```java Java theme={null}
  var detail = client.v1().audioRecaps().retrieveUserProgress(
      "audio_recap_abc123",
      "student-001"
  );

  System.out.println(detail.sections());
  ```

  ```csharp C# theme={null}
  var detail = await client.V1.AudioRecaps.RetrieveUserProgress(new()
  {
      ComponentID = "audio_recap_abc123",
      UserID = "student-001",
  });

  Console.WriteLine(detail.User.CompletionPct);
  ```

  ```curl cURL theme={null}
  curl "https://studyfetchapi.com/api/v1/audio-recaps/progress/audio_recap_abc123/users/student-001" \
    -H "x-api-key: your-api-key"
  ```
</CodeGroup>

#### Response

```json theme={null}
{
  "user": {
    "userId": "student-001",
    "groupIds": ["class-101"],
    "sectionsCompleted": 2,
    "totalSections": 21,
    "completionPct": 10
  },
  "sections": [
    {
      "sectionId": "section-id-1",
      "order": 0,
      "scriptPreview": "Spark.E here! Let's explore...",
      "lastPosition": 8,
      "completed": true,
      "completedAt": "2026-06-18T15:20:17.740Z",
      "updatedAt": "2026-06-18T15:20:17.764Z"
    },
    {
      "sectionId": "section-id-2",
      "order": 1,
      "scriptPreview": "Our exploration begins...",
      "lastPosition": 9,
      "completed": false,
      "updatedAt": "2026-06-18T15:20:45.577Z"
    }
  ]
}
```

### Embed in Your HTML

```html theme={null}
<iframe 
  src="https://embed.studyfetch.com/component/comp_202mno?token=..."
  width="100%"
  height="400px"
  frameborder="0"
  style="border: 1px solid #e5e5e5; border-radius: 8px;">
</iframe>
```
