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

# Uploading Files

> Learn how to upload different types of study materials

## Overview

StudyFetch supports multiple methods for uploading materials:

* **Direct file upload** - Upload files directly in the request
* **Upload and process** - Upload files and wait for processing to complete
* **URL import** - Import content from web URLs
* **Presigned URL upload** - Upload large files directly to S3
* **Create and process** - Create text materials and wait for processing to complete

<Note>
  **Processing Time**: After uploading, materials require processing time before they can be used. Materials will have `status: 'processing'` initially and must reach `status: 'active'` before they can be used in components or for grading. Processing time varies based on file size and type (typically 5-30 seconds for PDFs, longer for videos).

  Use the `uploadFileAndProcess` or `createAndProcess` methods if you need to use the material immediately after creation - they wait for processing to complete before returning.
</Note>

## Direct File Upload

Upload files directly to the API. Best for files under 10MB.

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

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

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

  const material = await client.v1.materials.upload.uploadFile({
    file,
    name: 'Biology Chapter 1 Notes',
    folderId: 'folder_123' // Optional
  });

  console.log('Material uploaded:', material._id);
  console.log('Status:', material.status); // 'processing'
  ```

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

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

  # Upload a file
  with open('biology-notes.pdf', 'rb') as file:
      material = client.v1.materials.upload.upload_file({
          'file': file,
          'name': "Biology Chapter 1 Notes",
          'folderId': "folder_123"  # Optional
      })

  print(f"Material uploaded: {material._id}")
  print(f"Status: {material.status}")  # 'processing'
  ```

  ```java Java theme={null}
  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.upload.UploadUploadFileParams;
  import java.io.FileInputStream;

  public class UploadMaterial {
      public static void main(String[] args) throws Exception {
          StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
              .fromEnv()
              .baseUrl("https://studyfetchapi.com")
              .build();
          
          FileInputStream fileStream = new FileInputStream("biology-notes.pdf");
          
          UploadUploadFileParams params = UploadUploadFileParams.builder()
              .file(fileStream)
              .name("Biology Chapter 1 Notes")
              .folderId("folder_123")  // Optional
              .build();
          
          MaterialResponse material = client.v1().materials().upload().uploadFile(params);
          
          System.out.println("Material uploaded: " + material._id());
          System.out.println("Status: " + material.status()); // 'processing'
      }
  }
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Materials;
  using System;
  using System.IO;
  using System.Threading.Tasks;

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

          var fileBytes = await File.ReadAllBytesAsync("biology-notes.pdf");
          
          var material = await client.V1.Materials.Upload.UploadFile(new()
          {
              File = fileBytes,
              FileName = "biology-notes.pdf",
              Name = "Biology Chapter 1 Notes",
              FolderID = "folder_123" // Optional
          });

          Console.WriteLine($"Material uploaded: {material._ID}");
          Console.WriteLine($"Status: {material.Status}"); // 'processing'
      }
  }
  ```
</CodeGroup>

## Upload and Process File

Upload a file and wait for processing to complete before returning. This is useful when you need to use the material immediately after upload.

<Note>
  **Synchronous Processing**: Unlike the regular `uploadFile` method which returns immediately while processing happens in the background, `uploadFileAndProcess` waits until the material is fully processed and ready to use before returning.
</Note>

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

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

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

  // Upload and wait for processing to complete
  const material = await client.v1.materials.upload.uploadFileAndProcess({
    file,
    name: 'Biology Chapter 1 Notes',
    folderId: 'folder_123' // Optional
  });

  // Material is ready to use immediately
  console.log('Material uploaded and processed:', material._id);
  console.log('Status:', material.status); // 'active'
  ```

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

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

  # Upload and wait for processing to complete
  with open('biology-notes.pdf', 'rb') as file:
      material = client.v1.materials.upload.upload_file_and_process({
          'file': file,
          'name': "Biology Chapter 1 Notes",
          'folderId': "folder_123"  # Optional
      })

  # Material is ready to use immediately
  print(f"Material uploaded and processed: {material._id}")
  print(f"Status: {material.status}")  # 'active'
  print(f"Word count: {material.metadata.word_count}")
  ```

  ```java Java theme={null}
  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.upload.UploadUploadFileAndProcessParams;
  import java.io.FileInputStream;

  public class UploadAndProcessMaterial {
      public static void main(String[] args) throws Exception {
          StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
              .fromEnv()
              .baseUrl("https://studyfetchapi.com")
              .build();
          
          FileInputStream fileStream = new FileInputStream("biology-notes.pdf");
          
          // Upload and wait for processing to complete
          UploadUploadFileAndProcessParams params = UploadUploadFileAndProcessParams.builder()
              .file(fileStream)
              .name("Biology Chapter 1 Notes")
              .folderId("folder_123")  // Optional
              .build();
          
          MaterialResponse material = client.v1().materials().upload().uploadFileAndProcess(params);
          
          // Material is ready to use immediately
          System.out.println("Material uploaded and processed: " + material._id());
          System.out.println("Status: " + material.status()); // ACTIVE
      }
  }
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Materials;
  using System;
  using System.IO;
  using System.Threading.Tasks;

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

          var fileBytes = await File.ReadAllBytesAsync("biology-notes.pdf");
          
          // Upload and wait for processing to complete
          var material = await client.V1.Materials.Upload.UploadFileAndProcess(new()
          {
              File = fileBytes,
              FileName = "biology-notes.pdf",
              Name = "Biology Chapter 1 Notes",
              FolderID = "folder_123" // Optional
          });

          // Material is ready to use immediately
          Console.WriteLine($"Material uploaded and processed: {material._ID}");
          Console.WriteLine($"Status: {material.Status}"); // 'active'
          Console.WriteLine($"Material name: {material.Name}");
      }
  }
  ```
