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
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.Direct File Upload
Upload files directly to the API. Best for files under 10MB.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'
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'
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'
}
}
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'
}
}
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.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.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'
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}")
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
}
}
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}");
}
}
Upload from URL
Import content directly from web URLs. Supports documents, videos, and web pages.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);
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}")
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());
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}");
}
}
Upload Text Content
Create materials from plain text content without file upload.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);
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}")
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(""));
}
}
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}");
}
}
}
}
Create and Process Material
ThecreateAndProcess 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.
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.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'
# 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}")
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(""));
}
}
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}");
}
}
File Type Examples
PDF Documents
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)
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
// 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: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');
}