Overview
The Practice Test component creates comprehensive tests from your study materials with multiple question types, difficulty levels, and customizable settings. Perfect for exam preparation and knowledge assessment.
Questions are generated in the background after the component is created. Learners take the test in the embed, which shows generation progress while questions are being written and auto-submits when the time limit runs out.
Creating a Practice Test Component
JavaScript
import StudyfetchSDK from '@studyfetch/sdk';
const client = new StudyfetchSDK({
apiKey: 'your-api-key',
baseURL: 'https://studyfetchapi.com',
});
const testComponent = await client.v1.components.create({
name: 'Biology Midterm Practice',
type: 'practice_test',
config: {
materials: ['mat-123', 'mat-456'],
folders: ['folder-789'],
questionTypes: ['multiplechoice', 'truefalse', 'shortanswer'],
questionsPerTest: 25,
difficulty: 'medium',
timeLimit: 45,
randomizeQuestions: true,
passingScore: 75,
},
});
console.log('Practice test component created:', testComponent._id, testComponent.componentId);
Python
from studyfetch_sdk import StudyfetchSDK
client = StudyfetchSDK(
api_key="your-api-key",
base_url="https://studyfetchapi.com",
)
test_component = client.v1.components.create(
name="Biology Midterm Practice",
type="practice_test",
config={
"materials": ["mat-123", "mat-456"],
"folders": ["folder-789"],
"question_types": ["multiplechoice", "truefalse", "shortanswer"],
"questions_per_test": 25,
"difficulty": "medium",
"time_limit": 45,
"randomize_questions": True,
"passing_score": 75,
},
)
print(f"Practice test component created: {test_component.api_id} {test_component.component_id}")
Java
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 CreatePracticeTestComponent {
public static void main(String[] args) {
StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
.fromEnv()
.baseUrl("https://studyfetchapi.com")
.build();
ComponentCreateParams params = ComponentCreateParams.builder()
.name("Biology Midterm Practice")
.type(ComponentCreateParams.Type.PRACTICE_TEST)
.config(ComponentCreateParams.Config.PracticeTestConfigDto.builder()
.materials(List.of("mat-123", "mat-456"))
.folders(List.of("folder-789"))
.questionTypes(List.of("multiplechoice", "truefalse", "shortanswer"))
.questionsPerTest(25)
.difficulty(ComponentCreateParams.Config.PracticeTestConfigDto.Difficulty.MEDIUM)
.timeLimit(45)
.randomizeQuestions(true)
.passingScore(75)
.build())
.build();
ComponentResponse component = client.v1().components().create(params);
System.out.println("Practice test component created: " + component._id());
}
}
C#
using StudyfetchSDK;
using StudyfetchSDK.Models.V1.Components;
using StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.PracticeTestConfigDtoProperties;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class CreatePracticeTestComponent
{
public static async Task CreatePracticeTest()
{
var client = new StudyfetchSDKClient()
{
APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
BaseUrl = new Uri("https://studyfetchapi.com")
};
var testComponent = await client.V1.Components.Create(new()
{
Name = "Biology Midterm Practice",
Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.PracticeTest,
Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.PracticeTestConfigDto()
{
Materials = new List<string> { "mat-123", "mat-456" },
Folders = new List<string> { "folder-789" },
QuestionTypes = new List<string> { "multiplechoice", "truefalse", "shortanswer" },
QuestionsPerTest = 25,
Difficulty = Difficulty.Medium,
TimeLimit = 45,
RandomizeQuestions = true,
PassingScore = 75,
}
});
Console.WriteLine($"Practice test component created: {testComponent._ID}");
}
}
Configuration Parameters
name
string · required
Name of the practice test component
type
string · required
Must be "practice_test"
config
object · required
Practice test configuration object. questionTypes is required, and you need at least one material or folder. Unknown keys are rejected with 400.
Configuration Properties
These properties go inside config.
questionTypes
array · required
Types of questions to include. At least one:
multiplechoice- Multiple choice questionstruefalse- True/false questionsshortanswer- Short answer questionsfrq- Free-response questionsfillinblank- Fill in the blank questions
Values are case-insensitive and underscores are ignored, so multiple_choice also works. Questions are split evenly across the types you choose.
materials
array
Material IDs to generate questions from. Provide materials, folders, or both.
folders
array
Folder IDs whose materials questions are generated from
questionsPerTest
number · default: 10
Number of questions per test
difficulty
string
Test difficulty level: easy, medium, hard, or mixed. When omitted, questions are generated at mixed difficulty.
timeLimit
number · default: 30
Time limit in minutes. The embed auto-submits the test when time runs out. There is no "no limit" option; 0 is treated as the default.
passingScore
number · default: 70
Minimum passing percentage (0-100) used to show a pass or fail result. 0 is treated as the default.
randomizeQuestions
boolean · default: false
Shuffle question order for each attempt
model
string · default: gpt-4o-mini-2024-07-18
AI model used to generate questions
allowRetakes
boolean
Accepted and stored, but not currently enforced; learners can always retake a test.
maxAttempts
number
Accepted and stored, but not currently enforced
showCorrectAnswers
boolean
Accepted and stored, but not currently used
showExplanations
boolean
Accepted and stored, but not currently used. Graded answers include an explanation when one is available.
randomizeAnswers
boolean
Accepted and stored, but not currently used
aiGenerationMode
string
balanced, comprehensive, focused, or adaptive. Accepted and stored, but not currently used.
questionDistribution
object
Per-type question counts (multiplechoice, truefalse, shortanswer, frq, fillinblank). Accepted and stored, but not currently used; questions are split evenly across questionTypes.
Response
{
"_id": "6650f1c2a9b3e4d5f6a7b8c9",
"componentId": "practice_test_V1StGXR8_Z",
"name": "Biology Midterm Practice",
"type": "practice_test",
"status": "active",
"origin": "api",
"organization": "64f0a1b2c3d4e5f6a7b8c9d0",
"materials": ["mat-123", "mat-456"],
"folders": ["folder-789"],
"config": {
"materials": ["mat-123", "mat-456"],
"folders": ["folder-789"],
"questionTypes": ["multiplechoice", "truefalse", "shortanswer"],
"questionsPerTest": 25,
"difficulty": "medium",
"timeLimit": 45,
"randomizeQuestions": true,
"passingScore": 75
},
"usageCount": 0,
"createdAt": "2026-10-06T10:00:00.000Z",
"updatedAt": "2026-10-06T10:00:00.000Z"
}
Embedding This Component
Once you've created a Practice Test component, you can embed it on your website using the embedding API. The component must be active. Attempts and results are stored per userId, so generate each learner's embed with their own userId.
Generate Embed URL
JavaScript
const embedResponse = await client.v1.components.generateEmbed(testComponent._id, {
// User tracking
userId: 'user-456',
studentName: 'Jane Smith', // Student name for display
groupIds: ['class-101', 'class-102'],
sessionId: 'session-789',
// Dimensions
width: '100%',
height: '700px',
});
console.log(embedResponse.embedUrl);
Python
embed_response = client.v1.components.generate_embed(
test_component.api_id,
user_id="user-456",
student_name="Jane Smith", # Student name for display
group_ids=["class-101", "class-102"],
session_id="session-789",
width="100%",
height="700px",
)
print(embed_response.embed_url)
Java
import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;
ComponentGenerateEmbedParams params = ComponentGenerateEmbedParams.builder()
.id(testComponent._id())
// User tracking
.userId("user-456")
.studentName("Jane Smith") // Student name for display
.groupIds(List.of("class-101", "class-102"))
.sessionId("session-789")
// Dimensions
.width("100%")
.height("700px")
.build();
ComponentGenerateEmbedResponse embedResponse = client.v1().components()
.generateEmbed(params);
System.out.println(embedResponse.embedUrl());
C#
using StudyfetchSDK;
using StudyfetchSDK.Models.V1.Components;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class GeneratePracticeTestEmbed
{
public static async Task GenerateEmbed(string testComponentId)
{
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 = testComponentId,
UserID = "user-456",
StudentName = "Jane Smith", // Student name for display
GroupIDs = new List<string> { "class-101", "class-102" },
SessionID = "session-789",
Width = "100%",
Height = "700px"
});
Console.WriteLine($"Embed URL: {embedResponse.EmbedURL}");
Console.WriteLine($"Token: {embedResponse.Token}");
}
}
The response contains embedUrl, token, expiresAt, componentId (the component's _id), componentType, and options (width and height, defaulting to 100% and 600px).
The practice test embed doesn't use any features settings, and always shows the learner's past attempts.
Embed in Your HTML
Use the embedUrl from the response as the iframe source. The host can differ per organization, so don't build the URL yourself.
<iframe
src="EMBED_URL_FROM_RESPONSE"
width="100%"
height="700px"
frameborder="0"
style="border: 1px solid #e5e5e5; border-radius: 8px;">
</iframe>
Taking Tests from Your Server
To run tests in your own interface, send actions to POST /api/v1/components/{id}/interact, where {id} is the component's _id:
action |
Body fields | Returns |
|---|---|---|
create_test |
userId |
A new attempt: testId, test, and questions. While questions are still being generated, generating: true with progress instead. |
get_test |
testId |
The attempt and its questions |
submit_answer |
testId, questionId, answer, userId |
Whether the answer is correct, its grade, and an explanation |
submit_test |
testId, answers (array of questionId and answer), userId |
grade, correctAnswers, totalQuestions, and per-question results |
get_results |
testId |
Results of a submitted attempt |
retake_test |
testId |
A fresh attempt at the same questions |
list_tests |
userId |
The user's attempts |
The SDKs' interact methods don't send a request body yet, so use cURL or an HTTP client.
curl -X POST "https://studyfetchapi.com/api/v1/components/6650f1c2a9b3e4d5f6a7b8c9/interact" \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{ "action": "create_test", "userId": "user-456" }'
React Native
The React Native SDK (@studyfetch/react-native-sdk) renders Practice Tests natively with embed tokens instead of an iframe. Import it from @studyfetch/react-native-sdk/tests and wrap your app in EmbedTokenProvider with a getToken function that asks your backend to mint an embed token for a component.
import { EmbedTokenProvider } from '@studyfetch/react-native-sdk';
import { StudyFetchTest, useTest } from '@studyfetch/react-native-sdk/tests';
// Full test UI: questions, submission, results
<EmbedTokenProvider getToken={fetchToken}>
<StudyFetchTest componentId="practice_test_V1StGXR8_Z" userId="user-456" />
</EmbedTokenProvider>
// Headless: build your own UI
const { questions, answers, setAnswer, submit, result, passed, retake, generating } = useTest({
componentId: 'practice_test_V1StGXR8_Z',
userId: 'user-456',
});
useTeststarts an attempt automatically and polls while questions are being generated.passedcompares the result with the component'spassingScore.