</CodeGroup>

## Upload from URL

Import content directly from web URLs. Supports documents, videos, and web pages.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const material = await client.v1.materials.upload.uploadFromURL({
    url: 'https://example.com/biology-textbook.pdf',
    name: 'Biology Textbook',
    folderId: 'folder_123' // Optional
  });

  console.log('Material imported:', material._id);
  ```

  ```python Python theme={null}
  material = client.v1.materials.upload.upload_from_url({
      'url': "https://example.com/biology-textbook.pdf",
      'name': "Biology Textbook",
      'folderId': "folder_123"  # Optional
  })

  print(f"Material imported: {material._id}")
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.models.v1.materials.upload.UploadUploadFromUrlParams;
  import com.studyfetch.javasdk.models.v1.materials.MaterialResponse;

  UploadUploadFromUrlParams params = UploadUploadFromUrlParams.builder()
      .url("https://example.com/biology-textbook.pdf")
      .name("Biology Textbook")
      .folderId("folder_123")  // Optional
      .build();

  MaterialResponse material = client.v1().materials().upload().uploadFromUrl(params);

  System.out.println("Material imported: " + material._id());
  ```

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

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

          var material = await client.V1.Materials.Upload.UploadFromURL(new()
          {
              URL = "https://example.com/biology-textbook.pdf",
              Name = "Biology Textbook",
              FolderID = "folder_123" // Optional
          });

          Console.WriteLine($"Material imported: {material._ID}");
      }
  }
  ```
</CodeGroup>

## Upload Text Content

Create materials from plain text content without file upload.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const material = await client.v1.materials.create({
    name: 'Biology Notes',
    content: {
      type: 'text',
      text: 'Cell Structure: The cell is the basic unit of life...'
    },
    folderId: 'folder_123', // Optional
    references: [
      {
        title: 'Introduction to Biology Textbook',
        url: 'https://example.com/textbook'
      }
    ] // Optional: source references
  });

  console.log('Text material created:', material._id);
  ```

  ```python Python theme={null}
  material = client.v1.materials.create(
      name="Biology Notes",
      content={
          "type": "text",
          "text": "Cell Structure: The cell is the basic unit of life..."
      },
      folder_id="folder_123",  # Optional
      references=[
          {
              "title": "Introduction to Biology Textbook",
              "url": "https://example.com/textbook"
          }
      ]  # Optional: source references
  )

  print(f"Text material created: {material._id}")
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.models.v1.materials.MaterialCreateParams;
  import com.studyfetch.javasdk.models.v1.materials.MaterialResponse;
  import com.studyfetch.javasdk.models.v1.materials.Content;
  import com.studyfetch.javasdk.models.v1.materials.Reference;
  import java.util.List;

  MaterialCreateParams params = MaterialCreateParams.builder()
      .name("Biology Notes")
      .content(Content.builder()
          .type(Content.Type.TEXT)
          .text("Cell Structure: The cell is the basic unit of life...")
          .build())
      .folderId("folder_123")  // Optional
      .references(List.of(
          Reference.builder()
              .title("Introduction to Biology Textbook")
              .url("https://example.com/textbook")
              .build()
      )) // Optional: source references
      .build();

  MaterialResponse material = client.v1().materials().create(params);

  System.out.println("Text material created: " + material._id());

  // Access references if any were added
  if (material.references().isPresent() && !material.references().get().isEmpty()) {
      System.out.println("References:");
      for (var reference : material.references().get()) {
          System.out.println("  - " + reference.title() + ": " + reference.url().orElse(""));
      }
  }
  ```

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

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

          var material = await client.V1.Materials.Create(new()
          {
              Name = "Biology Notes",
              Content = new()
              {
                  Type = StudyfetchSDK.Models.V1.Materials.ContentProperties.Type.Text,
                  Text = "Cell Structure: The cell is the basic unit of life..."
              },
              FolderID = "folder_123", // Optional
              References = new List<StudyfetchSDK.Models.V1.Materials.Reference>
              {
                  new("Introduction to Biology Textbook")
                  {
                      URL = "https://example.com/textbook"
                  }
              } // Optional: Add source references
          });

          Console.WriteLine($"Text material created: {material._ID}");
          
          // Access references if any were added
          if (material.References?.Count > 0)
          {
              Console.WriteLine("References:");
              foreach (var reference in material.References)
              {
                  Console.WriteLine($"  - {reference.Title}: {reference.URL}");
              }
          }
      }
  }
  ```
</CodeGroup>

