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

# Quickstart

> Upload materials, create components, and embed them in 3 simple steps

# Quickstart Guide

Get up and running with StudyFetch in just 5 minutes. You'll learn how to:

<Steps>
  <Step title="Create or Upload Material">
    Create text-based materials or upload files (PDFs, documents, etc.) to build your knowledge base
  </Step>

  <Step title="Create Component">
    Create an AI component (chat, flashcards, tests, etc.) that uses your materials
  </Step>

  <Step title="Embed Component">
    Generate an embed URL and add it to your website with a simple iframe
  </Step>
</Steps>

## Prerequisites

Before you begin, make sure you have:

* An API key ([get one from your console](https://console.studyfetch.com))
* Your preferred development environment set up:
  * **JavaScript**: Node.js 16+ installed
  * **Python**: Python 3.7+ installed
  * **Java**: Java 8+ and Maven/Gradle
  * **C#**: .NET 6.0+ installed

<Note>
  **Material Processing Time**: When you upload or create materials, they need time to process before they can be used in components. Attempting to create a component immediately after uploading materials will fail. Always check that materials have `status: 'active'` before using them. The examples below include proper waiting logic.
</Note>

## Language-Specific Quickstart

<Tabs>
  <Tab title="JavaScript">
    ### Install the SDK

    ```bash theme={null}
    npm install @studyfetch/sdk
    ```

    ### Initialize the Client

    ```javascript theme={null}
    import StudyfetchSDK from '@studyfetch/sdk';
    import fs from 'fs';
    import path from 'path';

    const client = new StudyfetchSDK({
      apiKey: process.env.STUDYFETCH_API_KEY,
      baseURL: 'https://studyfetchapi.com',
    });
    ```

    ### Step 1: Create or Upload Study Materials

    ```javascript theme={null}
    // Option 1: Create a text-based material
    const textMaterial = await client.v1.materials.create({
      content: {
        type: 'text',
        text: 'Chapter 1: Introduction to Biology\n\nBiology is the study of life...'
      },
      name: 'Biology Chapter 1 - Introduction',
      folderId: 'optional-folder-id', // Optional: organize in folders
      references: [
        {
          title: 'Biology Textbook Chapter 1',
          url: 'https://example.com/biology-ch1'
        }
      ] // Optional: source references
    });

    // Option 2: Upload a PDF file
    const fileBuffer = await fs.promises.readFile(
      path.join(process.cwd(), 'biology-textbook.pdf'),
    );
    const file = new File([fileBuffer], 'biology-textbook.pdf', {
      type: 'application/pdf',
    });

    const uploadedMaterial = await client.v1.materials.upload.uploadFile({
      file,
      name: 'Biology Textbook',
      folderId: 'optional-folder-id' // Optional: organize in folders
    });

    // Option 3: Upload material from a URL
    const urlMaterial = await client.v1.materials.upload.uploadFromURL({
      url: 'https://example.com/biology-notes.pdf',
      name: 'Online Biology Notes',
      folderId: 'optional-folder-id' // Optional: organize in folders
    });

    console.log('Materials created:', {
      text: textMaterial._id,
      uploaded: uploadedMaterial._id,
      url: urlMaterial._id
    });
    ```

    ### Step 2: Create a Chat Component

    <Warning>
      **Important**: Materials need time to process after upload. If you create a material and immediately try to use it in a component, the component creation will fail. Always ensure materials have `status: 'active'` before using them. For production applications, implement a polling mechanism to check material status.
    </Warning>

    ```javascript theme={null}
    // Wait for materials to finish processing
    // In production, implement proper polling with exponential backoff
    let materialStatus = 'processing';
    while (materialStatus !== 'active') {
      const material = await client.v1.materials.retrieve(textMaterial._id);
      materialStatus = material.status;
      if (materialStatus === 'error') {
        throw new Error('Material processing failed');
      }
      if (materialStatus === 'processing') {
        await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
      }
    }

    const chatComponent = await client.v1.components.create({
      name: 'Biology Study Assistant',
      type: 'chat',
      config: {
        model: 'gpt-4o-mini-2024-07-18',
        materials: [textMaterial._id, uploadedMaterial._id], // Use any material IDs
        temperature: 0.7,
        enableWebSearch: true
      }
    });

    console.log('Chat component created:', chatComponent._id);
    ```

    ### Step 3: Embed the Chat Component

    ```javascript theme={null}
    // Basic embed with minimal configuration
    const basicEmbed = await client.v1.components.generateEmbed(chatComponent._id, {
      userId: 'student-123'
    });

    // Advanced embed with all available options
    const advancedEmbed = await client.v1.components.generateEmbed(chatComponent._id, {
      // User tracking (optional)
      userId: 'student-123',
      studentName: 'John Doe',              // Student name for display
      groupIds: ['class-101', 'biology-spring-2024'],
      
      // Display dimensions
      width: '100%',
      height: '600px',
      
      // Chat-specific features
      features: {
        enableWebSearch: true,        // Allow users to search the web
        enableHistory: true,          // View and continue previous conversations
        enableVoice: true,           // Voice input with microphone
        enableFollowUps: true,       // AI-suggested follow-up questions
        enableComponentCreation: true, // AI can create flashcards, tests, etc.
        placeholderText: 'Ask your Biology tutor anything...',
        enableBadWordsFilter: true
      }
    });

    console.log('Basic Embed URL:', basicEmbed.embedUrl);
    console.log('Advanced Embed URL:', advancedEmbed.embedUrl);

    // Note: Theme and branding are configured at the organization level
    // StudyFetch branding is automatically hidden for all embeds
    ```

    ### Complete Example

    ```javascript theme={null}
    import StudyfetchSDK from '@studyfetch/sdk';
    import fs from 'fs';

    async function createStudyAssistant() {
      const client = new StudyfetchSDK({
        apiKey: process.env.STUDYFETCH_API_KEY,
        baseURL: 'https://studyfetchapi.com',
      });

      // 1. Create or upload materials
      const materials = [];
      
      // Create text material
      const textMaterial = await client.v1.materials.create({
        content: {
          type: 'text',
          text: 'Course introduction and key concepts...'
        },
        name: 'Course Introduction',
        references: [
          {
            title: 'Course Syllabus',
            url: 'https://example.com/syllabus'
          }
        ] // Optional: source references
      });
      materials.push(textMaterial._id);
      
      // Upload PDF file
      const fileBuffer = await fs.promises.readFile(
        path.join(process.cwd(), 'course-content.pdf'),
      );
      const file = new File([fileBuffer], 'course-content.pdf', {
        type: 'application/pdf',
      });
      
      const uploadedMaterial = await client.v1.materials.upload.uploadFile({
        file,
        name: 'Course Materials',
      });
      materials.push(uploadedMaterial._id);

      // IMPORTANT: Wait for materials to finish processing
      // Materials need time to process. Using them immediately will cause component creation to fail.
      for (const materialId of materials) {
        let materialStatus = 'processing';
        while (materialStatus !== 'active') {
          const material = await client.v1.materials.retrieve(materialId);
          materialStatus = material.status;
          if (materialStatus === 'error') {
            throw new Error(`Material ${materialId} processing failed`);
          }
          if (materialStatus === 'processing') {
            await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
          }
        }
      }

      // 2. Create chat assistant
      const chatComponent = await client.v1.components.create({
        name: 'Course Assistant',
        type: 'chat',
        config: {
          model: 'gpt-4o-mini-2024-07-18',
          materials: materials,
          temperature: 0.7,
          enableWebSearch: true
        }
      });

      // 3. Generate embed URL
      const embed = await client.v1.components.generateEmbed(chatComponent._id, {
        userId: 'student-123',
        studentName: 'John Doe',    // Student name for display
        groupIds: ['course-101'],
        width: '100%',
        height: '600px',
        features: {
          enableWebSearch: true,
          enableHistory: true,
          enableVoice: true,
          enableFollowUps: true,
          enableComponentCreation: true,
          placeholderText: 'Ask me anything about the course materials...',
          enableBadWordsFilter: true
        }
      });

      console.log('Study assistant created!');
      console.log('Embed URL:', embed.embedUrl);
      console.log('Component ID:', chatComponent._id);
      
      return { chatComponent, embed };
    }

    createStudyAssistant();
    ```
  </Tab>

  <Tab title="Python">
    ### Install the SDK

    ```bash theme={null}
    pip install studyfetch-sdk
    ```

    ### Initialize the Client

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

    client = StudyfetchSDK(
        api_key=os.environ.get("STUDYFETCH_API_KEY"),
        base_url="https://studyfetchapi.com",
    )
    ```

    ### Step 1: Create or Upload Study Materials

    ```python theme={null}
    # Option 1: Create a text-based material
    text_material = client.v1.materials.create(
        content={
            "type": "text",
            "text": "Chapter 1: Introduction to Biology\n\nBiology is the study of life..."
        },
        name="Biology Chapter 1 - Introduction",
        folderId="optional-folder-id",  # Optional: organize in folders
        references=[
            {
                "title": "Biology Textbook Chapter 1",
                "url": "https://example.com/biology-ch1"
            }
        ]  # Optional: source references
    )

    # Option 2: Upload a PDF file
    with open('biology-textbook.pdf', 'rb') as f:
        uploaded_material = client.v1.materials.upload.upload_file(
            file=f.read(),
            name="Biology Textbook",
            folderId="optional-folder-id"  # Optional: organize in folders
        )

    # Option 3: Upload material from a URL
    url_material = client.v1.materials.upload.upload_from_url(
        url="https://example.com/biology-notes.pdf",
        name="Online Biology Notes",
        folderId="optional-folder-id"  # Optional: organize in folders
    )

    print("Materials created:", {
        "text": text_material._id,
        "uploaded": uploaded_material._id,
        "url": url_material._id
    })
    ```

    ### Step 2: Create a Chat Component

    <Warning>
      **Important**: Materials need time to process after upload. If you create a material and immediately try to use it in a component, the component creation will fail. Always ensure materials have `status: 'active'` before using them. For production applications, implement a polling mechanism to check material status.
    </Warning>

    ```python theme={null}
    import time

    # Wait for materials to finish processing
    # In production, implement proper polling with exponential backoff
    material_status = "processing"
    while material_status != "active":
        material = client.v1.materials.retrieve(text_material._id)
        material_status = material.status
        if material_status == "error":
            raise Exception("Material processing failed")
        if material_status == "processing":
            time.sleep(2)  # Wait 2 seconds

    chat_component = client.v1.components.create(
        name="Biology Study Assistant",
        type="chat",
        config={
            "model": "gpt-4o-mini-2024-07-18",
            "materials": [text_material._id, uploaded_material._id],  # Use any material IDs
            "temperature": 0.7,
            "enableWebSearch": True
        }
    )

    print(f"Chat component created: {chat_component._id}")
    ```

    ### Step 3: Embed the Chat Component

    ```python theme={null}
    # Basic embed with minimal configuration
    basic_embed = client.v1.components.generateEmbed(
        component_id=chat_component._id,
        userId="student-123"
    )

    # Advanced embed with all available options
    advanced_embed = client.v1.components.generateEmbed(
        component_id=chat_component._id,
        # User tracking (optional)
        userId="student-123",
        student_name="John Doe",              # Student name for display
        groupIds=["class-101", "biology-spring-2024"],
        
        # Display dimensions
        width="100%",
        height="600px",
        
        # Chat-specific features
        features={
            "enableWebSearch": True,        # Allow users to search the web
            "enableHistory": True,          # View and continue previous conversations
            "enableVoice": True,           # Voice input with microphone
            "enableFollowUps": True,       # AI-suggested follow-up questions
            "enableComponentCreation": True, # AI can create flashcards, tests, etc.
            "placeholderText": "Ask your Biology tutor anything..."
        }
    )

    print(f"Basic Embed URL: {basic_embed.embedUrl}")
    print(f"Advanced Embed URL: {advanced_embed.embedUrl}")

    # Note: Theme and branding are configured at the organization level
    # StudyFetch branding is automatically hidden for all embeds
    ```

    ### Complete Example

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

    def create_study_assistant():
        client = StudyfetchSDK(
            api_key=os.environ.get("STUDYFETCH_API_KEY"),
            base_url="https://studyfetchapi.com",
        )

        # 1. Create or upload materials
        materials = []
        
        # Create text material
        text_material = client.v1.materials.create(
            content={
                "type": "text",
                "text": "Course introduction and key concepts..."
            },
            name="Course Introduction",
            references=[
                {
                    "title": "Course Syllabus",
                    "url": "https://example.com/syllabus"
                }
            ]  # Optional: source references
        )
        materials.append(text_material._id)
        
        # Upload PDF file
        with open('course-content.pdf', 'rb') as f:
            uploaded_material = client.v1.materials.upload.upload_file(
                file=f.read(),
                name="Course Materials"
            )
        materials.append(uploaded_material._id)

        # IMPORTANT: Wait for materials to finish processing
        # Materials need time to process. Using them immediately will cause component creation to fail.
        import time
        for material_id in materials:
            material_status = "processing"
            while material_status != "active":
                material = client.v1.materials.retrieve(material_id)
                material_status = material.status
                if material_status == "error":
                    raise Exception(f"Material {material_id} processing failed")
                if material_status == "processing":
                    time.sleep(2)  # Wait 2 seconds

        # 2. Create chat assistant
        chat_component = client.v1.components.create(
            name="Course Assistant",
            type="chat",
            config={
                "model": "gpt-4o-mini-2024-07-18",
                "materials": materials,
                "temperature": 0.7,
                "enableWebSearch": True
            }
        )

        # 3. Generate embed URL
        embed = client.v1.components.generateEmbed(
            component_id=chat_component._id,
            userId="student-123",
            student_name="John Doe",    # Student name for display
            groupIds=["course-101"],
            width="100%",
            height="600px",
            features={
                "enableWebSearch": True,
                "enableHistory": True,
                "enableVoice": True,
                "enableFollowUps": True,
                "enableComponentCreation": True,
                "placeholderText": "Ask me anything about the course materials..."
            }
        )

        print("Study assistant created!")
        print(f"Embed URL: {embed.embedUrl}")
        print(f"Component ID: {chat_component._id}")
        
        return chat_component, embed

    create_study_assistant()
    ```
  </Tab>

  <Tab title="Java">
    ### Install the SDK

    Maven:

    ```xml theme={null}
    <dependency>
      <groupId>com.studyfetch.javasdk</groupId>
      <artifactId>studyfetch-sdk</artifactId>
      <version>0.1.0-alpha.33</version>
    </dependency>
    ```

    Gradle:

    ```gradle theme={null}
    implementation group: 'com.studyfetch.javasdk', name: 'studyfetch-sdk', version: '0.1.0-alpha.33'
    ```

    ### Initialize the Client

    ```java theme={null}
    import com.studyfetch.javasdk.client.StudyfetchSdkClient;
    import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;

    StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
        .apiKey(System.getenv("STUDYFETCH_API_KEY"))
        .baseUrl("https://studyfetchapi.com")
        .build();
    ```

    ### Step 1: Create or Upload Study Materials

    ```java theme={null}
    import com.studyfetch.javasdk.models.v1.materials.MaterialResponse;
    import com.studyfetch.javasdk.models.v1.materials.MaterialCreateParams;
    import com.studyfetch.javasdk.models.v1.materials.Content;
    import com.studyfetch.javasdk.models.v1.materials.Reference;
    import com.studyfetch.javasdk.models.v1.materials.upload.UploadUploadFileParams;
    import com.studyfetch.javasdk.models.v1.materials.upload.UploadUploadFromUrlParams;
    import java.io.FileInputStream;
    import java.util.List;

    // Option 1: Create a text-based material
    MaterialCreateParams createParams = MaterialCreateParams.builder()
        .content(Content.builder()
            .type(Content.Type.TEXT)
            .text("Chapter 1: Introduction to Biology\n\nBiology is the study of life...")
            .build())
        .name("Biology Chapter 1 - Introduction")
        .folderId("optional-folder-id") // Optional: organize in folders
        .references(List.of(
            Reference.builder()
                .title("Biology Textbook Chapter 1")
                .url("https://example.com/biology-ch1")
                .build()
        )) // Optional: source references
        .build();
    MaterialResponse textMaterial = client.v1().materials().create(createParams);

    // Option 2: Upload a PDF file
    FileInputStream fileStream = new FileInputStream("biology-textbook.pdf");
    UploadUploadFileParams uploadParams = UploadUploadFileParams.builder()
        .file(fileStream)
        .name("Biology Textbook")
        .folderId("optional-folder-id") // Optional: organize in folders
        .build();
    MaterialResponse uploadedMaterial = client.v1().materials().upload().uploadFile(uploadParams);

    // Option 3: Upload material from a URL
    UploadUploadFromUrlParams urlParams = UploadUploadFromUrlParams.builder()
        .url("https://example.com/biology-notes.pdf")
        .name("Online Biology Notes")
        .folderId("optional-folder-id") // Optional: organize in folders
        .build();
    MaterialResponse urlMaterial = client.v1().materials().upload().uploadFromUrl(urlParams);

    System.out.println("Materials created:");
    System.out.println("Text: " + textMaterial._id());
    System.out.println("Uploaded: " + uploadedMaterial._id());
    System.out.println("URL: " + urlMaterial._id());
    ```

    ### Step 2: Create a Chat Component

    ```java theme={null}
    import com.studyfetch.javasdk.models.v1.components.ComponentResponse;
    import com.studyfetch.javasdk.models.v1.components.ComponentCreateParams;

    ComponentCreateParams chatParams = ComponentCreateParams.builder()
        .name("Biology Study Assistant")
        .type(ComponentCreateParams.Type.CHAT)
        .config(ComponentCreateParams.Config.ChatConfigDto.builder()
            .model("gpt-4o-mini-2024-07-18")
            .materials(List.of(textMaterial._id(), uploadedMaterial._id())) // Use any material IDs
            .temperature(0.7)
            .enableWebSearch(true)
            .build())
        .build();
        
    ComponentResponse chatComponent = client.v1().components().create(chatParams);
    System.out.println("Chat component created: " + chatComponent._id());
    ```

    ### Step 3: Embed the Chat Component

    ```java theme={null}
    import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
    import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;

    // Basic embed with minimal configuration
    ComponentGenerateEmbedParams basicEmbedParams = ComponentGenerateEmbedParams.builder()
        .id(chatComponent._id())
        .userId("student-123")
        .build();
        
    ComponentGenerateEmbedResponse basicEmbed = client.v1().components()
        .generateEmbed(basicEmbedParams);

    // Advanced embed with all available options
    ComponentGenerateEmbedParams advancedEmbedParams = ComponentGenerateEmbedParams.builder()
        .id(chatComponent._id())
        // User tracking (optional)
        .userId("student-123")
        .studentName("John Doe")              // Student name for display
        .groupIds(List.of("class-101", "biology-spring-2024"))
        
        // Display dimensions
        .width("100%")
        .height("600px")
        
        // Chat-specific features
        .features(ComponentGenerateEmbedParams.Features.builder()
            .enableWebSearch(true)        // Allow users to search the web
            .enableHistory(true)          // View and continue previous conversations
            .enableVoice(true)           // Voice input with microphone
            .enableFollowUps(true)       // AI-suggested follow-up questions
            .enableComponentCreation(true) // AI can create flashcards, tests, etc.
            .placeholderText("Ask your Biology tutor anything...")
            .build())
        .build();
        
    ComponentGenerateEmbedResponse advancedEmbed = client.v1().components()
        .generateEmbed(advancedEmbedParams);
        
    System.out.println("Basic Embed URL: " + basicEmbed.embedUrl());
    System.out.println("Advanced Embed URL: " + advancedEmbed.embedUrl());

    // Note: Theme and branding are configured at the organization level
    // StudyFetch branding is automatically hidden for all embeds
    ```

    ### Complete Example

    ```java theme={null}
    package com.example;

    import com.studyfetch.javasdk.client.StudyfetchSdkClient;
    import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
    import com.studyfetch.javasdk.models.v1.materials.MaterialResponse;
    import com.studyfetch.javasdk.models.v1.materials.MaterialCreateParams;
    import com.studyfetch.javasdk.models.v1.materials.MaterialRetrieveParams;
    import com.studyfetch.javasdk.models.v1.materials.Content;
    import com.studyfetch.javasdk.models.v1.materials.Reference;
    import com.studyfetch.javasdk.models.v1.materials.upload.UploadUploadFileParams;
    import com.studyfetch.javasdk.models.v1.components.ComponentResponse;
    import com.studyfetch.javasdk.models.v1.components.ComponentCreateParams;
    import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
    import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;
    import java.io.FileInputStream;
    import java.util.List;
    import java.util.ArrayList;

    public class StudyAssistant {
        public static void main(String[] args) throws Exception {
                    StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
            .apiKey(System.getenv("STUDYFETCH_API_KEY"))
            .baseUrl("https://studyfetchapi.com")
            .build();

            // 1. Create or upload materials
            List<String> materials = new ArrayList<>();
            
            // Create text material
            MaterialCreateParams createParams = MaterialCreateParams.builder()
                .content(Content.builder()
                    .type(Content.Type.TEXT)
                    .text("Course introduction and key concepts...")
                    .build())
                .name("Course Introduction")
                .references(List.of(
                    Reference.builder()
                        .title("Course Syllabus")
                        .url("https://example.com/syllabus")
                        .build()
                )) // Optional: source references
                .build();
            MaterialResponse textMaterial = client.v1().materials().create(createParams);
            materials.add(textMaterial._id());
            
            // Upload PDF file
            FileInputStream fileStream = new FileInputStream("course-content.pdf");
            UploadUploadFileParams uploadParams = UploadUploadFileParams.builder()
                .file(fileStream)
                .name("Course Materials")
                .build();
            MaterialResponse uploadedMaterial = client.v1().materials().upload().uploadFile(uploadParams);
            materials.add(uploadedMaterial._id());

            // IMPORTANT: Wait for materials to finish processing
            // Materials need time to process. Using them immediately will cause component creation to fail.
            for (String materialId : materials) {
                MaterialResponse.Status status = MaterialResponse.Status.PROCESSING;
                while (status.equals(MaterialResponse.Status.PROCESSING)) {
                    Thread.sleep(2000); // Wait 2 seconds
                    MaterialResponse material = client.v1().materials().retrieve(
                        MaterialRetrieveParams.builder()
                            .id(materialId)
                            .build()
                    );
                    status = material.status();
                    if (status.equals(MaterialResponse.Status.ERROR)) {
                        throw new Exception("Material processing failed");
                    }
                }
            }

            // 2. Create chat assistant
            ComponentCreateParams chatParams = ComponentCreateParams.builder()
                .name("Course Assistant")
                .type(ComponentCreateParams.Type.CHAT)
                .config(ComponentCreateParams.Config.ChatConfigDto.builder()
                    .model("gpt-4o-mini-2024-07-18")
                    .materials(materials)
                    .temperature(0.7)
                    .enableWebSearch(true)
                    .build())
                .build();
            ComponentResponse chatComponent = client.v1().components().create(chatParams);

            // 3. Generate embed URL
            ComponentGenerateEmbedParams embedParams = ComponentGenerateEmbedParams.builder()
                .id(chatComponent._id())
                .userId("student-123")
                .studentName("John Doe")    // Student name for display
                .groupIds(List.of("course-101"))
                .width("100%")
                .height("600px")
                .features(ComponentGenerateEmbedParams.Features.builder()
                    .enableWebSearch(true)
                    .enableHistory(true)
                    .enableVoice(true)
                    .enableFollowUps(true)
                    .enableComponentCreation(true)
                    .placeholderText("Ask me anything about the course materials...")
                    .build())
                .build();
            ComponentGenerateEmbedResponse embed = client.v1().components()
                .generateEmbed(embedParams);

            System.out.println("Study assistant created!");
            System.out.println("Embed URL: " + embed.embedUrl());
            System.out.println("Component ID: " + chatComponent._id());
        }
    }
    ```
  </Tab>

  <Tab title="C#">
    ### Install the SDK

    ```bash theme={null}
    dotnet add package StudyfetchSDK --version 0.8.1
    ```

    ### Initialize the Client

    ```csharp theme={null}
    using StudyfetchSDK;
    using StudyfetchSDK.Models.V1.Materials;
    using StudyfetchSDK.Models.V1.Materials.Upload;
    using StudyfetchSDK.Models.V1.Components;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Threading.Tasks;

    var client = new StudyfetchSDKClient()
    {
        APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
        BaseUrl = new Uri("https://studyfetchapi.com")
    };
    ```

    ### Step 1: Create or Upload Study Materials

    ```csharp theme={null}
    // Option 1: Create a text-based material
    var textMaterial = await client.V1.Materials.Create(new()
    {
        Content = new()
        {
            Type = StudyfetchSDK.Models.V1.Materials.ContentProperties.Type.Text,
            Text = "Chapter 1: Introduction to Biology\n\nBiology is the study of life..."
        },
        Name = "Biology Chapter 1 - Introduction",
        FolderID = "optional-folder-id", // Optional: organize in folders
        References = new List<StudyfetchSDK.Models.V1.Materials.Reference>
        {
            new("Biology Textbook Chapter 1")
            {
                URL = "https://example.com/biology-ch1"
            }
        } // Optional: source references
    });

    // Option 2: Upload a PDF file
    var fileBytes = await File.ReadAllBytesAsync("biology-textbook.pdf");
    var uploadedMaterial = await client.V1.Materials.Upload.UploadFile(new()
    {
        File = fileBytes,
        FileName = "biology-textbook.pdf",
        Name = "Biology Textbook",
        FolderID = "optional-folder-id" // Optional: organize in folders
    });

    // Option 3: Upload material from a URL
    var urlMaterial = await client.V1.Materials.Upload.UploadFromURL(new()
    {
        URL = "https://example.com/biology-notes.pdf",
        Name = "Online Biology Notes",
        FolderID = "optional-folder-id" // Optional: organize in folders
    });

    Console.WriteLine("Materials created:");
    Console.WriteLine($"Text: {textMaterial._ID}");
    Console.WriteLine($"Uploaded: {uploadedMaterial._ID}");
    Console.WriteLine($"URL: {urlMaterial._ID}");
    ```

    ### Step 2: Create a Chat Component

    ```csharp theme={null}
    // Wait for materials to finish processing
    // In production, implement proper polling with exponential backoff
    var materialStatus = "processing";
    while (materialStatus != "active")
    {
        var material = await client.V1.Materials.Retrieve(new()
        {
            ID = textMaterial._ID
        });
        materialStatus = material.Status.Raw();
        if (materialStatus == "error")
            throw new Exception("Material processing failed");
        if (materialStatus == "processing")
            await Task.Delay(2000); // Wait 2 seconds
    }

    var chatComponent = await client.V1.Components.Create(new()
    {
        Name = "Biology Study Assistant",
        Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.Chat,
        Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDto()
        {
            Model = "gpt-4o-mini-2024-07-18",
            Materials = new List<string> { textMaterial._ID, uploadedMaterial._ID }, // Use any material IDs
            Temperature = 0.7,
            EnableWebSearch = true
        }
    });

    Console.WriteLine($"Chat component created: {chatComponent._ID}");
    ```

    ### Step 3: Embed the Chat Component

    ```csharp theme={null}
    // Basic embed with minimal configuration
    var basicEmbed = await client.V1.Components.GenerateEmbed(new()
    {
        ID = chatComponent._ID,
        UserID = "student-123"
    });

    // Advanced embed with all available options
    var advancedEmbed = await client.V1.Components.GenerateEmbed(new()
    {
        ID = chatComponent._ID,
        // User tracking (optional)
        UserID = "student-123",
        StudentName = "John Doe",              // Student name for display
        GroupIDs = new List<string> { "class-101", "biology-spring-2024" },
        
        // Display dimensions
        Width = "100%",
        Height = "600px",
        
        // Chat-specific features
        Features = new StudyfetchSDK.Models.V1.Components.ComponentGenerateEmbedParamsProperties.Features(enableBadWordsFilter: true)
        {
            EnableWebSearch = true,        // Allow users to search the web
            EnableHistory = true,          // View and continue previous conversations
            EnableVoice = true,           // Voice input with microphone
            EnableFollowUps = true,       // AI-suggested follow-up questions
            EnableComponentCreation = true, // AI can create flashcards, tests, etc.
            PlaceholderText = "Ask your Biology tutor anything..."
        }
    });

    Console.WriteLine($"Basic Embed URL: {basicEmbed.EmbedURL}");
    Console.WriteLine($"Advanced Embed URL: {advancedEmbed.EmbedURL}");

    // Note: Theme and branding are configured at the organization level
    // StudyFetch branding is automatically hidden for all embeds
    ```

    ### Complete Example

    ```csharp theme={null}
    using StudyfetchSDK;
    using StudyfetchSDK.Models.V1.Materials;
    using StudyfetchSDK.Models.V1.Materials.Upload;
    using StudyfetchSDK.Models.V1.Components;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Threading.Tasks;

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

            // 1. Create or upload materials
            var materials = new List<string>();
            
            // Create text material
            var textMaterial = await client.V1.Materials.Create(new()
            {
                Content = new()
                {
                    Type = StudyfetchSDK.Models.V1.Materials.ContentProperties.Type.Text,
                    Text = "Course introduction and key concepts..."
                },
                Name = "Course Introduction",
                References = new List<StudyfetchSDK.Models.V1.Materials.Reference>
                {
                    new("Course Syllabus")
                    {
                        URL = "https://example.com/syllabus"
                    }
                } // Optional: source references
            });
            materials.Add(textMaterial._ID);
            
            // Upload PDF file
            var fileBytes = await File.ReadAllBytesAsync("course-content.pdf");
            var uploadedMaterial = await client.V1.Materials.Upload.UploadFile(new()
            {
                File = fileBytes,
                FileName = "course-content.pdf",
                Name = "Course Materials"
            });
            materials.Add(uploadedMaterial._ID);

            // IMPORTANT: Wait for materials to finish processing
            // Materials need time to process. Using them immediately will cause component creation to fail.
            foreach (var materialId in materials)
            {
                var materialStatus = "processing";
                while (materialStatus != "active")
                {
                    var material = await client.V1.Materials.Retrieve(new()
                    {
                        ID = materialId
                    });
                    materialStatus = material.Status.Raw();
                    if (materialStatus == "error")
                        throw new Exception($"Material {materialId} processing failed");
                    if (materialStatus == "processing")
                        await Task.Delay(2000); // Wait 2 seconds
                }
            }

            // 2. Create chat assistant
            var chatComponent = await client.V1.Components.Create(new()
            {
                Name = "Course Assistant",
                Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.Chat,
                Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDto()
                {
                    Model = "gpt-4o-mini-2024-07-18",
                    Materials = materials,
                    Temperature = 0.7,
                    EnableWebSearch = true
                }
            });

            // 3. Generate embed URL
            var embed = await client.V1.Components.GenerateEmbed(new()
            {
            ID = chatComponent._ID,
            UserID = "student-123",
            StudentName = "John Doe",    // Student name for display
            GroupIDs = new List<string> { "course-101" },
            Width = "100%",
            Height = "600px",
            Features = new StudyfetchSDK.Models.V1.Components.ComponentGenerateEmbedParamsProperties.Features(enableBadWordsFilter: true)
            {
                EnableWebSearch = true,
                EnableHistory = true,
                EnableVoice = true,
                EnableFollowUps = true,
                EnableComponentCreation = true,
                PlaceholderText = "Ask me anything about the course materials..."
            }
            });

            Console.WriteLine("Study assistant created!");
            Console.WriteLine($"Embed URL: {embed.EmbedURL}");
            Console.WriteLine($"Component ID: {chatComponent._ID}");
        }
    }
    ```
  </Tab>
</Tabs>

## Embedding Components

After creating components, embed them in your application:

```html theme={null}
<iframe
  src="YOUR_EMBED_URL"
  width="100%"
  height="600px"
  frameborder="0"
  allow="microphone"
></iframe>
```

## What's Next?

Now that you've created your first components, explore more features:

### Learn More About Components

* [Chat Components](/api-docs/components/chat) - Build conversational AI tutors
* [Flashcards](/api-docs/components/flashcards) - Create adaptive study cards
* [Practice Tests](/api-docs/components/practice-test) - Generate assessments
* [Audio Recaps](/api-docs/components/audio-recap) - Convert materials to audio
* [Scenarios](/api-docs/components/scenarios) - Design immersive learning experiences
* [Explainers](/api-docs/components/explainers) - Create animated video explanations
* [Uploads](/api-docs/components/uploads) - Manage and organize materials

### Advanced Features

* [Embedding Components](/api-docs/components/chat) - Integrate into your app
* Analytics API - Track usage and performance (see REST API tab)

### Resources

* REST API Reference - Complete API documentation (see REST API tab)

## Need Help?

* 📧 Email: [support@studyfetch.com](mailto:support@studyfetch.com)
* 💬 Discord: [Join our community](https://discord.gg/studyfetch)