## Create and Process Material

The `createAndProcess` method creates a material and waits for it to be fully processed before returning. This is useful when you need to use the material immediately after creation.

<Note>
  **Synchronous Processing**: Unlike the regular `create` method which returns immediately while processing happens in the background, `createAndProcess` waits until the material is fully processed and ready to use before returning.
</Note>

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

  const client = new StudyfetchSDK({
    apiKey: 'your-api-key',
  });

  // Create and wait for processing to complete
  const material = await client.v1.materials.createAndProcess({
    content: { 
      type: 'text',
      text: 'Chapter 1: Introduction to Biology...'
    },
    name: 'Chapter 1 - Introduction',
    references: [
      {
        title: 'Biology Course Materials',
        url: 'https://example.com/course-materials'
      }
    ] // Optional: source references
  });

  // Material is ready to use immediately
  console.log('Material ID:', material._id);
  console.log('Status:', material.status); // 'active'
  ```

  ```python Python theme={null}
  # Create and wait for processing to complete
  material = client.v1.materials.create_and_process({
      'content': {
          'type': 'text',
          'text': 'Chapter 1: Introduction to Biology...'
      },
      'name': 'Chapter 1 - Introduction',
      'references': [
          {
              'title': 'Biology Course Materials',
              'url': 'https://example.com/course-materials'
          }
      ]  # Optional: source references
  })

  # Material is ready to use immediately
  print(f"Material ID: {material._id}")
  print(f"Status: {material.status}")  # 'active'
  print(f"Word count: {material.metadata.word_count}")
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.StudyfetchSdkClient;
  import com.studyfetch.javasdk.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.materials.MaterialCreateAndProcessParams;
  import com.studyfetch.javasdk.models.v1.materials.MaterialResponse;
  import com.studyfetch.javasdk.models.v1.materials.Content;
  import com.studyfetch.javasdk.models.v1.materials.Reference;
  import java.util.List;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .apiKey("your-api-key")
      .baseUrl("https://studyfetchapi.com")
      .build();

  // Create and wait for processing to complete
  MaterialCreateAndProcessParams params = MaterialCreateAndProcessParams.builder()
      .content(Content.builder()
          .type(Content.Type.TEXT)
          .text("Chapter 1: Introduction to Biology...")
          .build())
      .name("Chapter 1 - Introduction")
      .references(List.of(
          Reference.builder()
              .title("Biology Course Materials")
              .url("https://example.com/course-materials")
              .build()
      )) // Optional: source references
      .build();

  MaterialResponse material = client.v1().materials().createAndProcess(params);

  // Material is ready to use immediately
  System.out.println("Material ID: " + material._id());
  System.out.println("Status: " + material.status()); // ACTIVE

  // Access references if any were added
  if (material.references().isPresent() && !material.references().get().isEmpty()) {
      System.out.println("References:");
      for (var reference : material.references().get()) {
          System.out.println("  - " + reference.title() + ": " + reference.url().orElse(""));
      }
  }
  ```

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

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

          // Create and wait for processing to complete
          var material = await client.V1.Materials.CreateAndProcess(new()
          {
              Content = new()
              {
                  Type = StudyfetchSDK.Models.V1.Materials.ContentProperties.Type.Text,
                  Text = "Chapter 1: Introduction to Biology..."
              },
              Name = "Chapter 1 - Introduction"
          });

          // Material is ready to use immediately
          Console.WriteLine($"Material ID: {material._ID}");
          Console.WriteLine($"Status: {material.Status}"); // 'active'
          Console.WriteLine($"Material name: {material.Name}");
      }
  }
  ```
</CodeGroup>

## File Type Examples

### PDF Documents

```javascript theme={null}
const fileBuffer = await fs.promises.readFile(
  path.join(process.cwd(), 'textbook.pdf'),
);
const file = new File([fileBuffer], 'textbook.pdf', {
  type: 'application/pdf',
});

const material = await client.v1.materials.upload.uploadFile({
  file,
  name: 'Biology Textbook'
});
```

### Audio Files (MP3, WAV)

```javascript theme={null}
const fileBuffer = await fs.promises.readFile(
  path.join(process.cwd(), 'podcast.mp3'),
);
const file = new File([fileBuffer], 'podcast.mp3', {
  type: 'audio/mpeg',
});

const material = await client.v1.materials.upload.uploadFile({
  file,
  name: 'Biology Podcast Episode 1'
});
```

### EPUB Books

```javascript theme={null}
// EPUB files are automatically processed into chapters
const fileBuffer = await fs.promises.readFile(
  path.join(process.cwd(), 'textbook.epub'),
);
const file = new File([fileBuffer], 'textbook.epub', {
  type: 'application/epub+zip',
});

const material = await client.v1.materials.upload.uploadFile({
  file,
  name: 'Digital Textbook'
});
```

## Processing Status

Check material status:

```javascript theme={null}
const material = await client.v1.materials.retrieve(materialId);

if (material.status === 'active') {
  console.log('Processing complete!');
} else if (material.status === 'processing') {
  console.log('Still processing...');
} else if (material.status === 'error') {
  console.log('Processing failed');
}
```
